feat: adopt template CSS architecture, hero/TOC/color alignment
Browse files- Copy template foundation CSS (_variables, _reset, _base, _layout,
_print) and component CSS (_code, _table, _tag, _card, _mermaid)
- Extract hero styles from HeroArticle.astro into shared _hero.css
- Extract TOC styles from TableOfContents.astro into shared _toc.css
- Create _editor-tokens.css for editor-specific design tokens
- Scope _reset.css and _base.css global styles to article area
to avoid overriding MUI portals (Dialog, Menu, Tooltip)
- Exclude _button.css and _form.css from editor (bare element
selectors conflict with MUI components)
- Align FrontmatterHero class names with template (.hero, .meta,
.meta-container-cell, .authors, .affiliations)
- Align publisher HTML renderer class names accordingly
- Fix TOC sticky positioning (align-self:stretch + sticky wrapper)
- Add hue-based color picker (OKLCH slider like template ColorPicker)
synced via Yjs settings, driving both MUI theme and CSS variables
- Align editor link styles with template (--primary-color)
- Add PostCSS config for @custom-media support
- Remove "Welcome to Collaborative Editor" from default content
Made-with: Cursor
- backend/src/hf-storage.ts +35 -23
- backend/src/publisher/extensions.ts +7 -0
- backend/src/publisher/html-renderer.ts +58 -318
- backend/src/publisher/index.ts +66 -15
- frontend/package-lock.json +1381 -26
- frontend/package.json +2 -0
- frontend/postcss.config.js +5 -0
- frontend/src/App.tsx +43 -27
- frontend/src/components/TableOfContents.tsx +21 -72
- frontend/src/editor/components/MermaidView.tsx +179 -0
- frontend/src/editor/components/factory.ts +3 -1
- frontend/src/editor/components/registry.ts +11 -0
- frontend/src/editor/default-content.ts +2 -4
- frontend/src/editor/frontmatter/FrontmatterHero.tsx +72 -154
- frontend/src/editor/frontmatter/HueSlider.tsx +196 -0
- frontend/src/editor/frontmatter/SettingsDrawer.tsx +18 -2
- frontend/src/main.tsx +24 -7
- frontend/src/styles/_base.css +174 -0
- frontend/src/styles/_editor-tokens.css +105 -0
- frontend/src/styles/_layout.css +363 -0
- frontend/src/styles/_print.css +128 -0
- frontend/src/styles/_reset.css +25 -0
- frontend/src/styles/_variables.css +126 -0
- frontend/src/styles/article.css +27 -26
- frontend/src/styles/components/_button.css +58 -0
- frontend/src/styles/components/_card.css +138 -0
- frontend/src/styles/components/_code.css +357 -0
- frontend/src/styles/components/_form.css +243 -0
- frontend/src/styles/components/_hero.css +136 -0
- frontend/src/styles/components/_mermaid.css +250 -0
- frontend/src/styles/components/_table.css +121 -0
- frontend/src/styles/components/_tag.css +14 -0
- frontend/src/styles/components/_toc.css +55 -0
- frontend/src/styles/editing.css +103 -32
- frontend/src/styles/toc.css +52 -0
- frontend/src/theme.ts +39 -28
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { uploadFile, downloadFile, createRepo, type RepoDesignation } from "@huggingface/hub";
|
| 2 |
|
| 3 |
const SPACE_ID = process.env.SPACE_ID || "";
|
| 4 |
|
|
@@ -188,6 +188,15 @@ export async function pullPublishedAssets(
|
|
| 188 |
|
| 189 |
// ---------- Published Assets ----------
|
| 190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
interface PublishedPayload {
|
| 192 |
html: string;
|
| 193 |
pdf: Buffer | null;
|
|
@@ -206,46 +215,49 @@ export async function uploadPublishedAssets(
|
|
| 206 |
const safeName = sanitizeName(docName);
|
| 207 |
const base = `published/${safeName}`;
|
| 208 |
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
|
| 216 |
const baseUrl = `https://huggingface.co/datasets/${HF_DATASET_ID}/resolve/main/${base}`;
|
| 217 |
let pdfUrl: string | null = null;
|
| 218 |
let thumbUrl: string | null = null;
|
| 219 |
|
| 220 |
if (payload.pdf) {
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
commitTitle: `publish ${safeName}: PDF`,
|
| 226 |
});
|
| 227 |
pdfUrl = `${baseUrl}/article.pdf`;
|
| 228 |
}
|
| 229 |
|
| 230 |
if (payload.thumbnail) {
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
commitTitle: `publish ${safeName}: thumbnail`,
|
| 236 |
});
|
| 237 |
thumbUrl = `${baseUrl}/thumb.jpg`;
|
| 238 |
}
|
| 239 |
|
| 240 |
-
await
|
| 241 |
repo,
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
content: new Blob([JSON.stringify(payload.meta, null, 2)]),
|
| 245 |
-
},
|
| 246 |
accessToken,
|
| 247 |
-
commitTitle: `publish ${safeName}: metadata`,
|
| 248 |
});
|
| 249 |
|
|
|
|
|
|
|
| 250 |
return { htmlUrl: `${baseUrl}/index.html`, pdfUrl, thumbUrl };
|
| 251 |
}
|
|
|
|
| 1 |
+
import { uploadFile, downloadFile, createRepo, commit, type CommitFile, type RepoDesignation } from "@huggingface/hub";
|
| 2 |
|
| 3 |
const SPACE_ID = process.env.SPACE_ID || "";
|
| 4 |
|
|
|
|
| 188 |
|
| 189 |
// ---------- Published Assets ----------
|
| 190 |
|
| 191 |
+
/**
|
| 192 |
+
* Build the public resolve URL for a published asset.
|
| 193 |
+
* Useful to pre-compute og:image / pdf URLs before HTML generation.
|
| 194 |
+
*/
|
| 195 |
+
export function getPublishedAssetUrl(docName: string, filename: string): string {
|
| 196 |
+
const safeName = sanitizeName(docName);
|
| 197 |
+
return `https://huggingface.co/datasets/${HF_DATASET_ID}/resolve/main/published/${safeName}/${filename}`;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
interface PublishedPayload {
|
| 201 |
html: string;
|
| 202 |
pdf: Buffer | null;
|
|
|
|
| 215 |
const safeName = sanitizeName(docName);
|
| 216 |
const base = `published/${safeName}`;
|
| 217 |
|
| 218 |
+
const operations: CommitFile[] = [
|
| 219 |
+
{
|
| 220 |
+
operation: "addOrUpdate",
|
| 221 |
+
path: `${base}/index.html`,
|
| 222 |
+
content: new Blob([payload.html]),
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
operation: "addOrUpdate",
|
| 226 |
+
path: `${base}/meta.json`,
|
| 227 |
+
content: new Blob([JSON.stringify(payload.meta, null, 2)]),
|
| 228 |
+
},
|
| 229 |
+
];
|
| 230 |
|
| 231 |
const baseUrl = `https://huggingface.co/datasets/${HF_DATASET_ID}/resolve/main/${base}`;
|
| 232 |
let pdfUrl: string | null = null;
|
| 233 |
let thumbUrl: string | null = null;
|
| 234 |
|
| 235 |
if (payload.pdf) {
|
| 236 |
+
operations.push({
|
| 237 |
+
operation: "addOrUpdate",
|
| 238 |
+
path: `${base}/article.pdf`,
|
| 239 |
+
content: new Blob([new Uint8Array(payload.pdf)]),
|
|
|
|
| 240 |
});
|
| 241 |
pdfUrl = `${baseUrl}/article.pdf`;
|
| 242 |
}
|
| 243 |
|
| 244 |
if (payload.thumbnail) {
|
| 245 |
+
operations.push({
|
| 246 |
+
operation: "addOrUpdate",
|
| 247 |
+
path: `${base}/thumb.jpg`,
|
| 248 |
+
content: new Blob([new Uint8Array(payload.thumbnail)]),
|
|
|
|
| 249 |
});
|
| 250 |
thumbUrl = `${baseUrl}/thumb.jpg`;
|
| 251 |
}
|
| 252 |
|
| 253 |
+
await commit({
|
| 254 |
repo,
|
| 255 |
+
operations,
|
| 256 |
+
title: `publish ${safeName}`,
|
|
|
|
|
|
|
| 257 |
accessToken,
|
|
|
|
| 258 |
});
|
| 259 |
|
| 260 |
+
console.log(`[hf-storage] published ${safeName} (${operations.length} files, single commit)`);
|
| 261 |
+
|
| 262 |
return { htmlUrl: `${baseUrl}/index.html`, pdfUrl, thumbUrl };
|
| 263 |
}
|
|
@@ -246,6 +246,13 @@ const COMPONENT_DEFS: ComponentDefLite[] = [
|
|
| 246 |
{ name: "html", type: "string", default: "" },
|
| 247 |
],
|
| 248 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
];
|
| 250 |
|
| 251 |
function makeServerWrapperExt(def: ComponentDefLite) {
|
|
|
|
| 246 |
{ name: "html", type: "string", default: "" },
|
| 247 |
],
|
| 248 |
},
|
| 249 |
+
{
|
| 250 |
+
name: "mermaid",
|
| 251 |
+
kind: "atomic",
|
| 252 |
+
fields: [
|
| 253 |
+
{ name: "code", type: "string", default: "" },
|
| 254 |
+
],
|
| 255 |
+
},
|
| 256 |
];
|
| 257 |
|
| 258 |
function makeServerWrapperExt(def: ComponentDefLite) {
|
|
@@ -7,6 +7,7 @@
|
|
| 7 |
|
| 8 |
import { generateHTML } from "@tiptap/html";
|
| 9 |
import { getServerExtensions } from "./extensions.js";
|
|
|
|
| 10 |
|
| 11 |
export interface PublishAuthor {
|
| 12 |
name: string;
|
|
@@ -29,6 +30,7 @@ export interface PublishMeta {
|
|
| 29 |
date: string;
|
| 30 |
doi?: string;
|
| 31 |
ogImage?: string;
|
|
|
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
|
@@ -37,8 +39,7 @@ export interface PublishMeta {
|
|
| 37 |
export function renderArticleHTML(
|
| 38 |
json: Record<string, unknown>,
|
| 39 |
meta: PublishMeta,
|
| 40 |
-
|
| 41 |
-
cssArticle: string
|
| 42 |
): string {
|
| 43 |
const extensions = getServerExtensions();
|
| 44 |
|
|
@@ -84,315 +85,33 @@ export function renderArticleHTML(
|
|
| 84 |
<!-- highlight.js theme -->
|
| 85 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github-dark.min.css">
|
| 86 |
|
| 87 |
-
<
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
/
|
| 92 |
-
body {
|
| 93 |
-
margin: 0;
|
| 94 |
-
padding: 0;
|
| 95 |
-
background: var(--bg-primary);
|
| 96 |
-
color: var(--text-primary);
|
| 97 |
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
/* Grid: TOC | Article | (empty right) */
|
| 101 |
-
.content-grid {
|
| 102 |
-
max-width: 1280px;
|
| 103 |
-
margin: 0 auto;
|
| 104 |
-
padding: 0 24px;
|
| 105 |
-
margin-top: 40px;
|
| 106 |
-
display: grid;
|
| 107 |
-
grid-template-columns: 260px minmax(0, 680px) 260px;
|
| 108 |
-
gap: 32px;
|
| 109 |
-
align-items: start;
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
/* Hero section */
|
| 113 |
-
.article-hero {
|
| 114 |
-
width: 100%;
|
| 115 |
-
padding: 64px 16px 16px;
|
| 116 |
-
text-align: center;
|
| 117 |
-
}
|
| 118 |
-
|
| 119 |
-
.article-hero h1 {
|
| 120 |
-
font-size: clamp(34px, 5vw, 54px);
|
| 121 |
-
font-weight: 800;
|
| 122 |
-
line-height: 1.12;
|
| 123 |
-
letter-spacing: -0.02em;
|
| 124 |
-
margin: 0 auto 8px;
|
| 125 |
-
max-width: 780px;
|
| 126 |
-
text-wrap: balance;
|
| 127 |
-
color: var(--text-heading);
|
| 128 |
-
}
|
| 129 |
-
|
| 130 |
-
.article-hero .hero-desc {
|
| 131 |
-
color: var(--text-tertiary);
|
| 132 |
-
font-style: italic;
|
| 133 |
-
margin: 0 auto 16px;
|
| 134 |
-
max-width: 55%;
|
| 135 |
-
font-size: 1.15em;
|
| 136 |
-
line-height: 1.6;
|
| 137 |
-
}
|
| 138 |
-
|
| 139 |
-
/* Meta bar */
|
| 140 |
-
.article-meta {
|
| 141 |
-
border-top: 1px solid var(--border);
|
| 142 |
-
border-bottom: 1px solid var(--border);
|
| 143 |
-
padding: 1rem 0;
|
| 144 |
-
font-size: 0.9rem;
|
| 145 |
-
}
|
| 146 |
-
|
| 147 |
-
.article-meta .meta-container {
|
| 148 |
-
max-width: 980px;
|
| 149 |
-
margin: 0 auto;
|
| 150 |
-
padding: 0 16px;
|
| 151 |
-
display: flex;
|
| 152 |
-
flex-direction: row;
|
| 153 |
-
justify-content: space-between;
|
| 154 |
-
gap: 8px;
|
| 155 |
-
flex-wrap: wrap;
|
| 156 |
-
row-gap: 12px;
|
| 157 |
-
}
|
| 158 |
-
|
| 159 |
-
.article-meta .meta-cell {
|
| 160 |
-
display: flex;
|
| 161 |
-
flex-direction: column;
|
| 162 |
-
gap: 8px;
|
| 163 |
-
max-width: 400px;
|
| 164 |
-
}
|
| 165 |
-
|
| 166 |
-
.article-meta .meta-cell h3 {
|
| 167 |
-
margin: 0;
|
| 168 |
-
font-size: 12px;
|
| 169 |
-
font-weight: 400;
|
| 170 |
-
color: var(--text-tertiary);
|
| 171 |
-
text-transform: uppercase;
|
| 172 |
-
letter-spacing: 0.02em;
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
.article-meta .meta-cell p { margin: 0; }
|
| 176 |
-
|
| 177 |
-
.article-meta .authors-list {
|
| 178 |
-
margin: 0;
|
| 179 |
-
list-style: none;
|
| 180 |
-
padding-left: 0;
|
| 181 |
-
display: flex;
|
| 182 |
-
flex-wrap: wrap;
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
.article-meta .authors-list li {
|
| 186 |
-
white-space: nowrap;
|
| 187 |
-
padding: 0;
|
| 188 |
-
}
|
| 189 |
-
|
| 190 |
-
.article-meta .author-link {
|
| 191 |
-
color: var(--accent-light);
|
| 192 |
-
text-decoration: underline;
|
| 193 |
-
text-underline-offset: 2px;
|
| 194 |
-
text-decoration-thickness: 0.06em;
|
| 195 |
-
}
|
| 196 |
-
|
| 197 |
-
.article-meta .author-link:hover {
|
| 198 |
-
color: var(--text-primary);
|
| 199 |
-
}
|
| 200 |
-
|
| 201 |
-
.article-meta .affiliations-list {
|
| 202 |
-
margin: 0;
|
| 203 |
-
padding-left: 1.25em;
|
| 204 |
-
}
|
| 205 |
-
|
| 206 |
-
.article-meta .affiliations-list li { margin: 0; }
|
| 207 |
-
|
| 208 |
-
.article-meta .doi-link {
|
| 209 |
-
color: var(--accent-light);
|
| 210 |
-
text-decoration: underline;
|
| 211 |
-
text-underline-offset: 2px;
|
| 212 |
-
font-family: monospace;
|
| 213 |
-
}
|
| 214 |
-
|
| 215 |
-
@media (max-width: 768px) {
|
| 216 |
-
.article-hero .hero-desc { max-width: 90%; }
|
| 217 |
-
.article-meta .meta-container { flex-direction: column; }
|
| 218 |
-
}
|
| 219 |
-
|
| 220 |
-
/* Theme toggle */
|
| 221 |
-
.theme-toggle {
|
| 222 |
-
position: fixed;
|
| 223 |
-
top: 1rem;
|
| 224 |
-
right: 1rem;
|
| 225 |
-
background: var(--bg-secondary);
|
| 226 |
-
border: 1px solid var(--border);
|
| 227 |
-
border-radius: 8px;
|
| 228 |
-
padding: 0.5rem;
|
| 229 |
-
cursor: pointer;
|
| 230 |
-
font-size: 1.2rem;
|
| 231 |
-
line-height: 1;
|
| 232 |
-
z-index: 100;
|
| 233 |
-
}
|
| 234 |
-
|
| 235 |
-
/* ---------- Table of Contents (desktop sticky) ---------- */
|
| 236 |
-
.table-of-contents {
|
| 237 |
-
position: sticky;
|
| 238 |
-
top: 32px;
|
| 239 |
-
margin-top: 12px;
|
| 240 |
-
}
|
| 241 |
-
|
| 242 |
-
.table-of-contents .title {
|
| 243 |
-
font-weight: 600;
|
| 244 |
-
font-size: 14px;
|
| 245 |
-
margin-bottom: 8px;
|
| 246 |
-
color: var(--text-primary);
|
| 247 |
-
}
|
| 248 |
-
|
| 249 |
-
.table-of-contents nav {
|
| 250 |
-
border-left: 1px solid var(--border);
|
| 251 |
-
padding-left: 16px;
|
| 252 |
-
font-size: 13px;
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
.table-of-contents nav ul {
|
| 256 |
-
margin: 0 0 6px;
|
| 257 |
-
padding-left: 1em;
|
| 258 |
-
}
|
| 259 |
-
|
| 260 |
-
.table-of-contents nav li {
|
| 261 |
-
list-style: none;
|
| 262 |
-
margin: 0.25em 0;
|
| 263 |
-
}
|
| 264 |
-
|
| 265 |
-
.table-of-contents nav a,
|
| 266 |
-
.table-of-contents nav a:link,
|
| 267 |
-
.table-of-contents nav a:visited {
|
| 268 |
-
color: var(--text-primary);
|
| 269 |
-
text-decoration: none;
|
| 270 |
-
border-bottom: none;
|
| 271 |
-
}
|
| 272 |
-
|
| 273 |
-
.table-of-contents nav > ul > li > a {
|
| 274 |
-
font-weight: 700;
|
| 275 |
-
}
|
| 276 |
-
|
| 277 |
-
.table-of-contents nav a:hover {
|
| 278 |
-
text-decoration: underline solid var(--text-tertiary);
|
| 279 |
-
}
|
| 280 |
-
|
| 281 |
-
.table-of-contents nav a.active {
|
| 282 |
-
text-decoration: underline;
|
| 283 |
-
}
|
| 284 |
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
transition: height 200ms ease;
|
| 290 |
-
}
|
| 291 |
|
| 292 |
-
/*
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
position: fixed;
|
| 296 |
-
top: 1rem;
|
| 297 |
-
left: 1rem;
|
| 298 |
-
z-index: 200;
|
| 299 |
-
width: 40px;
|
| 300 |
-
height: 40px;
|
| 301 |
-
border-radius: 50%;
|
| 302 |
-
border: 1px solid var(--border);
|
| 303 |
-
background: var(--bg-primary);
|
| 304 |
-
color: var(--text-primary);
|
| 305 |
-
cursor: pointer;
|
| 306 |
-
align-items: center;
|
| 307 |
-
justify-content: center;
|
| 308 |
-
box-shadow: 0 2px 12px rgba(0,0,0,.08);
|
| 309 |
-
transition: transform 150ms ease, box-shadow 150ms ease;
|
| 310 |
-
}
|
| 311 |
-
.toc-mobile-toggle:active { transform: scale(0.92); }
|
| 312 |
-
|
| 313 |
-
/* ---------- Mobile backdrop ---------- */
|
| 314 |
-
.toc-mobile-backdrop {
|
| 315 |
-
display: none;
|
| 316 |
-
position: fixed;
|
| 317 |
-
inset: 0;
|
| 318 |
-
z-index: 201;
|
| 319 |
-
background: rgba(0,0,0,.4);
|
| 320 |
-
opacity: 0;
|
| 321 |
-
pointer-events: none;
|
| 322 |
-
transition: opacity 250ms ease;
|
| 323 |
-
}
|
| 324 |
-
.toc-mobile-backdrop.open { opacity: 1; pointer-events: auto; }
|
| 325 |
-
|
| 326 |
-
/* ---------- Mobile sidebar ---------- */
|
| 327 |
-
.toc-mobile-sidebar {
|
| 328 |
-
display: none;
|
| 329 |
-
position: fixed;
|
| 330 |
-
top: 0; left: 0; bottom: 0;
|
| 331 |
-
z-index: 202;
|
| 332 |
-
width: min(320px, 85vw);
|
| 333 |
-
background: var(--bg-primary);
|
| 334 |
-
border-right: 1px solid var(--border);
|
| 335 |
-
transform: translateX(-100%);
|
| 336 |
-
transition: transform 300ms cubic-bezier(.4,0,.2,1);
|
| 337 |
-
flex-direction: column;
|
| 338 |
-
}
|
| 339 |
-
.toc-mobile-sidebar.open { transform: translateX(0); }
|
| 340 |
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
flex-shrink: 0;
|
| 348 |
-
}
|
| 349 |
-
.toc-mobile-sidebar__title { font-weight: 700; font-size: 15px; color: var(--text-primary); }
|
| 350 |
-
.toc-mobile-sidebar__close {
|
| 351 |
-
background: none; border: none; color: var(--text-tertiary);
|
| 352 |
-
cursor: pointer; padding: 6px; border-radius: 6px;
|
| 353 |
-
display: flex; align-items: center; justify-content: center;
|
| 354 |
-
transition: color 150ms ease, background 150ms ease;
|
| 355 |
-
}
|
| 356 |
-
.toc-mobile-sidebar__close:hover { color: var(--text-primary); background: var(--bg-secondary); }
|
| 357 |
|
| 358 |
-
|
| 359 |
-
flex: 1;
|
| 360 |
-
overflow-y: auto;
|
| 361 |
-
-webkit-overflow-scrolling: touch;
|
| 362 |
-
padding: 0.75rem 1rem 1.5rem;
|
| 363 |
-
}
|
| 364 |
-
.toc-mobile-sidebar nav ul { margin: 0 0 6px; padding-left: 1em; }
|
| 365 |
-
.toc-mobile-sidebar nav li { list-style: none; margin: 0.35em 0; }
|
| 366 |
-
.toc-mobile-sidebar nav a,
|
| 367 |
-
.toc-mobile-sidebar nav a:link,
|
| 368 |
-
.toc-mobile-sidebar nav a:visited {
|
| 369 |
-
color: var(--text-primary);
|
| 370 |
-
text-decoration: none;
|
| 371 |
-
border-bottom: none;
|
| 372 |
-
font-size: 14px;
|
| 373 |
-
line-height: 1.5;
|
| 374 |
-
}
|
| 375 |
-
.toc-mobile-sidebar nav > ul > li > a { font-weight: 700; }
|
| 376 |
-
.toc-mobile-sidebar nav a:hover { text-decoration: underline solid var(--text-tertiary); }
|
| 377 |
-
.toc-mobile-sidebar nav a.active { color: var(--accent-light); text-decoration: underline; }
|
| 378 |
-
|
| 379 |
-
/* ---------- Responsive: collapse below 1100px ---------- */
|
| 380 |
-
@media (max-width: 1100px) {
|
| 381 |
-
.content-grid {
|
| 382 |
-
overflow: hidden;
|
| 383 |
-
display: block;
|
| 384 |
-
padding: 0 16px;
|
| 385 |
-
margin-top: 0.5rem;
|
| 386 |
-
}
|
| 387 |
-
.table-of-contents { position: static; display: none; }
|
| 388 |
-
.toc-mobile-toggle { display: flex; }
|
| 389 |
-
.toc-mobile-backdrop { display: block; }
|
| 390 |
-
.toc-mobile-sidebar { display: flex; }
|
| 391 |
-
}
|
| 392 |
|
| 393 |
/* Accordion as details/summary */
|
| 394 |
details[data-component="accordion"] {
|
| 395 |
-
border: 1px solid var(--border);
|
| 396 |
border-radius: 8px;
|
| 397 |
padding: 0;
|
| 398 |
margin: 1em 0;
|
|
@@ -402,7 +121,7 @@ details[data-component="accordion"] > summary {
|
|
| 402 |
padding: 0.75rem 1rem;
|
| 403 |
cursor: pointer;
|
| 404 |
font-weight: 600;
|
| 405 |
-
color: var(--text-
|
| 406 |
list-style: none;
|
| 407 |
user-select: none;
|
| 408 |
}
|
|
@@ -419,16 +138,22 @@ details[data-component="accordion"] > summary::before {
|
|
| 419 |
details[data-component="accordion"][open] > summary::before { transform: rotate(90deg); }
|
| 420 |
details[data-component="accordion"] > .accordion-content { padding: 0 1rem 1rem; }
|
| 421 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
/* Image lightbox dialog */
|
| 423 |
dialog.lightbox { border: none; background: transparent; padding: 0; max-width: 95vw; max-height: 95vh; }
|
| 424 |
dialog.lightbox::backdrop { background: rgba(0, 0, 0, 0.85); }
|
| 425 |
dialog.lightbox img { max-width: 95vw; max-height: 90vh; object-fit: contain; border-radius: 4px; }
|
| 426 |
-
|
| 427 |
-
/* Print */
|
| 428 |
-
@media print {
|
| 429 |
-
.table-of-contents, .toc-mobile-toggle, .toc-mobile-backdrop, .toc-mobile-sidebar, .theme-toggle { display: none !important; }
|
| 430 |
-
.content-grid { display: block !important; }
|
| 431 |
-
}
|
| 432 |
</style>
|
| 433 |
</head>
|
| 434 |
<body>
|
|
@@ -454,7 +179,7 @@ dialog.lightbox img { max-width: 95vw; max-height: 90vh; object-fit: contain; bo
|
|
| 454 |
</aside>
|
| 455 |
|
| 456 |
<!-- Hero -->
|
| 457 |
-
<section class="
|
| 458 |
<h1>${safeTitle}</h1>
|
| 459 |
${meta.subtitle ? `<p class="hero-desc">${escapeHtml(meta.subtitle)}</p>` : ""}
|
| 460 |
</section>
|
|
@@ -770,6 +495,16 @@ function postProcess(html: string, biblioHtml: string): string {
|
|
| 770 |
}
|
| 771 |
);
|
| 772 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 773 |
// HtmlEmbed: div[data-component="htmlEmbed"] → iframe with srcdoc
|
| 774 |
result = result.replace(
|
| 775 |
/<div[^>]*data-component="htmlEmbed"[^>]*data-src="([^"]*)"[^>]*><\/div>/g,
|
|
@@ -813,7 +548,7 @@ function renderMetaBar(meta: PublishMeta): string {
|
|
| 813 |
const sep = i < meta.authors.length - 1 ? ", " : "";
|
| 814 |
return `<li>${name}${sup}${sep}</li>`;
|
| 815 |
}).join("");
|
| 816 |
-
cells.push(`<div class="meta-cell"><h3>Authors</h3><ul class="authors
|
| 817 |
}
|
| 818 |
|
| 819 |
// Affiliations cell
|
|
@@ -826,27 +561,32 @@ function renderMetaBar(meta: PublishMeta): string {
|
|
| 826 |
: escapeHtml(aff.name);
|
| 827 |
return `<li>${name}</li>`;
|
| 828 |
}).join("");
|
| 829 |
-
affContent = `<ol class="affiliations
|
| 830 |
} else {
|
| 831 |
const aff = meta.affiliations[0];
|
| 832 |
affContent = aff.url
|
| 833 |
? `<p><a href="${escapeHtml(aff.url)}" target="_blank" rel="noopener">${escapeHtml(aff.name)}</a></p>`
|
| 834 |
: `<p>${escapeHtml(aff.name)}</p>`;
|
| 835 |
}
|
| 836 |
-
cells.push(`<div class="meta-cell"><h3>Affiliations</h3>${affContent}</div>`);
|
| 837 |
}
|
| 838 |
|
| 839 |
// Published cell
|
| 840 |
if (meta.date) {
|
| 841 |
-
cells.push(`<div class="meta-cell"><h3>Published</h3><p>${escapeHtml(formatDate(meta.date))}</p></div>`);
|
| 842 |
}
|
| 843 |
|
| 844 |
// DOI cell
|
| 845 |
if (meta.doi) {
|
| 846 |
-
cells.push(`<div class="meta-cell"><h3>DOI</h3><p><a href="https://doi.org/${escapeHtml(meta.doi)}" class="doi-link" target="_blank" rel="noopener">${escapeHtml(meta.doi)}</a></p></div>`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 847 |
}
|
| 848 |
|
| 849 |
-
return `<header class="
|
| 850 |
}
|
| 851 |
|
| 852 |
function formatDate(dateStr: string): string {
|
|
|
|
| 7 |
|
| 8 |
import { generateHTML } from "@tiptap/html";
|
| 9 |
import { getServerExtensions } from "./extensions.js";
|
| 10 |
+
import type { PublishCSS } from "./index.js";
|
| 11 |
|
| 12 |
export interface PublishAuthor {
|
| 13 |
name: string;
|
|
|
|
| 30 |
date: string;
|
| 31 |
doi?: string;
|
| 32 |
ogImage?: string;
|
| 33 |
+
pdfUrl?: string;
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
|
|
|
| 39 |
export function renderArticleHTML(
|
| 40 |
json: Record<string, unknown>,
|
| 41 |
meta: PublishMeta,
|
| 42 |
+
css: PublishCSS
|
|
|
|
| 43 |
): string {
|
| 44 |
const extensions = getServerExtensions();
|
| 45 |
|
|
|
|
| 85 |
<!-- highlight.js theme -->
|
| 86 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github-dark.min.css">
|
| 87 |
|
| 88 |
+
<!-- Mermaid (renders <pre class="mermaid"> blocks) -->
|
| 89 |
+
<script type="module">
|
| 90 |
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
| 91 |
+
mermaid.initialize({ startOnLoad: true, theme: 'neutral' });
|
| 92 |
+
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
+
<style>
|
| 95 |
+
/* Template foundation */
|
| 96 |
+
${css.variables}
|
| 97 |
+
${css.reset}
|
|
|
|
|
|
|
| 98 |
|
| 99 |
+
/* Published page global reset (not needed in editor where MUI handles body) */
|
| 100 |
+
body { font-family: var(--default-font-family); color: var(--text-color); }
|
| 101 |
+
html { font-size: 16px; line-height: 1.6; background-color: var(--page-bg); overflow-x: hidden; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
| 103 |
+
${css.editorTokens}
|
| 104 |
+
${css.base}
|
| 105 |
+
${css.layout}
|
| 106 |
+
${css.components}
|
| 107 |
+
${css.article}
|
| 108 |
+
${css.print}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
+
/* Publisher-only overrides */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
/* Accordion as details/summary */
|
| 113 |
details[data-component="accordion"] {
|
| 114 |
+
border: 1px solid var(--border-color);
|
| 115 |
border-radius: 8px;
|
| 116 |
padding: 0;
|
| 117 |
margin: 1em 0;
|
|
|
|
| 121 |
padding: 0.75rem 1rem;
|
| 122 |
cursor: pointer;
|
| 123 |
font-weight: 600;
|
| 124 |
+
color: var(--text-color);
|
| 125 |
list-style: none;
|
| 126 |
user-select: none;
|
| 127 |
}
|
|
|
|
| 138 |
details[data-component="accordion"][open] > summary::before { transform: rotate(90deg); }
|
| 139 |
details[data-component="accordion"] > .accordion-content { padding: 0 1rem 1rem; }
|
| 140 |
|
| 141 |
+
/* PDF download link */
|
| 142 |
+
a.pdf-link {
|
| 143 |
+
display: inline-flex;
|
| 144 |
+
align-items: center;
|
| 145 |
+
gap: 0.4em;
|
| 146 |
+
color: var(--accent-color, #4493f8);
|
| 147 |
+
text-decoration: none;
|
| 148 |
+
font-weight: 500;
|
| 149 |
+
}
|
| 150 |
+
a.pdf-link:hover { text-decoration: underline; }
|
| 151 |
+
a.pdf-link::before { content: "\\1F4C4"; }
|
| 152 |
+
|
| 153 |
/* Image lightbox dialog */
|
| 154 |
dialog.lightbox { border: none; background: transparent; padding: 0; max-width: 95vw; max-height: 95vh; }
|
| 155 |
dialog.lightbox::backdrop { background: rgba(0, 0, 0, 0.85); }
|
| 156 |
dialog.lightbox img { max-width: 95vw; max-height: 90vh; object-fit: contain; border-radius: 4px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
</style>
|
| 158 |
</head>
|
| 159 |
<body>
|
|
|
|
| 179 |
</aside>
|
| 180 |
|
| 181 |
<!-- Hero -->
|
| 182 |
+
<section class="hero">
|
| 183 |
<h1>${safeTitle}</h1>
|
| 184 |
${meta.subtitle ? `<p class="hero-desc">${escapeHtml(meta.subtitle)}</p>` : ""}
|
| 185 |
</section>
|
|
|
|
| 495 |
}
|
| 496 |
);
|
| 497 |
|
| 498 |
+
// Mermaid: div[data-component="mermaid"] → <pre class="mermaid">code</pre>
|
| 499 |
+
result = result.replace(
|
| 500 |
+
/<div[^>]*data-component="mermaid"[^>]*><\/div>/g,
|
| 501 |
+
(match) => {
|
| 502 |
+
const codeMatch = match.match(/data-code="([^"]*)"/);
|
| 503 |
+
const code = codeMatch ? codeMatch[1].replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'") : "";
|
| 504 |
+
return `<pre class="mermaid">${escapeHtml(code)}</pre>`;
|
| 505 |
+
}
|
| 506 |
+
);
|
| 507 |
+
|
| 508 |
// HtmlEmbed: div[data-component="htmlEmbed"] → iframe with srcdoc
|
| 509 |
result = result.replace(
|
| 510 |
/<div[^>]*data-component="htmlEmbed"[^>]*data-src="([^"]*)"[^>]*><\/div>/g,
|
|
|
|
| 548 |
const sep = i < meta.authors.length - 1 ? ", " : "";
|
| 549 |
return `<li>${name}${sup}${sep}</li>`;
|
| 550 |
}).join("");
|
| 551 |
+
cells.push(`<div class="meta-container-cell"><h3>Authors</h3><ul class="authors">${items}</ul></div>`);
|
| 552 |
}
|
| 553 |
|
| 554 |
// Affiliations cell
|
|
|
|
| 561 |
: escapeHtml(aff.name);
|
| 562 |
return `<li>${name}</li>`;
|
| 563 |
}).join("");
|
| 564 |
+
affContent = `<ol class="affiliations">${items}</ol>`;
|
| 565 |
} else {
|
| 566 |
const aff = meta.affiliations[0];
|
| 567 |
affContent = aff.url
|
| 568 |
? `<p><a href="${escapeHtml(aff.url)}" target="_blank" rel="noopener">${escapeHtml(aff.name)}</a></p>`
|
| 569 |
: `<p>${escapeHtml(aff.name)}</p>`;
|
| 570 |
}
|
| 571 |
+
cells.push(`<div class="meta-container-cell"><h3>Affiliations</h3>${affContent}</div>`);
|
| 572 |
}
|
| 573 |
|
| 574 |
// Published cell
|
| 575 |
if (meta.date) {
|
| 576 |
+
cells.push(`<div class="meta-container-cell"><h3>Published</h3><p>${escapeHtml(formatDate(meta.date))}</p></div>`);
|
| 577 |
}
|
| 578 |
|
| 579 |
// DOI cell
|
| 580 |
if (meta.doi) {
|
| 581 |
+
cells.push(`<div class="meta-container-cell"><h3>DOI</h3><p><a href="https://doi.org/${escapeHtml(meta.doi)}" class="doi-link" target="_blank" rel="noopener">${escapeHtml(meta.doi)}</a></p></div>`);
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
// PDF download cell
|
| 585 |
+
if (meta.pdfUrl) {
|
| 586 |
+
cells.push(`<div class="meta-container-cell"><h3>PDF</h3><p><a href="${escapeHtml(meta.pdfUrl)}" class="pdf-link" target="_blank" rel="noopener" download>Download PDF</a></p></div>`);
|
| 587 |
}
|
| 588 |
|
| 589 |
+
return `<header class="meta"><div class="meta-container">${cells.join("")}</div></header>`;
|
| 590 |
}
|
| 591 |
|
| 592 |
function formatDate(dateStr: string): string {
|
|
@@ -15,6 +15,7 @@ import { isPdfEnabled, generatePdfAndThumbnail } from "./pdf-generator.js";
|
|
| 15 |
import {
|
| 16 |
isHfStorageEnabled,
|
| 17 |
uploadPublishedAssets,
|
|
|
|
| 18 |
} from "../hf-storage.js";
|
| 19 |
|
| 20 |
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -24,31 +25,60 @@ function docPath(name: string) {
|
|
| 24 |
return join(DATA_DIR, `${name.replace(/[^a-zA-Z0-9_-]/g, "_")}.yjs`);
|
| 25 |
}
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
/**
|
| 28 |
* Load CSS files for injection into the published HTML.
|
|
|
|
| 29 |
* Tries multiple paths: dev source, Docker copy, relative fallback.
|
| 30 |
*/
|
| 31 |
-
function loadCSS():
|
| 32 |
const candidates = [
|
| 33 |
join(__dirname, "..", "..", "..", "frontend", "src", "styles"),
|
| 34 |
join(__dirname, "..", "..", "frontend-styles"),
|
| 35 |
join(__dirname, "..", "frontend-styles"),
|
| 36 |
];
|
| 37 |
|
|
|
|
|
|
|
| 38 |
for (const dir of candidates) {
|
| 39 |
-
const
|
| 40 |
-
const
|
| 41 |
-
if (existsSync(
|
| 42 |
console.log("[publish] CSS found at:", dir);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
return {
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
};
|
| 47 |
}
|
| 48 |
}
|
| 49 |
|
| 50 |
console.warn("[publish] CSS files not found, tried:", candidates);
|
| 51 |
-
return {
|
| 52 |
}
|
| 53 |
|
| 54 |
interface AuthorObj {
|
|
@@ -169,14 +199,22 @@ export async function publishDocument(docName: string, token?: string): Promise<
|
|
| 169 |
doi: (frontmatter.doi as string) || undefined,
|
| 170 |
};
|
| 171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
const css = loadCSS();
|
| 173 |
-
console.log("[publish] CSS
|
| 174 |
console.log("[publish] Meta:", JSON.stringify(meta));
|
| 175 |
|
| 176 |
-
|
|
|
|
| 177 |
console.log("[publish] Generated HTML length:", html.length);
|
| 178 |
|
| 179 |
-
// Generate PDF + thumbnail
|
| 180 |
let pdf: Buffer | null = null;
|
| 181 |
let thumbnail: Buffer | null = null;
|
| 182 |
|
|
@@ -187,11 +225,15 @@ export async function publishDocument(docName: string, token?: string): Promise<
|
|
| 187 |
thumbnail = assets.thumbnail;
|
| 188 |
} catch (err) {
|
| 189 |
console.error("[publish] PDF generation failed:", err);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
}
|
| 191 |
}
|
| 192 |
|
| 193 |
// Try uploading to HF dataset
|
| 194 |
-
if (
|
| 195 |
try {
|
| 196 |
const urls = await uploadPublishedAssets(docName, {
|
| 197 |
html,
|
|
@@ -207,17 +249,26 @@ export async function publishDocument(docName: string, token?: string): Promise<
|
|
| 207 |
|
| 208 |
// Local storage (primary when HF disabled, fallback when HF fails)
|
| 209 |
const { writeFileSync, mkdirSync } = await import("fs");
|
| 210 |
-
const
|
|
|
|
| 211 |
mkdirSync(publishDir, { recursive: true });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
writeFileSync(join(publishDir, "index.html"), html);
|
| 213 |
if (pdf) writeFileSync(join(publishDir, "article.pdf"), pdf);
|
| 214 |
if (thumbnail) writeFileSync(join(publishDir, "thumb.jpg"), thumbnail);
|
| 215 |
writeFileSync(join(publishDir, "meta.json"), JSON.stringify(meta, null, 2));
|
| 216 |
|
| 217 |
return {
|
| 218 |
-
htmlUrl: `/published/${
|
| 219 |
-
pdfUrl: pdf ? `/published/${
|
| 220 |
-
thumbUrl: thumbnail ? `/published/${
|
| 221 |
success: true,
|
| 222 |
};
|
| 223 |
}
|
|
|
|
| 15 |
import {
|
| 16 |
isHfStorageEnabled,
|
| 17 |
uploadPublishedAssets,
|
| 18 |
+
getPublishedAssetUrl,
|
| 19 |
} from "../hf-storage.js";
|
| 20 |
|
| 21 |
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
| 25 |
return join(DATA_DIR, `${name.replace(/[^a-zA-Z0-9_-]/g, "_")}.yjs`);
|
| 26 |
}
|
| 27 |
|
| 28 |
+
export interface PublishCSS {
|
| 29 |
+
variables: string;
|
| 30 |
+
reset: string;
|
| 31 |
+
base: string;
|
| 32 |
+
layout: string;
|
| 33 |
+
print: string;
|
| 34 |
+
editorTokens: string;
|
| 35 |
+
article: string;
|
| 36 |
+
components: string;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
/**
|
| 40 |
* Load CSS files for injection into the published HTML.
|
| 41 |
+
* Reads the template CSS foundation + editor extensions.
|
| 42 |
* Tries multiple paths: dev source, Docker copy, relative fallback.
|
| 43 |
*/
|
| 44 |
+
function loadCSS(): PublishCSS {
|
| 45 |
const candidates = [
|
| 46 |
join(__dirname, "..", "..", "..", "frontend", "src", "styles"),
|
| 47 |
join(__dirname, "..", "..", "frontend-styles"),
|
| 48 |
join(__dirname, "..", "frontend-styles"),
|
| 49 |
];
|
| 50 |
|
| 51 |
+
const readSafe = (p: string) => (existsSync(p) ? readFileSync(p, "utf-8") : "");
|
| 52 |
+
|
| 53 |
for (const dir of candidates) {
|
| 54 |
+
const varsPath = join(dir, "_variables.css");
|
| 55 |
+
const basePath = join(dir, "_base.css");
|
| 56 |
+
if (existsSync(varsPath) && existsSync(basePath)) {
|
| 57 |
console.log("[publish] CSS found at:", dir);
|
| 58 |
+
|
| 59 |
+
const componentFiles = [
|
| 60 |
+
"_code.css", "_button.css", "_table.css", "_tag.css",
|
| 61 |
+
"_card.css", "_form.css", "_mermaid.css", "_hero.css", "_toc.css",
|
| 62 |
+
];
|
| 63 |
+
const componentsCss = componentFiles
|
| 64 |
+
.map((f) => readSafe(join(dir, "components", f)))
|
| 65 |
+
.join("\n");
|
| 66 |
+
|
| 67 |
return {
|
| 68 |
+
variables: readFileSync(varsPath, "utf-8"),
|
| 69 |
+
reset: readSafe(join(dir, "_reset.css")),
|
| 70 |
+
base: readFileSync(basePath, "utf-8"),
|
| 71 |
+
layout: readSafe(join(dir, "_layout.css")),
|
| 72 |
+
print: readSafe(join(dir, "_print.css")),
|
| 73 |
+
editorTokens: readSafe(join(dir, "_editor-tokens.css")),
|
| 74 |
+
article: readSafe(join(dir, "article.css")),
|
| 75 |
+
components: componentsCss,
|
| 76 |
};
|
| 77 |
}
|
| 78 |
}
|
| 79 |
|
| 80 |
console.warn("[publish] CSS files not found, tried:", candidates);
|
| 81 |
+
return { variables: "", reset: "", base: "", layout: "", print: "", editorTokens: "", article: "", components: "" };
|
| 82 |
}
|
| 83 |
|
| 84 |
interface AuthorObj {
|
|
|
|
| 199 |
doi: (frontmatter.doi as string) || undefined,
|
| 200 |
};
|
| 201 |
|
| 202 |
+
// Pre-compute public URLs so og:image and PDF link are embedded in HTML
|
| 203 |
+
const useHf = isHfStorageEnabled();
|
| 204 |
+
if (useHf && isPdfEnabled()) {
|
| 205 |
+
meta.ogImage = getPublishedAssetUrl(docName, "thumb.jpg");
|
| 206 |
+
meta.pdfUrl = getPublishedAssetUrl(docName, "article.pdf");
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
const css = loadCSS();
|
| 210 |
+
console.log("[publish] CSS variables length:", css.variables.length, "article length:", css.article.length);
|
| 211 |
console.log("[publish] Meta:", JSON.stringify(meta));
|
| 212 |
|
| 213 |
+
// First pass: generate HTML with og:image + PDF link pre-injected
|
| 214 |
+
let html = renderArticleHTML(json, meta, css);
|
| 215 |
console.log("[publish] Generated HTML length:", html.length);
|
| 216 |
|
| 217 |
+
// Generate PDF + thumbnail from the HTML
|
| 218 |
let pdf: Buffer | null = null;
|
| 219 |
let thumbnail: Buffer | null = null;
|
| 220 |
|
|
|
|
| 225 |
thumbnail = assets.thumbnail;
|
| 226 |
} catch (err) {
|
| 227 |
console.error("[publish] PDF generation failed:", err);
|
| 228 |
+
// Clear URLs from meta if generation failed
|
| 229 |
+
if (!thumbnail) delete meta.ogImage;
|
| 230 |
+
if (!pdf) delete meta.pdfUrl;
|
| 231 |
+
html = renderArticleHTML(json, meta, css);
|
| 232 |
}
|
| 233 |
}
|
| 234 |
|
| 235 |
// Try uploading to HF dataset
|
| 236 |
+
if (useHf) {
|
| 237 |
try {
|
| 238 |
const urls = await uploadPublishedAssets(docName, {
|
| 239 |
html,
|
|
|
|
| 249 |
|
| 250 |
// Local storage (primary when HF disabled, fallback when HF fails)
|
| 251 |
const { writeFileSync, mkdirSync } = await import("fs");
|
| 252 |
+
const safeDirName = docName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
| 253 |
+
const publishDir = join(DATA_DIR, "published", safeDirName);
|
| 254 |
mkdirSync(publishDir, { recursive: true });
|
| 255 |
+
|
| 256 |
+
// For local storage, rewrite meta with local URLs
|
| 257 |
+
if (thumbnail) meta.ogImage = `/published/${safeDirName}/thumb.jpg`;
|
| 258 |
+
else delete meta.ogImage;
|
| 259 |
+
if (pdf) meta.pdfUrl = `/published/${safeDirName}/article.pdf`;
|
| 260 |
+
else delete meta.pdfUrl;
|
| 261 |
+
html = renderArticleHTML(json, meta, css);
|
| 262 |
+
|
| 263 |
writeFileSync(join(publishDir, "index.html"), html);
|
| 264 |
if (pdf) writeFileSync(join(publishDir, "article.pdf"), pdf);
|
| 265 |
if (thumbnail) writeFileSync(join(publishDir, "thumb.jpg"), thumbnail);
|
| 266 |
writeFileSync(join(publishDir, "meta.json"), JSON.stringify(meta, null, 2));
|
| 267 |
|
| 268 |
return {
|
| 269 |
+
htmlUrl: `/published/${safeDirName}/index.html`,
|
| 270 |
+
pdfUrl: pdf ? `/published/${safeDirName}/article.pdf` : null,
|
| 271 |
+
thumbUrl: thumbnail ? `/published/${safeDirName}/thumb.jpg` : null,
|
| 272 |
success: true,
|
| 273 |
};
|
| 274 |
}
|
|
@@ -1,11 +1,11 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "
|
| 3 |
"version": "0.1.0",
|
| 4 |
"lockfileVersion": 3,
|
| 5 |
"requires": true,
|
| 6 |
"packages": {
|
| 7 |
"": {
|
| 8 |
-
"name": "
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
| 11 |
"@ai-sdk/react": "^3.0.160",
|
|
@@ -36,6 +36,7 @@
|
|
| 36 |
"ai": "^6.0.158",
|
| 37 |
"katex": "^0.16.45",
|
| 38 |
"lowlight": "^3.2.0",
|
|
|
|
| 39 |
"react": "^18.3.0",
|
| 40 |
"react-dom": "^18.3.0",
|
| 41 |
"tippy.js": "^6.3.7",
|
|
@@ -46,6 +47,7 @@
|
|
| 46 |
"@types/react": "^18.3.0",
|
| 47 |
"@types/react-dom": "^18.3.0",
|
| 48 |
"@vitejs/plugin-react": "^4.3.0",
|
|
|
|
| 49 |
"vite": "^6.0.0"
|
| 50 |
}
|
| 51 |
},
|
|
@@ -113,6 +115,19 @@
|
|
| 113 |
"react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1"
|
| 114 |
}
|
| 115 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
"node_modules/@babel/code-frame": {
|
| 117 |
"version": "7.29.0",
|
| 118 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
|
@@ -402,6 +417,142 @@
|
|
| 402 |
"node": ">=6.9.0"
|
| 403 |
}
|
| 404 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 405 |
"node_modules/@emotion/babel-plugin": {
|
| 406 |
"version": "11.13.5",
|
| 407 |
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
|
@@ -1064,6 +1215,23 @@
|
|
| 1064 |
}
|
| 1065 |
}
|
| 1066 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1067 |
"node_modules/@jridgewell/gen-mapping": {
|
| 1068 |
"version": "0.3.13",
|
| 1069 |
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
|
@@ -1116,6 +1284,15 @@
|
|
| 1116 |
"integrity": "sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==",
|
| 1117 |
"license": "MIT"
|
| 1118 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1119 |
"node_modules/@mui/core-downloads-tracker": {
|
| 1120 |
"version": "9.0.0",
|
| 1121 |
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-9.0.0.tgz",
|
|
@@ -2385,6 +2562,259 @@
|
|
| 2385 |
"@babel/types": "^7.28.2"
|
| 2386 |
}
|
| 2387 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2388 |
"node_modules/@types/estree": {
|
| 2389 |
"version": "1.0.8",
|
| 2390 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
|
@@ -2392,6 +2822,12 @@
|
|
| 2392 |
"dev": true,
|
| 2393 |
"license": "MIT"
|
| 2394 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2395 |
"node_modules/@types/hast": {
|
| 2396 |
"version": "3.0.4",
|
| 2397 |
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
|
@@ -2471,6 +2907,13 @@
|
|
| 2471 |
"@types/react": "*"
|
| 2472 |
}
|
| 2473 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2474 |
"node_modules/@types/unist": {
|
| 2475 |
"version": "3.0.3",
|
| 2476 |
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
|
@@ -2483,6 +2926,16 @@
|
|
| 2483 |
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
| 2484 |
"license": "MIT"
|
| 2485 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2486 |
"node_modules/@vercel/oidc": {
|
| 2487 |
"version": "3.1.0",
|
| 2488 |
"resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.1.0.tgz",
|
|
@@ -2513,6 +2966,18 @@
|
|
| 2513 |
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
| 2514 |
}
|
| 2515 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2516 |
"node_modules/ai": {
|
| 2517 |
"version": "6.0.158",
|
| 2518 |
"resolved": "https://registry.npmjs.org/ai/-/ai-6.0.158.tgz",
|
|
@@ -2630,6 +3095,35 @@
|
|
| 2630 |
],
|
| 2631 |
"license": "CC-BY-4.0"
|
| 2632 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2633 |
"node_modules/clsx": {
|
| 2634 |
"version": "2.1.1",
|
| 2635 |
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
|
@@ -2648,12 +3142,27 @@
|
|
| 2648 |
"node": ">= 12"
|
| 2649 |
}
|
| 2650 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2651 |
"node_modules/convert-source-map": {
|
| 2652 |
"version": "1.9.0",
|
| 2653 |
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
| 2654 |
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
| 2655 |
"license": "MIT"
|
| 2656 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2657 |
"node_modules/cosmiconfig": {
|
| 2658 |
"version": "7.1.0",
|
| 2659 |
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
|
@@ -2691,39 +3200,564 @@
|
|
| 2691 |
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
| 2692 |
"license": "MIT"
|
| 2693 |
},
|
| 2694 |
-
"node_modules/
|
| 2695 |
-
"version": "
|
| 2696 |
-
"resolved": "https://registry.npmjs.org/
|
| 2697 |
-
"integrity": "sha512-
|
| 2698 |
"license": "MIT",
|
| 2699 |
-
"
|
| 2700 |
-
"ms": "^2.1.3"
|
| 2701 |
-
},
|
| 2702 |
"engines": {
|
| 2703 |
-
"node": ">=
|
| 2704 |
-
},
|
| 2705 |
-
"peerDependenciesMeta": {
|
| 2706 |
-
"supports-color": {
|
| 2707 |
-
"optional": true
|
| 2708 |
-
}
|
| 2709 |
}
|
| 2710 |
},
|
| 2711 |
-
"node_modules/
|
| 2712 |
-
"version": "
|
| 2713 |
-
"resolved": "https://registry.npmjs.org/
|
| 2714 |
-
"integrity": "sha512-
|
| 2715 |
"license": "MIT",
|
| 2716 |
-
"
|
| 2717 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2718 |
}
|
| 2719 |
},
|
| 2720 |
-
"node_modules/
|
| 2721 |
-
"version": "
|
| 2722 |
-
"resolved": "https://registry.npmjs.org/
|
| 2723 |
-
"integrity": "sha512-
|
| 2724 |
"license": "MIT",
|
| 2725 |
"dependencies": {
|
| 2726 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2727 |
},
|
| 2728 |
"funding": {
|
| 2729 |
"type": "github",
|
|
@@ -2740,6 +3774,15 @@
|
|
| 2740 |
"csstype": "^3.0.2"
|
| 2741 |
}
|
| 2742 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2743 |
"node_modules/electron-to-chromium": {
|
| 2744 |
"version": "1.5.335",
|
| 2745 |
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.335.tgz",
|
|
@@ -2917,6 +3960,12 @@
|
|
| 2917 |
"node": ">=6.9.0"
|
| 2918 |
}
|
| 2919 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2920 |
"node_modules/hasown": {
|
| 2921 |
"version": "2.0.2",
|
| 2922 |
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
|
@@ -2954,6 +4003,18 @@
|
|
| 2954 |
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
| 2955 |
"license": "MIT"
|
| 2956 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2957 |
"node_modules/import-fresh": {
|
| 2958 |
"version": "3.3.1",
|
| 2959 |
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
|
@@ -2970,6 +4031,15 @@
|
|
| 2970 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 2971 |
}
|
| 2972 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2973 |
"node_modules/is-arrayish": {
|
| 2974 |
"version": "0.2.1",
|
| 2975 |
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
|
@@ -3061,6 +4131,35 @@
|
|
| 3061 |
"katex": "cli.js"
|
| 3062 |
}
|
| 3063 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3064 |
"node_modules/lib0": {
|
| 3065 |
"version": "0.2.117",
|
| 3066 |
"resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.117.tgz",
|
|
@@ -3103,6 +4202,12 @@
|
|
| 3103 |
"integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==",
|
| 3104 |
"license": "MIT"
|
| 3105 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3106 |
"node_modules/loose-envify": {
|
| 3107 |
"version": "1.4.0",
|
| 3108 |
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
@@ -3158,12 +4263,71 @@
|
|
| 3158 |
"markdown-it": "bin/markdown-it.mjs"
|
| 3159 |
}
|
| 3160 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3161 |
"node_modules/mdurl": {
|
| 3162 |
"version": "2.0.0",
|
| 3163 |
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
| 3164 |
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
| 3165 |
"license": "MIT"
|
| 3166 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3167 |
"node_modules/ms": {
|
| 3168 |
"version": "2.1.3",
|
| 3169 |
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
@@ -3211,6 +4375,12 @@
|
|
| 3211 |
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
| 3212 |
"license": "MIT"
|
| 3213 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3214 |
"node_modules/parent-module": {
|
| 3215 |
"version": "1.0.1",
|
| 3216 |
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
|
@@ -3241,6 +4411,12 @@
|
|
| 3241 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 3242 |
}
|
| 3243 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3244 |
"node_modules/path-parse": {
|
| 3245 |
"version": "1.0.7",
|
| 3246 |
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
|
@@ -3256,6 +4432,12 @@
|
|
| 3256 |
"node": ">=8"
|
| 3257 |
}
|
| 3258 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3259 |
"node_modules/picocolors": {
|
| 3260 |
"version": "1.1.1",
|
| 3261 |
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
|
@@ -3276,6 +4458,33 @@
|
|
| 3276 |
"url": "https://github.com/sponsors/jonschlinkert"
|
| 3277 |
}
|
| 3278 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3279 |
"node_modules/postcss": {
|
| 3280 |
"version": "8.5.9",
|
| 3281 |
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
|
|
@@ -3296,6 +4505,7 @@
|
|
| 3296 |
}
|
| 3297 |
],
|
| 3298 |
"license": "MIT",
|
|
|
|
| 3299 |
"dependencies": {
|
| 3300 |
"nanoid": "^3.3.11",
|
| 3301 |
"picocolors": "^1.1.1",
|
|
@@ -3305,6 +4515,35 @@
|
|
| 3305 |
"node": "^10 || ^12 || >=14"
|
| 3306 |
}
|
| 3307 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3308 |
"node_modules/prop-types": {
|
| 3309 |
"version": "15.8.1",
|
| 3310 |
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
|
@@ -3618,6 +4857,12 @@
|
|
| 3618 |
"node": ">=4"
|
| 3619 |
}
|
| 3620 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3621 |
"node_modules/rollup": {
|
| 3622 |
"version": "4.60.1",
|
| 3623 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz",
|
|
@@ -3669,6 +4914,30 @@
|
|
| 3669 |
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
| 3670 |
"license": "MIT"
|
| 3671 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3672 |
"node_modules/scheduler": {
|
| 3673 |
"version": "0.23.2",
|
| 3674 |
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
|
@@ -3750,6 +5019,15 @@
|
|
| 3750 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 3751 |
}
|
| 3752 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3753 |
"node_modules/tinyglobby": {
|
| 3754 |
"version": "0.2.16",
|
| 3755 |
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
|
|
@@ -3776,12 +5054,27 @@
|
|
| 3776 |
"@popperjs/core": "^2.9.0"
|
| 3777 |
}
|
| 3778 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3779 |
"node_modules/uc.micro": {
|
| 3780 |
"version": "2.1.0",
|
| 3781 |
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
| 3782 |
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
| 3783 |
"license": "MIT"
|
| 3784 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3785 |
"node_modules/update-browserslist-db": {
|
| 3786 |
"version": "1.2.3",
|
| 3787 |
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
|
@@ -3822,6 +5115,19 @@
|
|
| 3822 |
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
| 3823 |
}
|
| 3824 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3825 |
"node_modules/vite": {
|
| 3826 |
"version": "6.4.2",
|
| 3827 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
|
|
@@ -3898,6 +5204,55 @@
|
|
| 3898 |
}
|
| 3899 |
}
|
| 3900 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3901 |
"node_modules/w3c-keyname": {
|
| 3902 |
"version": "2.2.8",
|
| 3903 |
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "research-article-template-editor-frontend",
|
| 3 |
"version": "0.1.0",
|
| 4 |
"lockfileVersion": 3,
|
| 5 |
"requires": true,
|
| 6 |
"packages": {
|
| 7 |
"": {
|
| 8 |
+
"name": "research-article-template-editor-frontend",
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
| 11 |
"@ai-sdk/react": "^3.0.160",
|
|
|
|
| 36 |
"ai": "^6.0.158",
|
| 37 |
"katex": "^0.16.45",
|
| 38 |
"lowlight": "^3.2.0",
|
| 39 |
+
"mermaid": "^11.14.0",
|
| 40 |
"react": "^18.3.0",
|
| 41 |
"react-dom": "^18.3.0",
|
| 42 |
"tippy.js": "^6.3.7",
|
|
|
|
| 47 |
"@types/react": "^18.3.0",
|
| 48 |
"@types/react-dom": "^18.3.0",
|
| 49 |
"@vitejs/plugin-react": "^4.3.0",
|
| 50 |
+
"postcss-custom-media": "^12.0.1",
|
| 51 |
"vite": "^6.0.0"
|
| 52 |
}
|
| 53 |
},
|
|
|
|
| 115 |
"react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1"
|
| 116 |
}
|
| 117 |
},
|
| 118 |
+
"node_modules/@antfu/install-pkg": {
|
| 119 |
+
"version": "1.1.0",
|
| 120 |
+
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
|
| 121 |
+
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
|
| 122 |
+
"license": "MIT",
|
| 123 |
+
"dependencies": {
|
| 124 |
+
"package-manager-detector": "^1.3.0",
|
| 125 |
+
"tinyexec": "^1.0.1"
|
| 126 |
+
},
|
| 127 |
+
"funding": {
|
| 128 |
+
"url": "https://github.com/sponsors/antfu"
|
| 129 |
+
}
|
| 130 |
+
},
|
| 131 |
"node_modules/@babel/code-frame": {
|
| 132 |
"version": "7.29.0",
|
| 133 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
|
|
|
| 417 |
"node": ">=6.9.0"
|
| 418 |
}
|
| 419 |
},
|
| 420 |
+
"node_modules/@braintree/sanitize-url": {
|
| 421 |
+
"version": "7.1.2",
|
| 422 |
+
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz",
|
| 423 |
+
"integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==",
|
| 424 |
+
"license": "MIT"
|
| 425 |
+
},
|
| 426 |
+
"node_modules/@chevrotain/cst-dts-gen": {
|
| 427 |
+
"version": "12.0.0",
|
| 428 |
+
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-12.0.0.tgz",
|
| 429 |
+
"integrity": "sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==",
|
| 430 |
+
"license": "Apache-2.0",
|
| 431 |
+
"dependencies": {
|
| 432 |
+
"@chevrotain/gast": "12.0.0",
|
| 433 |
+
"@chevrotain/types": "12.0.0"
|
| 434 |
+
}
|
| 435 |
+
},
|
| 436 |
+
"node_modules/@chevrotain/gast": {
|
| 437 |
+
"version": "12.0.0",
|
| 438 |
+
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-12.0.0.tgz",
|
| 439 |
+
"integrity": "sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==",
|
| 440 |
+
"license": "Apache-2.0",
|
| 441 |
+
"dependencies": {
|
| 442 |
+
"@chevrotain/types": "12.0.0"
|
| 443 |
+
}
|
| 444 |
+
},
|
| 445 |
+
"node_modules/@chevrotain/regexp-to-ast": {
|
| 446 |
+
"version": "12.0.0",
|
| 447 |
+
"resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-12.0.0.tgz",
|
| 448 |
+
"integrity": "sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==",
|
| 449 |
+
"license": "Apache-2.0"
|
| 450 |
+
},
|
| 451 |
+
"node_modules/@chevrotain/types": {
|
| 452 |
+
"version": "12.0.0",
|
| 453 |
+
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-12.0.0.tgz",
|
| 454 |
+
"integrity": "sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==",
|
| 455 |
+
"license": "Apache-2.0"
|
| 456 |
+
},
|
| 457 |
+
"node_modules/@chevrotain/utils": {
|
| 458 |
+
"version": "12.0.0",
|
| 459 |
+
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-12.0.0.tgz",
|
| 460 |
+
"integrity": "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==",
|
| 461 |
+
"license": "Apache-2.0"
|
| 462 |
+
},
|
| 463 |
+
"node_modules/@csstools/cascade-layer-name-parser": {
|
| 464 |
+
"version": "3.0.0",
|
| 465 |
+
"resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-3.0.0.tgz",
|
| 466 |
+
"integrity": "sha512-/3iksyevwRfSJx5yH0RkcrcYXwuhMQx3Juqf40t97PeEy2/Mz2TItZ/z/216qpe4GgOyFBP8MKIwVvytzHmfIQ==",
|
| 467 |
+
"dev": true,
|
| 468 |
+
"funding": [
|
| 469 |
+
{
|
| 470 |
+
"type": "github",
|
| 471 |
+
"url": "https://github.com/sponsors/csstools"
|
| 472 |
+
},
|
| 473 |
+
{
|
| 474 |
+
"type": "opencollective",
|
| 475 |
+
"url": "https://opencollective.com/csstools"
|
| 476 |
+
}
|
| 477 |
+
],
|
| 478 |
+
"license": "MIT",
|
| 479 |
+
"engines": {
|
| 480 |
+
"node": ">=20.19.0"
|
| 481 |
+
},
|
| 482 |
+
"peerDependencies": {
|
| 483 |
+
"@csstools/css-parser-algorithms": "^4.0.0",
|
| 484 |
+
"@csstools/css-tokenizer": "^4.0.0"
|
| 485 |
+
}
|
| 486 |
+
},
|
| 487 |
+
"node_modules/@csstools/css-parser-algorithms": {
|
| 488 |
+
"version": "4.0.0",
|
| 489 |
+
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
|
| 490 |
+
"integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
|
| 491 |
+
"dev": true,
|
| 492 |
+
"funding": [
|
| 493 |
+
{
|
| 494 |
+
"type": "github",
|
| 495 |
+
"url": "https://github.com/sponsors/csstools"
|
| 496 |
+
},
|
| 497 |
+
{
|
| 498 |
+
"type": "opencollective",
|
| 499 |
+
"url": "https://opencollective.com/csstools"
|
| 500 |
+
}
|
| 501 |
+
],
|
| 502 |
+
"license": "MIT",
|
| 503 |
+
"peer": true,
|
| 504 |
+
"engines": {
|
| 505 |
+
"node": ">=20.19.0"
|
| 506 |
+
},
|
| 507 |
+
"peerDependencies": {
|
| 508 |
+
"@csstools/css-tokenizer": "^4.0.0"
|
| 509 |
+
}
|
| 510 |
+
},
|
| 511 |
+
"node_modules/@csstools/css-tokenizer": {
|
| 512 |
+
"version": "4.0.0",
|
| 513 |
+
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
|
| 514 |
+
"integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
|
| 515 |
+
"dev": true,
|
| 516 |
+
"funding": [
|
| 517 |
+
{
|
| 518 |
+
"type": "github",
|
| 519 |
+
"url": "https://github.com/sponsors/csstools"
|
| 520 |
+
},
|
| 521 |
+
{
|
| 522 |
+
"type": "opencollective",
|
| 523 |
+
"url": "https://opencollective.com/csstools"
|
| 524 |
+
}
|
| 525 |
+
],
|
| 526 |
+
"license": "MIT",
|
| 527 |
+
"peer": true,
|
| 528 |
+
"engines": {
|
| 529 |
+
"node": ">=20.19.0"
|
| 530 |
+
}
|
| 531 |
+
},
|
| 532 |
+
"node_modules/@csstools/media-query-list-parser": {
|
| 533 |
+
"version": "5.0.0",
|
| 534 |
+
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz",
|
| 535 |
+
"integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==",
|
| 536 |
+
"dev": true,
|
| 537 |
+
"funding": [
|
| 538 |
+
{
|
| 539 |
+
"type": "github",
|
| 540 |
+
"url": "https://github.com/sponsors/csstools"
|
| 541 |
+
},
|
| 542 |
+
{
|
| 543 |
+
"type": "opencollective",
|
| 544 |
+
"url": "https://opencollective.com/csstools"
|
| 545 |
+
}
|
| 546 |
+
],
|
| 547 |
+
"license": "MIT",
|
| 548 |
+
"engines": {
|
| 549 |
+
"node": ">=20.19.0"
|
| 550 |
+
},
|
| 551 |
+
"peerDependencies": {
|
| 552 |
+
"@csstools/css-parser-algorithms": "^4.0.0",
|
| 553 |
+
"@csstools/css-tokenizer": "^4.0.0"
|
| 554 |
+
}
|
| 555 |
+
},
|
| 556 |
"node_modules/@emotion/babel-plugin": {
|
| 557 |
"version": "11.13.5",
|
| 558 |
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
|
|
|
| 1215 |
}
|
| 1216 |
}
|
| 1217 |
},
|
| 1218 |
+
"node_modules/@iconify/types": {
|
| 1219 |
+
"version": "2.0.0",
|
| 1220 |
+
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
|
| 1221 |
+
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
|
| 1222 |
+
"license": "MIT"
|
| 1223 |
+
},
|
| 1224 |
+
"node_modules/@iconify/utils": {
|
| 1225 |
+
"version": "3.1.0",
|
| 1226 |
+
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz",
|
| 1227 |
+
"integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==",
|
| 1228 |
+
"license": "MIT",
|
| 1229 |
+
"dependencies": {
|
| 1230 |
+
"@antfu/install-pkg": "^1.1.0",
|
| 1231 |
+
"@iconify/types": "^2.0.0",
|
| 1232 |
+
"mlly": "^1.8.0"
|
| 1233 |
+
}
|
| 1234 |
+
},
|
| 1235 |
"node_modules/@jridgewell/gen-mapping": {
|
| 1236 |
"version": "0.3.13",
|
| 1237 |
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
|
|
|
| 1284 |
"integrity": "sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==",
|
| 1285 |
"license": "MIT"
|
| 1286 |
},
|
| 1287 |
+
"node_modules/@mermaid-js/parser": {
|
| 1288 |
+
"version": "1.1.0",
|
| 1289 |
+
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.1.0.tgz",
|
| 1290 |
+
"integrity": "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw==",
|
| 1291 |
+
"license": "MIT",
|
| 1292 |
+
"dependencies": {
|
| 1293 |
+
"langium": "^4.0.0"
|
| 1294 |
+
}
|
| 1295 |
+
},
|
| 1296 |
"node_modules/@mui/core-downloads-tracker": {
|
| 1297 |
"version": "9.0.0",
|
| 1298 |
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-9.0.0.tgz",
|
|
|
|
| 2562 |
"@babel/types": "^7.28.2"
|
| 2563 |
}
|
| 2564 |
},
|
| 2565 |
+
"node_modules/@types/d3": {
|
| 2566 |
+
"version": "7.4.3",
|
| 2567 |
+
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
|
| 2568 |
+
"integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
|
| 2569 |
+
"license": "MIT",
|
| 2570 |
+
"dependencies": {
|
| 2571 |
+
"@types/d3-array": "*",
|
| 2572 |
+
"@types/d3-axis": "*",
|
| 2573 |
+
"@types/d3-brush": "*",
|
| 2574 |
+
"@types/d3-chord": "*",
|
| 2575 |
+
"@types/d3-color": "*",
|
| 2576 |
+
"@types/d3-contour": "*",
|
| 2577 |
+
"@types/d3-delaunay": "*",
|
| 2578 |
+
"@types/d3-dispatch": "*",
|
| 2579 |
+
"@types/d3-drag": "*",
|
| 2580 |
+
"@types/d3-dsv": "*",
|
| 2581 |
+
"@types/d3-ease": "*",
|
| 2582 |
+
"@types/d3-fetch": "*",
|
| 2583 |
+
"@types/d3-force": "*",
|
| 2584 |
+
"@types/d3-format": "*",
|
| 2585 |
+
"@types/d3-geo": "*",
|
| 2586 |
+
"@types/d3-hierarchy": "*",
|
| 2587 |
+
"@types/d3-interpolate": "*",
|
| 2588 |
+
"@types/d3-path": "*",
|
| 2589 |
+
"@types/d3-polygon": "*",
|
| 2590 |
+
"@types/d3-quadtree": "*",
|
| 2591 |
+
"@types/d3-random": "*",
|
| 2592 |
+
"@types/d3-scale": "*",
|
| 2593 |
+
"@types/d3-scale-chromatic": "*",
|
| 2594 |
+
"@types/d3-selection": "*",
|
| 2595 |
+
"@types/d3-shape": "*",
|
| 2596 |
+
"@types/d3-time": "*",
|
| 2597 |
+
"@types/d3-time-format": "*",
|
| 2598 |
+
"@types/d3-timer": "*",
|
| 2599 |
+
"@types/d3-transition": "*",
|
| 2600 |
+
"@types/d3-zoom": "*"
|
| 2601 |
+
}
|
| 2602 |
+
},
|
| 2603 |
+
"node_modules/@types/d3-array": {
|
| 2604 |
+
"version": "3.2.2",
|
| 2605 |
+
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
|
| 2606 |
+
"integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
|
| 2607 |
+
"license": "MIT"
|
| 2608 |
+
},
|
| 2609 |
+
"node_modules/@types/d3-axis": {
|
| 2610 |
+
"version": "3.0.6",
|
| 2611 |
+
"resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz",
|
| 2612 |
+
"integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
|
| 2613 |
+
"license": "MIT",
|
| 2614 |
+
"dependencies": {
|
| 2615 |
+
"@types/d3-selection": "*"
|
| 2616 |
+
}
|
| 2617 |
+
},
|
| 2618 |
+
"node_modules/@types/d3-brush": {
|
| 2619 |
+
"version": "3.0.6",
|
| 2620 |
+
"resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz",
|
| 2621 |
+
"integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
|
| 2622 |
+
"license": "MIT",
|
| 2623 |
+
"dependencies": {
|
| 2624 |
+
"@types/d3-selection": "*"
|
| 2625 |
+
}
|
| 2626 |
+
},
|
| 2627 |
+
"node_modules/@types/d3-chord": {
|
| 2628 |
+
"version": "3.0.6",
|
| 2629 |
+
"resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz",
|
| 2630 |
+
"integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==",
|
| 2631 |
+
"license": "MIT"
|
| 2632 |
+
},
|
| 2633 |
+
"node_modules/@types/d3-color": {
|
| 2634 |
+
"version": "3.1.3",
|
| 2635 |
+
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
|
| 2636 |
+
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
|
| 2637 |
+
"license": "MIT"
|
| 2638 |
+
},
|
| 2639 |
+
"node_modules/@types/d3-contour": {
|
| 2640 |
+
"version": "3.0.6",
|
| 2641 |
+
"resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz",
|
| 2642 |
+
"integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
|
| 2643 |
+
"license": "MIT",
|
| 2644 |
+
"dependencies": {
|
| 2645 |
+
"@types/d3-array": "*",
|
| 2646 |
+
"@types/geojson": "*"
|
| 2647 |
+
}
|
| 2648 |
+
},
|
| 2649 |
+
"node_modules/@types/d3-delaunay": {
|
| 2650 |
+
"version": "6.0.4",
|
| 2651 |
+
"resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
|
| 2652 |
+
"integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==",
|
| 2653 |
+
"license": "MIT"
|
| 2654 |
+
},
|
| 2655 |
+
"node_modules/@types/d3-dispatch": {
|
| 2656 |
+
"version": "3.0.7",
|
| 2657 |
+
"resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz",
|
| 2658 |
+
"integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==",
|
| 2659 |
+
"license": "MIT"
|
| 2660 |
+
},
|
| 2661 |
+
"node_modules/@types/d3-drag": {
|
| 2662 |
+
"version": "3.0.7",
|
| 2663 |
+
"resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
|
| 2664 |
+
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
|
| 2665 |
+
"license": "MIT",
|
| 2666 |
+
"dependencies": {
|
| 2667 |
+
"@types/d3-selection": "*"
|
| 2668 |
+
}
|
| 2669 |
+
},
|
| 2670 |
+
"node_modules/@types/d3-dsv": {
|
| 2671 |
+
"version": "3.0.7",
|
| 2672 |
+
"resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",
|
| 2673 |
+
"integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==",
|
| 2674 |
+
"license": "MIT"
|
| 2675 |
+
},
|
| 2676 |
+
"node_modules/@types/d3-ease": {
|
| 2677 |
+
"version": "3.0.2",
|
| 2678 |
+
"resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
|
| 2679 |
+
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
| 2680 |
+
"license": "MIT"
|
| 2681 |
+
},
|
| 2682 |
+
"node_modules/@types/d3-fetch": {
|
| 2683 |
+
"version": "3.0.7",
|
| 2684 |
+
"resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",
|
| 2685 |
+
"integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
|
| 2686 |
+
"license": "MIT",
|
| 2687 |
+
"dependencies": {
|
| 2688 |
+
"@types/d3-dsv": "*"
|
| 2689 |
+
}
|
| 2690 |
+
},
|
| 2691 |
+
"node_modules/@types/d3-force": {
|
| 2692 |
+
"version": "3.0.10",
|
| 2693 |
+
"resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz",
|
| 2694 |
+
"integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",
|
| 2695 |
+
"license": "MIT"
|
| 2696 |
+
},
|
| 2697 |
+
"node_modules/@types/d3-format": {
|
| 2698 |
+
"version": "3.0.4",
|
| 2699 |
+
"resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz",
|
| 2700 |
+
"integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==",
|
| 2701 |
+
"license": "MIT"
|
| 2702 |
+
},
|
| 2703 |
+
"node_modules/@types/d3-geo": {
|
| 2704 |
+
"version": "3.1.0",
|
| 2705 |
+
"resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz",
|
| 2706 |
+
"integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
|
| 2707 |
+
"license": "MIT",
|
| 2708 |
+
"dependencies": {
|
| 2709 |
+
"@types/geojson": "*"
|
| 2710 |
+
}
|
| 2711 |
+
},
|
| 2712 |
+
"node_modules/@types/d3-hierarchy": {
|
| 2713 |
+
"version": "3.1.7",
|
| 2714 |
+
"resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
|
| 2715 |
+
"integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",
|
| 2716 |
+
"license": "MIT"
|
| 2717 |
+
},
|
| 2718 |
+
"node_modules/@types/d3-interpolate": {
|
| 2719 |
+
"version": "3.0.4",
|
| 2720 |
+
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
|
| 2721 |
+
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
|
| 2722 |
+
"license": "MIT",
|
| 2723 |
+
"dependencies": {
|
| 2724 |
+
"@types/d3-color": "*"
|
| 2725 |
+
}
|
| 2726 |
+
},
|
| 2727 |
+
"node_modules/@types/d3-path": {
|
| 2728 |
+
"version": "3.1.1",
|
| 2729 |
+
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
|
| 2730 |
+
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
|
| 2731 |
+
"license": "MIT"
|
| 2732 |
+
},
|
| 2733 |
+
"node_modules/@types/d3-polygon": {
|
| 2734 |
+
"version": "3.0.2",
|
| 2735 |
+
"resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",
|
| 2736 |
+
"integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==",
|
| 2737 |
+
"license": "MIT"
|
| 2738 |
+
},
|
| 2739 |
+
"node_modules/@types/d3-quadtree": {
|
| 2740 |
+
"version": "3.0.6",
|
| 2741 |
+
"resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",
|
| 2742 |
+
"integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==",
|
| 2743 |
+
"license": "MIT"
|
| 2744 |
+
},
|
| 2745 |
+
"node_modules/@types/d3-random": {
|
| 2746 |
+
"version": "3.0.3",
|
| 2747 |
+
"resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz",
|
| 2748 |
+
"integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==",
|
| 2749 |
+
"license": "MIT"
|
| 2750 |
+
},
|
| 2751 |
+
"node_modules/@types/d3-scale": {
|
| 2752 |
+
"version": "4.0.9",
|
| 2753 |
+
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
|
| 2754 |
+
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
|
| 2755 |
+
"license": "MIT",
|
| 2756 |
+
"dependencies": {
|
| 2757 |
+
"@types/d3-time": "*"
|
| 2758 |
+
}
|
| 2759 |
+
},
|
| 2760 |
+
"node_modules/@types/d3-scale-chromatic": {
|
| 2761 |
+
"version": "3.1.0",
|
| 2762 |
+
"resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
|
| 2763 |
+
"integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==",
|
| 2764 |
+
"license": "MIT"
|
| 2765 |
+
},
|
| 2766 |
+
"node_modules/@types/d3-selection": {
|
| 2767 |
+
"version": "3.0.11",
|
| 2768 |
+
"resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
|
| 2769 |
+
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
|
| 2770 |
+
"license": "MIT"
|
| 2771 |
+
},
|
| 2772 |
+
"node_modules/@types/d3-shape": {
|
| 2773 |
+
"version": "3.1.8",
|
| 2774 |
+
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz",
|
| 2775 |
+
"integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==",
|
| 2776 |
+
"license": "MIT",
|
| 2777 |
+
"dependencies": {
|
| 2778 |
+
"@types/d3-path": "*"
|
| 2779 |
+
}
|
| 2780 |
+
},
|
| 2781 |
+
"node_modules/@types/d3-time": {
|
| 2782 |
+
"version": "3.0.4",
|
| 2783 |
+
"resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
|
| 2784 |
+
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
|
| 2785 |
+
"license": "MIT"
|
| 2786 |
+
},
|
| 2787 |
+
"node_modules/@types/d3-time-format": {
|
| 2788 |
+
"version": "4.0.3",
|
| 2789 |
+
"resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",
|
| 2790 |
+
"integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==",
|
| 2791 |
+
"license": "MIT"
|
| 2792 |
+
},
|
| 2793 |
+
"node_modules/@types/d3-timer": {
|
| 2794 |
+
"version": "3.0.2",
|
| 2795 |
+
"resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
|
| 2796 |
+
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
| 2797 |
+
"license": "MIT"
|
| 2798 |
+
},
|
| 2799 |
+
"node_modules/@types/d3-transition": {
|
| 2800 |
+
"version": "3.0.9",
|
| 2801 |
+
"resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
|
| 2802 |
+
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
|
| 2803 |
+
"license": "MIT",
|
| 2804 |
+
"dependencies": {
|
| 2805 |
+
"@types/d3-selection": "*"
|
| 2806 |
+
}
|
| 2807 |
+
},
|
| 2808 |
+
"node_modules/@types/d3-zoom": {
|
| 2809 |
+
"version": "3.0.8",
|
| 2810 |
+
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
|
| 2811 |
+
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
|
| 2812 |
+
"license": "MIT",
|
| 2813 |
+
"dependencies": {
|
| 2814 |
+
"@types/d3-interpolate": "*",
|
| 2815 |
+
"@types/d3-selection": "*"
|
| 2816 |
+
}
|
| 2817 |
+
},
|
| 2818 |
"node_modules/@types/estree": {
|
| 2819 |
"version": "1.0.8",
|
| 2820 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
|
|
|
| 2822 |
"dev": true,
|
| 2823 |
"license": "MIT"
|
| 2824 |
},
|
| 2825 |
+
"node_modules/@types/geojson": {
|
| 2826 |
+
"version": "7946.0.16",
|
| 2827 |
+
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
|
| 2828 |
+
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
|
| 2829 |
+
"license": "MIT"
|
| 2830 |
+
},
|
| 2831 |
"node_modules/@types/hast": {
|
| 2832 |
"version": "3.0.4",
|
| 2833 |
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
|
|
|
| 2907 |
"@types/react": "*"
|
| 2908 |
}
|
| 2909 |
},
|
| 2910 |
+
"node_modules/@types/trusted-types": {
|
| 2911 |
+
"version": "2.0.7",
|
| 2912 |
+
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
| 2913 |
+
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
| 2914 |
+
"license": "MIT",
|
| 2915 |
+
"optional": true
|
| 2916 |
+
},
|
| 2917 |
"node_modules/@types/unist": {
|
| 2918 |
"version": "3.0.3",
|
| 2919 |
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
|
|
|
| 2926 |
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
| 2927 |
"license": "MIT"
|
| 2928 |
},
|
| 2929 |
+
"node_modules/@upsetjs/venn.js": {
|
| 2930 |
+
"version": "2.0.0",
|
| 2931 |
+
"resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz",
|
| 2932 |
+
"integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==",
|
| 2933 |
+
"license": "MIT",
|
| 2934 |
+
"optionalDependencies": {
|
| 2935 |
+
"d3-selection": "^3.0.0",
|
| 2936 |
+
"d3-transition": "^3.0.1"
|
| 2937 |
+
}
|
| 2938 |
+
},
|
| 2939 |
"node_modules/@vercel/oidc": {
|
| 2940 |
"version": "3.1.0",
|
| 2941 |
"resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.1.0.tgz",
|
|
|
|
| 2966 |
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
| 2967 |
}
|
| 2968 |
},
|
| 2969 |
+
"node_modules/acorn": {
|
| 2970 |
+
"version": "8.16.0",
|
| 2971 |
+
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
| 2972 |
+
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
| 2973 |
+
"license": "MIT",
|
| 2974 |
+
"bin": {
|
| 2975 |
+
"acorn": "bin/acorn"
|
| 2976 |
+
},
|
| 2977 |
+
"engines": {
|
| 2978 |
+
"node": ">=0.4.0"
|
| 2979 |
+
}
|
| 2980 |
+
},
|
| 2981 |
"node_modules/ai": {
|
| 2982 |
"version": "6.0.158",
|
| 2983 |
"resolved": "https://registry.npmjs.org/ai/-/ai-6.0.158.tgz",
|
|
|
|
| 3095 |
],
|
| 3096 |
"license": "CC-BY-4.0"
|
| 3097 |
},
|
| 3098 |
+
"node_modules/chevrotain": {
|
| 3099 |
+
"version": "12.0.0",
|
| 3100 |
+
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-12.0.0.tgz",
|
| 3101 |
+
"integrity": "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==",
|
| 3102 |
+
"license": "Apache-2.0",
|
| 3103 |
+
"peer": true,
|
| 3104 |
+
"dependencies": {
|
| 3105 |
+
"@chevrotain/cst-dts-gen": "12.0.0",
|
| 3106 |
+
"@chevrotain/gast": "12.0.0",
|
| 3107 |
+
"@chevrotain/regexp-to-ast": "12.0.0",
|
| 3108 |
+
"@chevrotain/types": "12.0.0",
|
| 3109 |
+
"@chevrotain/utils": "12.0.0"
|
| 3110 |
+
},
|
| 3111 |
+
"engines": {
|
| 3112 |
+
"node": ">=22.0.0"
|
| 3113 |
+
}
|
| 3114 |
+
},
|
| 3115 |
+
"node_modules/chevrotain-allstar": {
|
| 3116 |
+
"version": "0.4.1",
|
| 3117 |
+
"resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.4.1.tgz",
|
| 3118 |
+
"integrity": "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA==",
|
| 3119 |
+
"license": "MIT",
|
| 3120 |
+
"dependencies": {
|
| 3121 |
+
"lodash-es": "^4.17.21"
|
| 3122 |
+
},
|
| 3123 |
+
"peerDependencies": {
|
| 3124 |
+
"chevrotain": "^12.0.0"
|
| 3125 |
+
}
|
| 3126 |
+
},
|
| 3127 |
"node_modules/clsx": {
|
| 3128 |
"version": "2.1.1",
|
| 3129 |
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
|
|
|
| 3142 |
"node": ">= 12"
|
| 3143 |
}
|
| 3144 |
},
|
| 3145 |
+
"node_modules/confbox": {
|
| 3146 |
+
"version": "0.1.8",
|
| 3147 |
+
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
| 3148 |
+
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
| 3149 |
+
"license": "MIT"
|
| 3150 |
+
},
|
| 3151 |
"node_modules/convert-source-map": {
|
| 3152 |
"version": "1.9.0",
|
| 3153 |
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
| 3154 |
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
| 3155 |
"license": "MIT"
|
| 3156 |
},
|
| 3157 |
+
"node_modules/cose-base": {
|
| 3158 |
+
"version": "1.0.3",
|
| 3159 |
+
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",
|
| 3160 |
+
"integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==",
|
| 3161 |
+
"license": "MIT",
|
| 3162 |
+
"dependencies": {
|
| 3163 |
+
"layout-base": "^1.0.0"
|
| 3164 |
+
}
|
| 3165 |
+
},
|
| 3166 |
"node_modules/cosmiconfig": {
|
| 3167 |
"version": "7.1.0",
|
| 3168 |
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
|
|
|
| 3200 |
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
| 3201 |
"license": "MIT"
|
| 3202 |
},
|
| 3203 |
+
"node_modules/cytoscape": {
|
| 3204 |
+
"version": "3.33.2",
|
| 3205 |
+
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.2.tgz",
|
| 3206 |
+
"integrity": "sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw==",
|
| 3207 |
"license": "MIT",
|
| 3208 |
+
"peer": true,
|
|
|
|
|
|
|
| 3209 |
"engines": {
|
| 3210 |
+
"node": ">=0.10"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3211 |
}
|
| 3212 |
},
|
| 3213 |
+
"node_modules/cytoscape-cose-bilkent": {
|
| 3214 |
+
"version": "4.1.0",
|
| 3215 |
+
"resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz",
|
| 3216 |
+
"integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==",
|
| 3217 |
"license": "MIT",
|
| 3218 |
+
"dependencies": {
|
| 3219 |
+
"cose-base": "^1.0.0"
|
| 3220 |
+
},
|
| 3221 |
+
"peerDependencies": {
|
| 3222 |
+
"cytoscape": "^3.2.0"
|
| 3223 |
}
|
| 3224 |
},
|
| 3225 |
+
"node_modules/cytoscape-fcose": {
|
| 3226 |
+
"version": "2.2.0",
|
| 3227 |
+
"resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
|
| 3228 |
+
"integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
|
| 3229 |
"license": "MIT",
|
| 3230 |
"dependencies": {
|
| 3231 |
+
"cose-base": "^2.2.0"
|
| 3232 |
+
},
|
| 3233 |
+
"peerDependencies": {
|
| 3234 |
+
"cytoscape": "^3.2.0"
|
| 3235 |
+
}
|
| 3236 |
+
},
|
| 3237 |
+
"node_modules/cytoscape-fcose/node_modules/cose-base": {
|
| 3238 |
+
"version": "2.2.0",
|
| 3239 |
+
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",
|
| 3240 |
+
"integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
|
| 3241 |
+
"license": "MIT",
|
| 3242 |
+
"dependencies": {
|
| 3243 |
+
"layout-base": "^2.0.0"
|
| 3244 |
+
}
|
| 3245 |
+
},
|
| 3246 |
+
"node_modules/cytoscape-fcose/node_modules/layout-base": {
|
| 3247 |
+
"version": "2.0.1",
|
| 3248 |
+
"resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",
|
| 3249 |
+
"integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",
|
| 3250 |
+
"license": "MIT"
|
| 3251 |
+
},
|
| 3252 |
+
"node_modules/d3": {
|
| 3253 |
+
"version": "7.9.0",
|
| 3254 |
+
"resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
|
| 3255 |
+
"integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
|
| 3256 |
+
"license": "ISC",
|
| 3257 |
+
"dependencies": {
|
| 3258 |
+
"d3-array": "3",
|
| 3259 |
+
"d3-axis": "3",
|
| 3260 |
+
"d3-brush": "3",
|
| 3261 |
+
"d3-chord": "3",
|
| 3262 |
+
"d3-color": "3",
|
| 3263 |
+
"d3-contour": "4",
|
| 3264 |
+
"d3-delaunay": "6",
|
| 3265 |
+
"d3-dispatch": "3",
|
| 3266 |
+
"d3-drag": "3",
|
| 3267 |
+
"d3-dsv": "3",
|
| 3268 |
+
"d3-ease": "3",
|
| 3269 |
+
"d3-fetch": "3",
|
| 3270 |
+
"d3-force": "3",
|
| 3271 |
+
"d3-format": "3",
|
| 3272 |
+
"d3-geo": "3",
|
| 3273 |
+
"d3-hierarchy": "3",
|
| 3274 |
+
"d3-interpolate": "3",
|
| 3275 |
+
"d3-path": "3",
|
| 3276 |
+
"d3-polygon": "3",
|
| 3277 |
+
"d3-quadtree": "3",
|
| 3278 |
+
"d3-random": "3",
|
| 3279 |
+
"d3-scale": "4",
|
| 3280 |
+
"d3-scale-chromatic": "3",
|
| 3281 |
+
"d3-selection": "3",
|
| 3282 |
+
"d3-shape": "3",
|
| 3283 |
+
"d3-time": "3",
|
| 3284 |
+
"d3-time-format": "4",
|
| 3285 |
+
"d3-timer": "3",
|
| 3286 |
+
"d3-transition": "3",
|
| 3287 |
+
"d3-zoom": "3"
|
| 3288 |
+
},
|
| 3289 |
+
"engines": {
|
| 3290 |
+
"node": ">=12"
|
| 3291 |
+
}
|
| 3292 |
+
},
|
| 3293 |
+
"node_modules/d3-array": {
|
| 3294 |
+
"version": "3.2.4",
|
| 3295 |
+
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
| 3296 |
+
"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
|
| 3297 |
+
"license": "ISC",
|
| 3298 |
+
"dependencies": {
|
| 3299 |
+
"internmap": "1 - 2"
|
| 3300 |
+
},
|
| 3301 |
+
"engines": {
|
| 3302 |
+
"node": ">=12"
|
| 3303 |
+
}
|
| 3304 |
+
},
|
| 3305 |
+
"node_modules/d3-axis": {
|
| 3306 |
+
"version": "3.0.0",
|
| 3307 |
+
"resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
|
| 3308 |
+
"integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
|
| 3309 |
+
"license": "ISC",
|
| 3310 |
+
"engines": {
|
| 3311 |
+
"node": ">=12"
|
| 3312 |
+
}
|
| 3313 |
+
},
|
| 3314 |
+
"node_modules/d3-brush": {
|
| 3315 |
+
"version": "3.0.0",
|
| 3316 |
+
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
|
| 3317 |
+
"integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
|
| 3318 |
+
"license": "ISC",
|
| 3319 |
+
"dependencies": {
|
| 3320 |
+
"d3-dispatch": "1 - 3",
|
| 3321 |
+
"d3-drag": "2 - 3",
|
| 3322 |
+
"d3-interpolate": "1 - 3",
|
| 3323 |
+
"d3-selection": "3",
|
| 3324 |
+
"d3-transition": "3"
|
| 3325 |
+
},
|
| 3326 |
+
"engines": {
|
| 3327 |
+
"node": ">=12"
|
| 3328 |
+
}
|
| 3329 |
+
},
|
| 3330 |
+
"node_modules/d3-chord": {
|
| 3331 |
+
"version": "3.0.1",
|
| 3332 |
+
"resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
|
| 3333 |
+
"integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
|
| 3334 |
+
"license": "ISC",
|
| 3335 |
+
"dependencies": {
|
| 3336 |
+
"d3-path": "1 - 3"
|
| 3337 |
+
},
|
| 3338 |
+
"engines": {
|
| 3339 |
+
"node": ">=12"
|
| 3340 |
+
}
|
| 3341 |
+
},
|
| 3342 |
+
"node_modules/d3-color": {
|
| 3343 |
+
"version": "3.1.0",
|
| 3344 |
+
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
| 3345 |
+
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
|
| 3346 |
+
"license": "ISC",
|
| 3347 |
+
"engines": {
|
| 3348 |
+
"node": ">=12"
|
| 3349 |
+
}
|
| 3350 |
+
},
|
| 3351 |
+
"node_modules/d3-contour": {
|
| 3352 |
+
"version": "4.0.2",
|
| 3353 |
+
"resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
|
| 3354 |
+
"integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
|
| 3355 |
+
"license": "ISC",
|
| 3356 |
+
"dependencies": {
|
| 3357 |
+
"d3-array": "^3.2.0"
|
| 3358 |
+
},
|
| 3359 |
+
"engines": {
|
| 3360 |
+
"node": ">=12"
|
| 3361 |
+
}
|
| 3362 |
+
},
|
| 3363 |
+
"node_modules/d3-delaunay": {
|
| 3364 |
+
"version": "6.0.4",
|
| 3365 |
+
"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
|
| 3366 |
+
"integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
|
| 3367 |
+
"license": "ISC",
|
| 3368 |
+
"dependencies": {
|
| 3369 |
+
"delaunator": "5"
|
| 3370 |
+
},
|
| 3371 |
+
"engines": {
|
| 3372 |
+
"node": ">=12"
|
| 3373 |
+
}
|
| 3374 |
+
},
|
| 3375 |
+
"node_modules/d3-dispatch": {
|
| 3376 |
+
"version": "3.0.1",
|
| 3377 |
+
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
|
| 3378 |
+
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
|
| 3379 |
+
"license": "ISC",
|
| 3380 |
+
"engines": {
|
| 3381 |
+
"node": ">=12"
|
| 3382 |
+
}
|
| 3383 |
+
},
|
| 3384 |
+
"node_modules/d3-drag": {
|
| 3385 |
+
"version": "3.0.0",
|
| 3386 |
+
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
|
| 3387 |
+
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
|
| 3388 |
+
"license": "ISC",
|
| 3389 |
+
"dependencies": {
|
| 3390 |
+
"d3-dispatch": "1 - 3",
|
| 3391 |
+
"d3-selection": "3"
|
| 3392 |
+
},
|
| 3393 |
+
"engines": {
|
| 3394 |
+
"node": ">=12"
|
| 3395 |
+
}
|
| 3396 |
+
},
|
| 3397 |
+
"node_modules/d3-dsv": {
|
| 3398 |
+
"version": "3.0.1",
|
| 3399 |
+
"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
|
| 3400 |
+
"integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
|
| 3401 |
+
"license": "ISC",
|
| 3402 |
+
"dependencies": {
|
| 3403 |
+
"commander": "7",
|
| 3404 |
+
"iconv-lite": "0.6",
|
| 3405 |
+
"rw": "1"
|
| 3406 |
+
},
|
| 3407 |
+
"bin": {
|
| 3408 |
+
"csv2json": "bin/dsv2json.js",
|
| 3409 |
+
"csv2tsv": "bin/dsv2dsv.js",
|
| 3410 |
+
"dsv2dsv": "bin/dsv2dsv.js",
|
| 3411 |
+
"dsv2json": "bin/dsv2json.js",
|
| 3412 |
+
"json2csv": "bin/json2dsv.js",
|
| 3413 |
+
"json2dsv": "bin/json2dsv.js",
|
| 3414 |
+
"json2tsv": "bin/json2dsv.js",
|
| 3415 |
+
"tsv2csv": "bin/dsv2dsv.js",
|
| 3416 |
+
"tsv2json": "bin/dsv2json.js"
|
| 3417 |
+
},
|
| 3418 |
+
"engines": {
|
| 3419 |
+
"node": ">=12"
|
| 3420 |
+
}
|
| 3421 |
+
},
|
| 3422 |
+
"node_modules/d3-dsv/node_modules/commander": {
|
| 3423 |
+
"version": "7.2.0",
|
| 3424 |
+
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
| 3425 |
+
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
| 3426 |
+
"license": "MIT",
|
| 3427 |
+
"engines": {
|
| 3428 |
+
"node": ">= 10"
|
| 3429 |
+
}
|
| 3430 |
+
},
|
| 3431 |
+
"node_modules/d3-ease": {
|
| 3432 |
+
"version": "3.0.1",
|
| 3433 |
+
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
| 3434 |
+
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
|
| 3435 |
+
"license": "BSD-3-Clause",
|
| 3436 |
+
"engines": {
|
| 3437 |
+
"node": ">=12"
|
| 3438 |
+
}
|
| 3439 |
+
},
|
| 3440 |
+
"node_modules/d3-fetch": {
|
| 3441 |
+
"version": "3.0.1",
|
| 3442 |
+
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
|
| 3443 |
+
"integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
|
| 3444 |
+
"license": "ISC",
|
| 3445 |
+
"dependencies": {
|
| 3446 |
+
"d3-dsv": "1 - 3"
|
| 3447 |
+
},
|
| 3448 |
+
"engines": {
|
| 3449 |
+
"node": ">=12"
|
| 3450 |
+
}
|
| 3451 |
+
},
|
| 3452 |
+
"node_modules/d3-force": {
|
| 3453 |
+
"version": "3.0.0",
|
| 3454 |
+
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
| 3455 |
+
"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
|
| 3456 |
+
"license": "ISC",
|
| 3457 |
+
"dependencies": {
|
| 3458 |
+
"d3-dispatch": "1 - 3",
|
| 3459 |
+
"d3-quadtree": "1 - 3",
|
| 3460 |
+
"d3-timer": "1 - 3"
|
| 3461 |
+
},
|
| 3462 |
+
"engines": {
|
| 3463 |
+
"node": ">=12"
|
| 3464 |
+
}
|
| 3465 |
+
},
|
| 3466 |
+
"node_modules/d3-format": {
|
| 3467 |
+
"version": "3.1.2",
|
| 3468 |
+
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
|
| 3469 |
+
"integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",
|
| 3470 |
+
"license": "ISC",
|
| 3471 |
+
"engines": {
|
| 3472 |
+
"node": ">=12"
|
| 3473 |
+
}
|
| 3474 |
+
},
|
| 3475 |
+
"node_modules/d3-geo": {
|
| 3476 |
+
"version": "3.1.1",
|
| 3477 |
+
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
|
| 3478 |
+
"integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
|
| 3479 |
+
"license": "ISC",
|
| 3480 |
+
"dependencies": {
|
| 3481 |
+
"d3-array": "2.5.0 - 3"
|
| 3482 |
+
},
|
| 3483 |
+
"engines": {
|
| 3484 |
+
"node": ">=12"
|
| 3485 |
+
}
|
| 3486 |
+
},
|
| 3487 |
+
"node_modules/d3-hierarchy": {
|
| 3488 |
+
"version": "3.1.2",
|
| 3489 |
+
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
|
| 3490 |
+
"integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
|
| 3491 |
+
"license": "ISC",
|
| 3492 |
+
"engines": {
|
| 3493 |
+
"node": ">=12"
|
| 3494 |
+
}
|
| 3495 |
+
},
|
| 3496 |
+
"node_modules/d3-interpolate": {
|
| 3497 |
+
"version": "3.0.1",
|
| 3498 |
+
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
| 3499 |
+
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
| 3500 |
+
"license": "ISC",
|
| 3501 |
+
"dependencies": {
|
| 3502 |
+
"d3-color": "1 - 3"
|
| 3503 |
+
},
|
| 3504 |
+
"engines": {
|
| 3505 |
+
"node": ">=12"
|
| 3506 |
+
}
|
| 3507 |
+
},
|
| 3508 |
+
"node_modules/d3-path": {
|
| 3509 |
+
"version": "3.1.0",
|
| 3510 |
+
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
|
| 3511 |
+
"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
|
| 3512 |
+
"license": "ISC",
|
| 3513 |
+
"engines": {
|
| 3514 |
+
"node": ">=12"
|
| 3515 |
+
}
|
| 3516 |
+
},
|
| 3517 |
+
"node_modules/d3-polygon": {
|
| 3518 |
+
"version": "3.0.1",
|
| 3519 |
+
"resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
|
| 3520 |
+
"integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
|
| 3521 |
+
"license": "ISC",
|
| 3522 |
+
"engines": {
|
| 3523 |
+
"node": ">=12"
|
| 3524 |
+
}
|
| 3525 |
+
},
|
| 3526 |
+
"node_modules/d3-quadtree": {
|
| 3527 |
+
"version": "3.0.1",
|
| 3528 |
+
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
|
| 3529 |
+
"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
|
| 3530 |
+
"license": "ISC",
|
| 3531 |
+
"engines": {
|
| 3532 |
+
"node": ">=12"
|
| 3533 |
+
}
|
| 3534 |
+
},
|
| 3535 |
+
"node_modules/d3-random": {
|
| 3536 |
+
"version": "3.0.1",
|
| 3537 |
+
"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
|
| 3538 |
+
"integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
|
| 3539 |
+
"license": "ISC",
|
| 3540 |
+
"engines": {
|
| 3541 |
+
"node": ">=12"
|
| 3542 |
+
}
|
| 3543 |
+
},
|
| 3544 |
+
"node_modules/d3-sankey": {
|
| 3545 |
+
"version": "0.12.3",
|
| 3546 |
+
"resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz",
|
| 3547 |
+
"integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",
|
| 3548 |
+
"license": "BSD-3-Clause",
|
| 3549 |
+
"dependencies": {
|
| 3550 |
+
"d3-array": "1 - 2",
|
| 3551 |
+
"d3-shape": "^1.2.0"
|
| 3552 |
+
}
|
| 3553 |
+
},
|
| 3554 |
+
"node_modules/d3-sankey/node_modules/d3-array": {
|
| 3555 |
+
"version": "2.12.1",
|
| 3556 |
+
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
|
| 3557 |
+
"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
|
| 3558 |
+
"license": "BSD-3-Clause",
|
| 3559 |
+
"dependencies": {
|
| 3560 |
+
"internmap": "^1.0.0"
|
| 3561 |
+
}
|
| 3562 |
+
},
|
| 3563 |
+
"node_modules/d3-sankey/node_modules/d3-path": {
|
| 3564 |
+
"version": "1.0.9",
|
| 3565 |
+
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
|
| 3566 |
+
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==",
|
| 3567 |
+
"license": "BSD-3-Clause"
|
| 3568 |
+
},
|
| 3569 |
+
"node_modules/d3-sankey/node_modules/d3-shape": {
|
| 3570 |
+
"version": "1.3.7",
|
| 3571 |
+
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
|
| 3572 |
+
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
|
| 3573 |
+
"license": "BSD-3-Clause",
|
| 3574 |
+
"dependencies": {
|
| 3575 |
+
"d3-path": "1"
|
| 3576 |
+
}
|
| 3577 |
+
},
|
| 3578 |
+
"node_modules/d3-sankey/node_modules/internmap": {
|
| 3579 |
+
"version": "1.0.1",
|
| 3580 |
+
"resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
|
| 3581 |
+
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
|
| 3582 |
+
"license": "ISC"
|
| 3583 |
+
},
|
| 3584 |
+
"node_modules/d3-scale": {
|
| 3585 |
+
"version": "4.0.2",
|
| 3586 |
+
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
| 3587 |
+
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
|
| 3588 |
+
"license": "ISC",
|
| 3589 |
+
"dependencies": {
|
| 3590 |
+
"d3-array": "2.10.0 - 3",
|
| 3591 |
+
"d3-format": "1 - 3",
|
| 3592 |
+
"d3-interpolate": "1.2.0 - 3",
|
| 3593 |
+
"d3-time": "2.1.1 - 3",
|
| 3594 |
+
"d3-time-format": "2 - 4"
|
| 3595 |
+
},
|
| 3596 |
+
"engines": {
|
| 3597 |
+
"node": ">=12"
|
| 3598 |
+
}
|
| 3599 |
+
},
|
| 3600 |
+
"node_modules/d3-scale-chromatic": {
|
| 3601 |
+
"version": "3.1.0",
|
| 3602 |
+
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
|
| 3603 |
+
"integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
|
| 3604 |
+
"license": "ISC",
|
| 3605 |
+
"dependencies": {
|
| 3606 |
+
"d3-color": "1 - 3",
|
| 3607 |
+
"d3-interpolate": "1 - 3"
|
| 3608 |
+
},
|
| 3609 |
+
"engines": {
|
| 3610 |
+
"node": ">=12"
|
| 3611 |
+
}
|
| 3612 |
+
},
|
| 3613 |
+
"node_modules/d3-selection": {
|
| 3614 |
+
"version": "3.0.0",
|
| 3615 |
+
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
| 3616 |
+
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
| 3617 |
+
"license": "ISC",
|
| 3618 |
+
"peer": true,
|
| 3619 |
+
"engines": {
|
| 3620 |
+
"node": ">=12"
|
| 3621 |
+
}
|
| 3622 |
+
},
|
| 3623 |
+
"node_modules/d3-shape": {
|
| 3624 |
+
"version": "3.2.0",
|
| 3625 |
+
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
| 3626 |
+
"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
|
| 3627 |
+
"license": "ISC",
|
| 3628 |
+
"dependencies": {
|
| 3629 |
+
"d3-path": "^3.1.0"
|
| 3630 |
+
},
|
| 3631 |
+
"engines": {
|
| 3632 |
+
"node": ">=12"
|
| 3633 |
+
}
|
| 3634 |
+
},
|
| 3635 |
+
"node_modules/d3-time": {
|
| 3636 |
+
"version": "3.1.0",
|
| 3637 |
+
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
|
| 3638 |
+
"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
|
| 3639 |
+
"license": "ISC",
|
| 3640 |
+
"dependencies": {
|
| 3641 |
+
"d3-array": "2 - 3"
|
| 3642 |
+
},
|
| 3643 |
+
"engines": {
|
| 3644 |
+
"node": ">=12"
|
| 3645 |
+
}
|
| 3646 |
+
},
|
| 3647 |
+
"node_modules/d3-time-format": {
|
| 3648 |
+
"version": "4.1.0",
|
| 3649 |
+
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
|
| 3650 |
+
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
|
| 3651 |
+
"license": "ISC",
|
| 3652 |
+
"dependencies": {
|
| 3653 |
+
"d3-time": "1 - 3"
|
| 3654 |
+
},
|
| 3655 |
+
"engines": {
|
| 3656 |
+
"node": ">=12"
|
| 3657 |
+
}
|
| 3658 |
+
},
|
| 3659 |
+
"node_modules/d3-timer": {
|
| 3660 |
+
"version": "3.0.1",
|
| 3661 |
+
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
| 3662 |
+
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
| 3663 |
+
"license": "ISC",
|
| 3664 |
+
"engines": {
|
| 3665 |
+
"node": ">=12"
|
| 3666 |
+
}
|
| 3667 |
+
},
|
| 3668 |
+
"node_modules/d3-transition": {
|
| 3669 |
+
"version": "3.0.1",
|
| 3670 |
+
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
|
| 3671 |
+
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
|
| 3672 |
+
"license": "ISC",
|
| 3673 |
+
"dependencies": {
|
| 3674 |
+
"d3-color": "1 - 3",
|
| 3675 |
+
"d3-dispatch": "1 - 3",
|
| 3676 |
+
"d3-ease": "1 - 3",
|
| 3677 |
+
"d3-interpolate": "1 - 3",
|
| 3678 |
+
"d3-timer": "1 - 3"
|
| 3679 |
+
},
|
| 3680 |
+
"engines": {
|
| 3681 |
+
"node": ">=12"
|
| 3682 |
+
},
|
| 3683 |
+
"peerDependencies": {
|
| 3684 |
+
"d3-selection": "2 - 3"
|
| 3685 |
+
}
|
| 3686 |
+
},
|
| 3687 |
+
"node_modules/d3-zoom": {
|
| 3688 |
+
"version": "3.0.0",
|
| 3689 |
+
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
|
| 3690 |
+
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
|
| 3691 |
+
"license": "ISC",
|
| 3692 |
+
"dependencies": {
|
| 3693 |
+
"d3-dispatch": "1 - 3",
|
| 3694 |
+
"d3-drag": "2 - 3",
|
| 3695 |
+
"d3-interpolate": "1 - 3",
|
| 3696 |
+
"d3-selection": "2 - 3",
|
| 3697 |
+
"d3-transition": "2 - 3"
|
| 3698 |
+
},
|
| 3699 |
+
"engines": {
|
| 3700 |
+
"node": ">=12"
|
| 3701 |
+
}
|
| 3702 |
+
},
|
| 3703 |
+
"node_modules/dagre-d3-es": {
|
| 3704 |
+
"version": "7.0.14",
|
| 3705 |
+
"resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz",
|
| 3706 |
+
"integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==",
|
| 3707 |
+
"license": "MIT",
|
| 3708 |
+
"dependencies": {
|
| 3709 |
+
"d3": "^7.9.0",
|
| 3710 |
+
"lodash-es": "^4.17.21"
|
| 3711 |
+
}
|
| 3712 |
+
},
|
| 3713 |
+
"node_modules/dayjs": {
|
| 3714 |
+
"version": "1.11.20",
|
| 3715 |
+
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz",
|
| 3716 |
+
"integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
|
| 3717 |
+
"license": "MIT"
|
| 3718 |
+
},
|
| 3719 |
+
"node_modules/debug": {
|
| 3720 |
+
"version": "4.4.3",
|
| 3721 |
+
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
| 3722 |
+
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
| 3723 |
+
"license": "MIT",
|
| 3724 |
+
"dependencies": {
|
| 3725 |
+
"ms": "^2.1.3"
|
| 3726 |
+
},
|
| 3727 |
+
"engines": {
|
| 3728 |
+
"node": ">=6.0"
|
| 3729 |
+
},
|
| 3730 |
+
"peerDependenciesMeta": {
|
| 3731 |
+
"supports-color": {
|
| 3732 |
+
"optional": true
|
| 3733 |
+
}
|
| 3734 |
+
}
|
| 3735 |
+
},
|
| 3736 |
+
"node_modules/delaunator": {
|
| 3737 |
+
"version": "5.1.0",
|
| 3738 |
+
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz",
|
| 3739 |
+
"integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==",
|
| 3740 |
+
"license": "ISC",
|
| 3741 |
+
"dependencies": {
|
| 3742 |
+
"robust-predicates": "^3.0.2"
|
| 3743 |
+
}
|
| 3744 |
+
},
|
| 3745 |
+
"node_modules/dequal": {
|
| 3746 |
+
"version": "2.0.3",
|
| 3747 |
+
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
| 3748 |
+
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
| 3749 |
+
"license": "MIT",
|
| 3750 |
+
"engines": {
|
| 3751 |
+
"node": ">=6"
|
| 3752 |
+
}
|
| 3753 |
+
},
|
| 3754 |
+
"node_modules/devlop": {
|
| 3755 |
+
"version": "1.1.0",
|
| 3756 |
+
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
|
| 3757 |
+
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
|
| 3758 |
+
"license": "MIT",
|
| 3759 |
+
"dependencies": {
|
| 3760 |
+
"dequal": "^2.0.0"
|
| 3761 |
},
|
| 3762 |
"funding": {
|
| 3763 |
"type": "github",
|
|
|
|
| 3774 |
"csstype": "^3.0.2"
|
| 3775 |
}
|
| 3776 |
},
|
| 3777 |
+
"node_modules/dompurify": {
|
| 3778 |
+
"version": "3.3.3",
|
| 3779 |
+
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz",
|
| 3780 |
+
"integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==",
|
| 3781 |
+
"license": "(MPL-2.0 OR Apache-2.0)",
|
| 3782 |
+
"optionalDependencies": {
|
| 3783 |
+
"@types/trusted-types": "^2.0.7"
|
| 3784 |
+
}
|
| 3785 |
+
},
|
| 3786 |
"node_modules/electron-to-chromium": {
|
| 3787 |
"version": "1.5.335",
|
| 3788 |
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.335.tgz",
|
|
|
|
| 3960 |
"node": ">=6.9.0"
|
| 3961 |
}
|
| 3962 |
},
|
| 3963 |
+
"node_modules/hachure-fill": {
|
| 3964 |
+
"version": "0.5.2",
|
| 3965 |
+
"resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz",
|
| 3966 |
+
"integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==",
|
| 3967 |
+
"license": "MIT"
|
| 3968 |
+
},
|
| 3969 |
"node_modules/hasown": {
|
| 3970 |
"version": "2.0.2",
|
| 3971 |
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
|
|
|
| 4003 |
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
| 4004 |
"license": "MIT"
|
| 4005 |
},
|
| 4006 |
+
"node_modules/iconv-lite": {
|
| 4007 |
+
"version": "0.6.3",
|
| 4008 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
| 4009 |
+
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
| 4010 |
+
"license": "MIT",
|
| 4011 |
+
"dependencies": {
|
| 4012 |
+
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
| 4013 |
+
},
|
| 4014 |
+
"engines": {
|
| 4015 |
+
"node": ">=0.10.0"
|
| 4016 |
+
}
|
| 4017 |
+
},
|
| 4018 |
"node_modules/import-fresh": {
|
| 4019 |
"version": "3.3.1",
|
| 4020 |
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
|
|
|
| 4031 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 4032 |
}
|
| 4033 |
},
|
| 4034 |
+
"node_modules/internmap": {
|
| 4035 |
+
"version": "2.0.3",
|
| 4036 |
+
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
|
| 4037 |
+
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
|
| 4038 |
+
"license": "ISC",
|
| 4039 |
+
"engines": {
|
| 4040 |
+
"node": ">=12"
|
| 4041 |
+
}
|
| 4042 |
+
},
|
| 4043 |
"node_modules/is-arrayish": {
|
| 4044 |
"version": "0.2.1",
|
| 4045 |
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
|
|
|
| 4131 |
"katex": "cli.js"
|
| 4132 |
}
|
| 4133 |
},
|
| 4134 |
+
"node_modules/khroma": {
|
| 4135 |
+
"version": "2.1.0",
|
| 4136 |
+
"resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz",
|
| 4137 |
+
"integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="
|
| 4138 |
+
},
|
| 4139 |
+
"node_modules/langium": {
|
| 4140 |
+
"version": "4.2.2",
|
| 4141 |
+
"resolved": "https://registry.npmjs.org/langium/-/langium-4.2.2.tgz",
|
| 4142 |
+
"integrity": "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==",
|
| 4143 |
+
"license": "MIT",
|
| 4144 |
+
"dependencies": {
|
| 4145 |
+
"@chevrotain/regexp-to-ast": "~12.0.0",
|
| 4146 |
+
"chevrotain": "~12.0.0",
|
| 4147 |
+
"chevrotain-allstar": "~0.4.1",
|
| 4148 |
+
"vscode-languageserver": "~9.0.1",
|
| 4149 |
+
"vscode-languageserver-textdocument": "~1.0.11",
|
| 4150 |
+
"vscode-uri": "~3.1.0"
|
| 4151 |
+
},
|
| 4152 |
+
"engines": {
|
| 4153 |
+
"node": ">=20.10.0",
|
| 4154 |
+
"npm": ">=10.2.3"
|
| 4155 |
+
}
|
| 4156 |
+
},
|
| 4157 |
+
"node_modules/layout-base": {
|
| 4158 |
+
"version": "1.0.2",
|
| 4159 |
+
"resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz",
|
| 4160 |
+
"integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==",
|
| 4161 |
+
"license": "MIT"
|
| 4162 |
+
},
|
| 4163 |
"node_modules/lib0": {
|
| 4164 |
"version": "0.2.117",
|
| 4165 |
"resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.117.tgz",
|
|
|
|
| 4202 |
"integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==",
|
| 4203 |
"license": "MIT"
|
| 4204 |
},
|
| 4205 |
+
"node_modules/lodash-es": {
|
| 4206 |
+
"version": "4.18.1",
|
| 4207 |
+
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
|
| 4208 |
+
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
|
| 4209 |
+
"license": "MIT"
|
| 4210 |
+
},
|
| 4211 |
"node_modules/loose-envify": {
|
| 4212 |
"version": "1.4.0",
|
| 4213 |
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
|
|
| 4263 |
"markdown-it": "bin/markdown-it.mjs"
|
| 4264 |
}
|
| 4265 |
},
|
| 4266 |
+
"node_modules/marked": {
|
| 4267 |
+
"version": "16.4.2",
|
| 4268 |
+
"resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz",
|
| 4269 |
+
"integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==",
|
| 4270 |
+
"license": "MIT",
|
| 4271 |
+
"bin": {
|
| 4272 |
+
"marked": "bin/marked.js"
|
| 4273 |
+
},
|
| 4274 |
+
"engines": {
|
| 4275 |
+
"node": ">= 20"
|
| 4276 |
+
}
|
| 4277 |
+
},
|
| 4278 |
"node_modules/mdurl": {
|
| 4279 |
"version": "2.0.0",
|
| 4280 |
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
| 4281 |
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
| 4282 |
"license": "MIT"
|
| 4283 |
},
|
| 4284 |
+
"node_modules/mermaid": {
|
| 4285 |
+
"version": "11.14.0",
|
| 4286 |
+
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.14.0.tgz",
|
| 4287 |
+
"integrity": "sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g==",
|
| 4288 |
+
"license": "MIT",
|
| 4289 |
+
"dependencies": {
|
| 4290 |
+
"@braintree/sanitize-url": "^7.1.1",
|
| 4291 |
+
"@iconify/utils": "^3.0.2",
|
| 4292 |
+
"@mermaid-js/parser": "^1.1.0",
|
| 4293 |
+
"@types/d3": "^7.4.3",
|
| 4294 |
+
"@upsetjs/venn.js": "^2.0.0",
|
| 4295 |
+
"cytoscape": "^3.33.1",
|
| 4296 |
+
"cytoscape-cose-bilkent": "^4.1.0",
|
| 4297 |
+
"cytoscape-fcose": "^2.2.0",
|
| 4298 |
+
"d3": "^7.9.0",
|
| 4299 |
+
"d3-sankey": "^0.12.3",
|
| 4300 |
+
"dagre-d3-es": "7.0.14",
|
| 4301 |
+
"dayjs": "^1.11.19",
|
| 4302 |
+
"dompurify": "^3.3.1",
|
| 4303 |
+
"katex": "^0.16.25",
|
| 4304 |
+
"khroma": "^2.1.0",
|
| 4305 |
+
"lodash-es": "^4.17.23",
|
| 4306 |
+
"marked": "^16.3.0",
|
| 4307 |
+
"roughjs": "^4.6.6",
|
| 4308 |
+
"stylis": "^4.3.6",
|
| 4309 |
+
"ts-dedent": "^2.2.0",
|
| 4310 |
+
"uuid": "^11.1.0"
|
| 4311 |
+
}
|
| 4312 |
+
},
|
| 4313 |
+
"node_modules/mermaid/node_modules/stylis": {
|
| 4314 |
+
"version": "4.3.6",
|
| 4315 |
+
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
|
| 4316 |
+
"integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
|
| 4317 |
+
"license": "MIT"
|
| 4318 |
+
},
|
| 4319 |
+
"node_modules/mlly": {
|
| 4320 |
+
"version": "1.8.2",
|
| 4321 |
+
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
|
| 4322 |
+
"integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
|
| 4323 |
+
"license": "MIT",
|
| 4324 |
+
"dependencies": {
|
| 4325 |
+
"acorn": "^8.16.0",
|
| 4326 |
+
"pathe": "^2.0.3",
|
| 4327 |
+
"pkg-types": "^1.3.1",
|
| 4328 |
+
"ufo": "^1.6.3"
|
| 4329 |
+
}
|
| 4330 |
+
},
|
| 4331 |
"node_modules/ms": {
|
| 4332 |
"version": "2.1.3",
|
| 4333 |
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
|
|
| 4375 |
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
| 4376 |
"license": "MIT"
|
| 4377 |
},
|
| 4378 |
+
"node_modules/package-manager-detector": {
|
| 4379 |
+
"version": "1.6.0",
|
| 4380 |
+
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
|
| 4381 |
+
"integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
|
| 4382 |
+
"license": "MIT"
|
| 4383 |
+
},
|
| 4384 |
"node_modules/parent-module": {
|
| 4385 |
"version": "1.0.1",
|
| 4386 |
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
|
|
|
| 4411 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 4412 |
}
|
| 4413 |
},
|
| 4414 |
+
"node_modules/path-data-parser": {
|
| 4415 |
+
"version": "0.1.0",
|
| 4416 |
+
"resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz",
|
| 4417 |
+
"integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==",
|
| 4418 |
+
"license": "MIT"
|
| 4419 |
+
},
|
| 4420 |
"node_modules/path-parse": {
|
| 4421 |
"version": "1.0.7",
|
| 4422 |
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
|
|
|
| 4432 |
"node": ">=8"
|
| 4433 |
}
|
| 4434 |
},
|
| 4435 |
+
"node_modules/pathe": {
|
| 4436 |
+
"version": "2.0.3",
|
| 4437 |
+
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
| 4438 |
+
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
| 4439 |
+
"license": "MIT"
|
| 4440 |
+
},
|
| 4441 |
"node_modules/picocolors": {
|
| 4442 |
"version": "1.1.1",
|
| 4443 |
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
|
|
|
| 4458 |
"url": "https://github.com/sponsors/jonschlinkert"
|
| 4459 |
}
|
| 4460 |
},
|
| 4461 |
+
"node_modules/pkg-types": {
|
| 4462 |
+
"version": "1.3.1",
|
| 4463 |
+
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
| 4464 |
+
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
| 4465 |
+
"license": "MIT",
|
| 4466 |
+
"dependencies": {
|
| 4467 |
+
"confbox": "^0.1.8",
|
| 4468 |
+
"mlly": "^1.7.4",
|
| 4469 |
+
"pathe": "^2.0.1"
|
| 4470 |
+
}
|
| 4471 |
+
},
|
| 4472 |
+
"node_modules/points-on-curve": {
|
| 4473 |
+
"version": "0.2.0",
|
| 4474 |
+
"resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz",
|
| 4475 |
+
"integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==",
|
| 4476 |
+
"license": "MIT"
|
| 4477 |
+
},
|
| 4478 |
+
"node_modules/points-on-path": {
|
| 4479 |
+
"version": "0.2.1",
|
| 4480 |
+
"resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz",
|
| 4481 |
+
"integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==",
|
| 4482 |
+
"license": "MIT",
|
| 4483 |
+
"dependencies": {
|
| 4484 |
+
"path-data-parser": "0.1.0",
|
| 4485 |
+
"points-on-curve": "0.2.0"
|
| 4486 |
+
}
|
| 4487 |
+
},
|
| 4488 |
"node_modules/postcss": {
|
| 4489 |
"version": "8.5.9",
|
| 4490 |
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
|
|
|
|
| 4505 |
}
|
| 4506 |
],
|
| 4507 |
"license": "MIT",
|
| 4508 |
+
"peer": true,
|
| 4509 |
"dependencies": {
|
| 4510 |
"nanoid": "^3.3.11",
|
| 4511 |
"picocolors": "^1.1.1",
|
|
|
|
| 4515 |
"node": "^10 || ^12 || >=14"
|
| 4516 |
}
|
| 4517 |
},
|
| 4518 |
+
"node_modules/postcss-custom-media": {
|
| 4519 |
+
"version": "12.0.1",
|
| 4520 |
+
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-12.0.1.tgz",
|
| 4521 |
+
"integrity": "sha512-66syE14+VeqkUf0rRX0bvbTCbNRJF132jD+ceo8th1dap2YJEAqpdh5uG98CE3IbgHT7m9XM0GIlOazNWqQdeA==",
|
| 4522 |
+
"dev": true,
|
| 4523 |
+
"funding": [
|
| 4524 |
+
{
|
| 4525 |
+
"type": "github",
|
| 4526 |
+
"url": "https://github.com/sponsors/csstools"
|
| 4527 |
+
},
|
| 4528 |
+
{
|
| 4529 |
+
"type": "opencollective",
|
| 4530 |
+
"url": "https://opencollective.com/csstools"
|
| 4531 |
+
}
|
| 4532 |
+
],
|
| 4533 |
+
"license": "MIT",
|
| 4534 |
+
"dependencies": {
|
| 4535 |
+
"@csstools/cascade-layer-name-parser": "^3.0.0",
|
| 4536 |
+
"@csstools/css-parser-algorithms": "^4.0.0",
|
| 4537 |
+
"@csstools/css-tokenizer": "^4.0.0",
|
| 4538 |
+
"@csstools/media-query-list-parser": "^5.0.0"
|
| 4539 |
+
},
|
| 4540 |
+
"engines": {
|
| 4541 |
+
"node": ">=20.19.0"
|
| 4542 |
+
},
|
| 4543 |
+
"peerDependencies": {
|
| 4544 |
+
"postcss": "^8.4"
|
| 4545 |
+
}
|
| 4546 |
+
},
|
| 4547 |
"node_modules/prop-types": {
|
| 4548 |
"version": "15.8.1",
|
| 4549 |
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
|
|
|
| 4857 |
"node": ">=4"
|
| 4858 |
}
|
| 4859 |
},
|
| 4860 |
+
"node_modules/robust-predicates": {
|
| 4861 |
+
"version": "3.0.3",
|
| 4862 |
+
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",
|
| 4863 |
+
"integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==",
|
| 4864 |
+
"license": "Unlicense"
|
| 4865 |
+
},
|
| 4866 |
"node_modules/rollup": {
|
| 4867 |
"version": "4.60.1",
|
| 4868 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz",
|
|
|
|
| 4914 |
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
| 4915 |
"license": "MIT"
|
| 4916 |
},
|
| 4917 |
+
"node_modules/roughjs": {
|
| 4918 |
+
"version": "4.6.6",
|
| 4919 |
+
"resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz",
|
| 4920 |
+
"integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==",
|
| 4921 |
+
"license": "MIT",
|
| 4922 |
+
"dependencies": {
|
| 4923 |
+
"hachure-fill": "^0.5.2",
|
| 4924 |
+
"path-data-parser": "^0.1.0",
|
| 4925 |
+
"points-on-curve": "^0.2.0",
|
| 4926 |
+
"points-on-path": "^0.2.1"
|
| 4927 |
+
}
|
| 4928 |
+
},
|
| 4929 |
+
"node_modules/rw": {
|
| 4930 |
+
"version": "1.3.3",
|
| 4931 |
+
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
|
| 4932 |
+
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
|
| 4933 |
+
"license": "BSD-3-Clause"
|
| 4934 |
+
},
|
| 4935 |
+
"node_modules/safer-buffer": {
|
| 4936 |
+
"version": "2.1.2",
|
| 4937 |
+
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
| 4938 |
+
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
| 4939 |
+
"license": "MIT"
|
| 4940 |
+
},
|
| 4941 |
"node_modules/scheduler": {
|
| 4942 |
"version": "0.23.2",
|
| 4943 |
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
|
|
|
| 5019 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 5020 |
}
|
| 5021 |
},
|
| 5022 |
+
"node_modules/tinyexec": {
|
| 5023 |
+
"version": "1.1.1",
|
| 5024 |
+
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz",
|
| 5025 |
+
"integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==",
|
| 5026 |
+
"license": "MIT",
|
| 5027 |
+
"engines": {
|
| 5028 |
+
"node": ">=18"
|
| 5029 |
+
}
|
| 5030 |
+
},
|
| 5031 |
"node_modules/tinyglobby": {
|
| 5032 |
"version": "0.2.16",
|
| 5033 |
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
|
|
|
|
| 5054 |
"@popperjs/core": "^2.9.0"
|
| 5055 |
}
|
| 5056 |
},
|
| 5057 |
+
"node_modules/ts-dedent": {
|
| 5058 |
+
"version": "2.2.0",
|
| 5059 |
+
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
|
| 5060 |
+
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
|
| 5061 |
+
"license": "MIT",
|
| 5062 |
+
"engines": {
|
| 5063 |
+
"node": ">=6.10"
|
| 5064 |
+
}
|
| 5065 |
+
},
|
| 5066 |
"node_modules/uc.micro": {
|
| 5067 |
"version": "2.1.0",
|
| 5068 |
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
| 5069 |
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
| 5070 |
"license": "MIT"
|
| 5071 |
},
|
| 5072 |
+
"node_modules/ufo": {
|
| 5073 |
+
"version": "1.6.3",
|
| 5074 |
+
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
|
| 5075 |
+
"integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==",
|
| 5076 |
+
"license": "MIT"
|
| 5077 |
+
},
|
| 5078 |
"node_modules/update-browserslist-db": {
|
| 5079 |
"version": "1.2.3",
|
| 5080 |
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
|
|
|
| 5115 |
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
| 5116 |
}
|
| 5117 |
},
|
| 5118 |
+
"node_modules/uuid": {
|
| 5119 |
+
"version": "11.1.0",
|
| 5120 |
+
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
| 5121 |
+
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
| 5122 |
+
"funding": [
|
| 5123 |
+
"https://github.com/sponsors/broofa",
|
| 5124 |
+
"https://github.com/sponsors/ctavan"
|
| 5125 |
+
],
|
| 5126 |
+
"license": "MIT",
|
| 5127 |
+
"bin": {
|
| 5128 |
+
"uuid": "dist/esm/bin/uuid"
|
| 5129 |
+
}
|
| 5130 |
+
},
|
| 5131 |
"node_modules/vite": {
|
| 5132 |
"version": "6.4.2",
|
| 5133 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
|
|
|
|
| 5204 |
}
|
| 5205 |
}
|
| 5206 |
},
|
| 5207 |
+
"node_modules/vscode-jsonrpc": {
|
| 5208 |
+
"version": "8.2.0",
|
| 5209 |
+
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
|
| 5210 |
+
"integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
|
| 5211 |
+
"license": "MIT",
|
| 5212 |
+
"engines": {
|
| 5213 |
+
"node": ">=14.0.0"
|
| 5214 |
+
}
|
| 5215 |
+
},
|
| 5216 |
+
"node_modules/vscode-languageserver": {
|
| 5217 |
+
"version": "9.0.1",
|
| 5218 |
+
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz",
|
| 5219 |
+
"integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==",
|
| 5220 |
+
"license": "MIT",
|
| 5221 |
+
"dependencies": {
|
| 5222 |
+
"vscode-languageserver-protocol": "3.17.5"
|
| 5223 |
+
},
|
| 5224 |
+
"bin": {
|
| 5225 |
+
"installServerIntoExtension": "bin/installServerIntoExtension"
|
| 5226 |
+
}
|
| 5227 |
+
},
|
| 5228 |
+
"node_modules/vscode-languageserver-protocol": {
|
| 5229 |
+
"version": "3.17.5",
|
| 5230 |
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
|
| 5231 |
+
"integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
|
| 5232 |
+
"license": "MIT",
|
| 5233 |
+
"dependencies": {
|
| 5234 |
+
"vscode-jsonrpc": "8.2.0",
|
| 5235 |
+
"vscode-languageserver-types": "3.17.5"
|
| 5236 |
+
}
|
| 5237 |
+
},
|
| 5238 |
+
"node_modules/vscode-languageserver-textdocument": {
|
| 5239 |
+
"version": "1.0.12",
|
| 5240 |
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
|
| 5241 |
+
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
|
| 5242 |
+
"license": "MIT"
|
| 5243 |
+
},
|
| 5244 |
+
"node_modules/vscode-languageserver-types": {
|
| 5245 |
+
"version": "3.17.5",
|
| 5246 |
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
|
| 5247 |
+
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
|
| 5248 |
+
"license": "MIT"
|
| 5249 |
+
},
|
| 5250 |
+
"node_modules/vscode-uri": {
|
| 5251 |
+
"version": "3.1.0",
|
| 5252 |
+
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
| 5253 |
+
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
| 5254 |
+
"license": "MIT"
|
| 5255 |
+
},
|
| 5256 |
"node_modules/w3c-keyname": {
|
| 5257 |
"version": "2.2.8",
|
| 5258 |
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
|
@@ -37,6 +37,7 @@
|
|
| 37 |
"ai": "^6.0.158",
|
| 38 |
"katex": "^0.16.45",
|
| 39 |
"lowlight": "^3.2.0",
|
|
|
|
| 40 |
"react": "^18.3.0",
|
| 41 |
"react-dom": "^18.3.0",
|
| 42 |
"tippy.js": "^6.3.7",
|
|
@@ -47,6 +48,7 @@
|
|
| 47 |
"@types/react": "^18.3.0",
|
| 48 |
"@types/react-dom": "^18.3.0",
|
| 49 |
"@vitejs/plugin-react": "^4.3.0",
|
|
|
|
| 50 |
"vite": "^6.0.0"
|
| 51 |
}
|
| 52 |
}
|
|
|
|
| 37 |
"ai": "^6.0.158",
|
| 38 |
"katex": "^0.16.45",
|
| 39 |
"lowlight": "^3.2.0",
|
| 40 |
+
"mermaid": "^11.14.0",
|
| 41 |
"react": "^18.3.0",
|
| 42 |
"react-dom": "^18.3.0",
|
| 43 |
"tippy.js": "^6.3.7",
|
|
|
|
| 48 |
"@types/react": "^18.3.0",
|
| 49 |
"@types/react-dom": "^18.3.0",
|
| 50 |
"@vitejs/plugin-react": "^4.3.0",
|
| 51 |
+
"postcss-custom-media": "^12.0.1",
|
| 52 |
"vite": "^6.0.0"
|
| 53 |
}
|
| 54 |
}
|
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export default {
|
| 2 |
+
plugins: {
|
| 3 |
+
"postcss-custom-media": {},
|
| 4 |
+
},
|
| 5 |
+
};
|
|
@@ -1,7 +1,8 @@
|
|
| 1 |
-
import { useRef, useState, useCallback, useEffect } from "react";
|
| 2 |
import { Editor as TiptapEditor } from "@tiptap/core";
|
| 3 |
import { UndoManager } from "yjs";
|
| 4 |
import type * as Y from "yjs";
|
|
|
|
| 5 |
import {
|
| 6 |
Box,
|
| 7 |
Chip,
|
|
@@ -13,6 +14,8 @@ import UndoIcon from "@mui/icons-material/Undo";
|
|
| 13 |
import RedoIcon from "@mui/icons-material/Redo";
|
| 14 |
import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined";
|
| 15 |
import PublishOutlinedIcon from "@mui/icons-material/PublishOutlined";
|
|
|
|
|
|
|
| 16 |
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutlined";
|
| 17 |
import CloseIcon from "@mui/icons-material/Close";
|
| 18 |
import {
|
|
@@ -74,6 +77,27 @@ export default function App() {
|
|
| 74 |
const [hasSelection, setHasSelection] = useState(false);
|
| 75 |
const [undoManager, setUndoManager] = useState<UndoManager | null>(null);
|
| 76 |
const [chatOpen, setChatOpen] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
const agentChat = useAgentChat({ editor: editorInstance, undoManager, frontmatterStore });
|
| 79 |
|
|
@@ -168,7 +192,9 @@ export default function App() {
|
|
| 168 |
}, [commentStore, user]);
|
| 169 |
|
| 170 |
return (
|
|
|
|
| 171 |
<Box
|
|
|
|
| 172 |
sx={{
|
| 173 |
height: "100vh",
|
| 174 |
display: "flex",
|
|
@@ -238,36 +264,25 @@ export default function App() {
|
|
| 238 |
</Box>
|
| 239 |
|
| 240 |
{/* Single scroll container */}
|
| 241 |
-
<
|
| 242 |
ref={editorContainerCallback}
|
| 243 |
-
|
| 244 |
-
flex: 1,
|
| 245 |
-
overflowY: "auto",
|
| 246 |
-
overflowX: "hidden",
|
| 247 |
-
}}
|
| 248 |
>
|
| 249 |
-
<
|
| 250 |
-
sx={{
|
| 251 |
-
display: "grid",
|
| 252 |
-
gridTemplateColumns: "200px 1fr 240px",
|
| 253 |
-
gridTemplateRows: "auto 1fr",
|
| 254 |
-
minHeight: "100%",
|
| 255 |
-
}}
|
| 256 |
-
>
|
| 257 |
{/* Hero - center column only, row 1 */}
|
| 258 |
-
<
|
| 259 |
<FrontmatterHero store={frontmatterStore} />
|
| 260 |
-
</
|
| 261 |
|
| 262 |
{/* TOC - left column, row 2, sticky */}
|
| 263 |
-
<
|
| 264 |
-
<
|
| 265 |
<TableOfContents editor={editorInstance} />
|
| 266 |
-
</
|
| 267 |
-
</
|
| 268 |
|
| 269 |
{/* Editor - center column, row 2 */}
|
| 270 |
-
<
|
| 271 |
<Editor
|
| 272 |
docName={docName}
|
| 273 |
user={user}
|
|
@@ -279,19 +294,19 @@ export default function App() {
|
|
| 279 |
onUndoManagerReady={setUndoManager}
|
| 280 |
onAddComment={handleAddComment}
|
| 281 |
/>
|
| 282 |
-
</
|
| 283 |
|
| 284 |
{/* Comments - right column, row 2 */}
|
| 285 |
-
<
|
| 286 |
<CommentsSidebar
|
| 287 |
editor={editorInstance}
|
| 288 |
commentStore={commentStore}
|
| 289 |
user={user}
|
| 290 |
editorContainer={containerEl}
|
| 291 |
/>
|
| 292 |
-
</
|
| 293 |
-
</
|
| 294 |
-
</
|
| 295 |
|
| 296 |
{/* Floating chat - bottom left */}
|
| 297 |
{chatOpen ? (
|
|
@@ -442,5 +457,6 @@ export default function App() {
|
|
| 442 |
</DialogActions>
|
| 443 |
</Dialog>
|
| 444 |
</Box>
|
|
|
|
| 445 |
);
|
| 446 |
}
|
|
|
|
| 1 |
+
import { useRef, useState, useCallback, useEffect, useMemo } from "react";
|
| 2 |
import { Editor as TiptapEditor } from "@tiptap/core";
|
| 3 |
import { UndoManager } from "yjs";
|
| 4 |
import type * as Y from "yjs";
|
| 5 |
+
import { ThemeProvider } from "@mui/material/styles";
|
| 6 |
import {
|
| 7 |
Box,
|
| 8 |
Chip,
|
|
|
|
| 14 |
import RedoIcon from "@mui/icons-material/Redo";
|
| 15 |
import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined";
|
| 16 |
import PublishOutlinedIcon from "@mui/icons-material/PublishOutlined";
|
| 17 |
+
import { buildTheme, DEFAULT_PRIMARY, DEFAULT_HUE } from "./theme";
|
| 18 |
+
import { oklchToHex, OKLCH_L, OKLCH_C } from "./editor/frontmatter/HueSlider";
|
| 19 |
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutlined";
|
| 20 |
import CloseIcon from "@mui/icons-material/Close";
|
| 21 |
import {
|
|
|
|
| 77 |
const [hasSelection, setHasSelection] = useState(false);
|
| 78 |
const [undoManager, setUndoManager] = useState<UndoManager | null>(null);
|
| 79 |
const [chatOpen, setChatOpen] = useState(false);
|
| 80 |
+
const [primaryHue, setPrimaryHue] = useState(DEFAULT_HUE);
|
| 81 |
+
|
| 82 |
+
const primaryHex = useMemo(() => oklchToHex(OKLCH_L, OKLCH_C, primaryHue), [primaryHue]);
|
| 83 |
+
const muiTheme = useMemo(() => buildTheme(primaryHex), [primaryHex]);
|
| 84 |
+
|
| 85 |
+
// Sync primary hue from Yjs settings + push to CSS variables
|
| 86 |
+
useEffect(() => {
|
| 87 |
+
if (!settingsMap) return;
|
| 88 |
+
const sync = () => {
|
| 89 |
+
const h = settingsMap.get("primaryHue") as number | undefined;
|
| 90 |
+
if (h !== undefined) {
|
| 91 |
+
setPrimaryHue(h);
|
| 92 |
+
const oklch = `oklch(${OKLCH_L} ${OKLCH_C} ${h})`;
|
| 93 |
+
document.documentElement.style.setProperty("--primary-color", oklch);
|
| 94 |
+
document.documentElement.style.setProperty("--primary-color-hover", oklch);
|
| 95 |
+
}
|
| 96 |
+
};
|
| 97 |
+
sync();
|
| 98 |
+
settingsMap.observe(sync);
|
| 99 |
+
return () => settingsMap.unobserve(sync);
|
| 100 |
+
}, [settingsMap]);
|
| 101 |
|
| 102 |
const agentChat = useAgentChat({ editor: editorInstance, undoManager, frontmatterStore });
|
| 103 |
|
|
|
|
| 192 |
}, [commentStore, user]);
|
| 193 |
|
| 194 |
return (
|
| 195 |
+
<ThemeProvider theme={muiTheme}>
|
| 196 |
<Box
|
| 197 |
+
className="editor-app"
|
| 198 |
sx={{
|
| 199 |
height: "100vh",
|
| 200 |
display: "flex",
|
|
|
|
| 264 |
</Box>
|
| 265 |
|
| 266 |
{/* Single scroll container */}
|
| 267 |
+
<div
|
| 268 |
ref={editorContainerCallback}
|
| 269 |
+
style={{ flex: 1, overflowY: "auto", overflowX: "hidden" }}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
>
|
| 271 |
+
<div className="content-grid">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
{/* Hero - center column only, row 1 */}
|
| 273 |
+
<div className="content-grid__hero">
|
| 274 |
<FrontmatterHero store={frontmatterStore} />
|
| 275 |
+
</div>
|
| 276 |
|
| 277 |
{/* TOC - left column, row 2, sticky */}
|
| 278 |
+
<div className="content-grid__toc">
|
| 279 |
+
<div className="table-of-contents--sticky">
|
| 280 |
<TableOfContents editor={editorInstance} />
|
| 281 |
+
</div>
|
| 282 |
+
</div>
|
| 283 |
|
| 284 |
{/* Editor - center column, row 2 */}
|
| 285 |
+
<div className="content-grid__editor">
|
| 286 |
<Editor
|
| 287 |
docName={docName}
|
| 288 |
user={user}
|
|
|
|
| 294 |
onUndoManagerReady={setUndoManager}
|
| 295 |
onAddComment={handleAddComment}
|
| 296 |
/>
|
| 297 |
+
</div>
|
| 298 |
|
| 299 |
{/* Comments - right column, row 2 */}
|
| 300 |
+
<div className="content-grid__comments">
|
| 301 |
<CommentsSidebar
|
| 302 |
editor={editorInstance}
|
| 303 |
commentStore={commentStore}
|
| 304 |
user={user}
|
| 305 |
editorContainer={containerEl}
|
| 306 |
/>
|
| 307 |
+
</div>
|
| 308 |
+
</div>
|
| 309 |
+
</div>
|
| 310 |
|
| 311 |
{/* Floating chat - bottom left */}
|
| 312 |
{chatOpen ? (
|
|
|
|
| 457 |
</DialogActions>
|
| 458 |
</Dialog>
|
| 459 |
</Box>
|
| 460 |
+
</ThemeProvider>
|
| 461 |
);
|
| 462 |
}
|
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
| 2 |
-
import { Box, Typography } from "@mui/material";
|
| 3 |
import type { Editor } from "@tiptap/core";
|
| 4 |
|
| 5 |
const SCROLL_OFFSET_PX = 80;
|
|
@@ -133,103 +132,53 @@ export function TableOfContents({ editor }: TableOfContentsProps) {
|
|
| 133 |
|
| 134 |
if (!editor || headings.length === 0) {
|
| 135 |
return (
|
| 136 |
-
<
|
| 137 |
-
<
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
<Typography variant="caption" sx={{ color: "text.disabled", display: "block", mt: 1, fontSize: "0.7rem" }}>
|
| 141 |
-
Headings will appear here as you write.
|
| 142 |
-
</Typography>
|
| 143 |
-
</Box>
|
| 144 |
);
|
| 145 |
}
|
| 146 |
|
| 147 |
const renderList = (nodes: TocNode[], isRoot: boolean) => (
|
| 148 |
-
<
|
| 149 |
-
component="ul"
|
| 150 |
-
sx={{
|
| 151 |
-
m: 0,
|
| 152 |
-
mb: isRoot ? 0 : "6px",
|
| 153 |
-
pl: isRoot ? 0 : "1em",
|
| 154 |
-
listStyle: "none",
|
| 155 |
-
}}
|
| 156 |
-
>
|
| 157 |
{nodes.map((node) => {
|
| 158 |
const isExpanded = expandedPositions.has(node.pos);
|
| 159 |
const hasChildren = node.children.length > 0;
|
| 160 |
|
| 161 |
return (
|
| 162 |
-
<
|
| 163 |
-
<
|
| 164 |
-
|
| 165 |
-
onClick={(e
|
| 166 |
e.preventDefault();
|
| 167 |
scrollTo(node.pos);
|
| 168 |
}}
|
| 169 |
-
sx={{
|
| 170 |
-
cursor: "pointer",
|
| 171 |
-
fontSize: "13px",
|
| 172 |
-
lineHeight: 1.5,
|
| 173 |
-
fontWeight: isRoot ? 700 : 400,
|
| 174 |
-
color: "text.secondary",
|
| 175 |
-
textDecoration: activePos === node.pos ? "underline" : "none",
|
| 176 |
-
textUnderlineOffset: "3px",
|
| 177 |
-
transition: "color 120ms ease",
|
| 178 |
-
"&:hover": {
|
| 179 |
-
textDecoration: "underline solid",
|
| 180 |
-
textDecorationColor: "text.disabled",
|
| 181 |
-
},
|
| 182 |
-
}}
|
| 183 |
>
|
| 184 |
{node.text}
|
| 185 |
-
</
|
| 186 |
{hasChildren && (
|
| 187 |
-
<
|
| 188 |
-
|
| 189 |
-
|
| 190 |
maxHeight: isExpanded ? 500 : 0,
|
| 191 |
opacity: isExpanded ? 1 : 0,
|
| 192 |
-
transition: "max-height 200ms ease, opacity 200ms ease",
|
| 193 |
}}
|
| 194 |
>
|
| 195 |
{renderList(node.children, false)}
|
| 196 |
-
</
|
| 197 |
)}
|
| 198 |
-
</
|
| 199 |
);
|
| 200 |
})}
|
| 201 |
-
</
|
| 202 |
);
|
| 203 |
|
| 204 |
return (
|
| 205 |
-
<
|
| 206 |
-
<
|
| 207 |
-
|
| 208 |
-
sx={{
|
| 209 |
-
color: "text.disabled",
|
| 210 |
-
fontWeight: 600,
|
| 211 |
-
textTransform: "uppercase",
|
| 212 |
-
letterSpacing: "0.05em",
|
| 213 |
-
fontSize: "0.65rem",
|
| 214 |
-
pl: "16px",
|
| 215 |
-
mb: 1,
|
| 216 |
-
display: "block",
|
| 217 |
-
}}
|
| 218 |
-
>
|
| 219 |
-
Table of contents
|
| 220 |
-
</Typography>
|
| 221 |
-
|
| 222 |
-
<Box
|
| 223 |
-
component="nav"
|
| 224 |
-
sx={{
|
| 225 |
-
borderLeft: "1px solid",
|
| 226 |
-
borderColor: "divider",
|
| 227 |
-
pl: "16px",
|
| 228 |
-
fontSize: "13px",
|
| 229 |
-
}}
|
| 230 |
-
>
|
| 231 |
{renderList(tree, true)}
|
| 232 |
-
</
|
| 233 |
-
</
|
| 234 |
);
|
| 235 |
}
|
|
|
|
| 1 |
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
|
|
|
| 2 |
import type { Editor } from "@tiptap/core";
|
| 3 |
|
| 4 |
const SCROLL_OFFSET_PX = 80;
|
|
|
|
| 132 |
|
| 133 |
if (!editor || headings.length === 0) {
|
| 134 |
return (
|
| 135 |
+
<div className="table-of-contents">
|
| 136 |
+
<div className="toc-title">Table of contents</div>
|
| 137 |
+
<div className="toc-empty">Headings will appear here as you write.</div>
|
| 138 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
);
|
| 140 |
}
|
| 141 |
|
| 142 |
const renderList = (nodes: TocNode[], isRoot: boolean) => (
|
| 143 |
+
<ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
{nodes.map((node) => {
|
| 145 |
const isExpanded = expandedPositions.has(node.pos);
|
| 146 |
const hasChildren = node.children.length > 0;
|
| 147 |
|
| 148 |
return (
|
| 149 |
+
<li key={node.id}>
|
| 150 |
+
<a
|
| 151 |
+
className={activePos === node.pos ? "active" : undefined}
|
| 152 |
+
onClick={(e) => {
|
| 153 |
e.preventDefault();
|
| 154 |
scrollTo(node.pos);
|
| 155 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
>
|
| 157 |
{node.text}
|
| 158 |
+
</a>
|
| 159 |
{hasChildren && (
|
| 160 |
+
<div
|
| 161 |
+
className="toc-children"
|
| 162 |
+
style={{
|
| 163 |
maxHeight: isExpanded ? 500 : 0,
|
| 164 |
opacity: isExpanded ? 1 : 0,
|
|
|
|
| 165 |
}}
|
| 166 |
>
|
| 167 |
{renderList(node.children, false)}
|
| 168 |
+
</div>
|
| 169 |
)}
|
| 170 |
+
</li>
|
| 171 |
);
|
| 172 |
})}
|
| 173 |
+
</ul>
|
| 174 |
);
|
| 175 |
|
| 176 |
return (
|
| 177 |
+
<div className="table-of-contents">
|
| 178 |
+
<div className="toc-title">Table of contents</div>
|
| 179 |
+
<nav>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
{renderList(tree, true)}
|
| 181 |
+
</nav>
|
| 182 |
+
</div>
|
| 183 |
);
|
| 184 |
}
|
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState, useEffect, useRef, useCallback } from "react";
|
| 2 |
+
import { NodeViewWrapper } from "@tiptap/react";
|
| 3 |
+
import type { NodeViewProps } from "@tiptap/react";
|
| 4 |
+
import mermaid from "mermaid";
|
| 5 |
+
|
| 6 |
+
let mermaidInitialized = false;
|
| 7 |
+
|
| 8 |
+
function ensureMermaidInit() {
|
| 9 |
+
if (mermaidInitialized) return;
|
| 10 |
+
mermaid.initialize({
|
| 11 |
+
startOnLoad: false,
|
| 12 |
+
theme: "neutral",
|
| 13 |
+
securityLevel: "loose",
|
| 14 |
+
fontFamily: "var(--default-font-family)",
|
| 15 |
+
});
|
| 16 |
+
mermaidInitialized = true;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
export function MermaidNodeView({ node, updateAttributes }: NodeViewProps) {
|
| 20 |
+
const code = (node.attrs.code as string) || "";
|
| 21 |
+
const [editing, setEditing] = useState(!code);
|
| 22 |
+
const [draft, setDraft] = useState(code);
|
| 23 |
+
const [svgHtml, setSvgHtml] = useState("");
|
| 24 |
+
const [error, setError] = useState("");
|
| 25 |
+
const renderIdRef = useRef(0);
|
| 26 |
+
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
| 27 |
+
|
| 28 |
+
useEffect(() => {
|
| 29 |
+
if (!editing) setDraft(code);
|
| 30 |
+
}, [code, editing]);
|
| 31 |
+
|
| 32 |
+
useEffect(() => {
|
| 33 |
+
if (editing && textareaRef.current) {
|
| 34 |
+
textareaRef.current.focus();
|
| 35 |
+
textareaRef.current.selectionStart = textareaRef.current.value.length;
|
| 36 |
+
}
|
| 37 |
+
}, [editing]);
|
| 38 |
+
|
| 39 |
+
const renderDiagram = useCallback(async (src: string) => {
|
| 40 |
+
if (!src.trim()) {
|
| 41 |
+
setSvgHtml("");
|
| 42 |
+
setError("");
|
| 43 |
+
return;
|
| 44 |
+
}
|
| 45 |
+
ensureMermaidInit();
|
| 46 |
+
const id = `mermaid-${++renderIdRef.current}`;
|
| 47 |
+
try {
|
| 48 |
+
const { svg } = await mermaid.render(id, src);
|
| 49 |
+
setSvgHtml(svg);
|
| 50 |
+
setError("");
|
| 51 |
+
} catch (err: any) {
|
| 52 |
+
setError(err?.message || "Invalid diagram");
|
| 53 |
+
const stale = document.getElementById(id);
|
| 54 |
+
stale?.remove();
|
| 55 |
+
}
|
| 56 |
+
}, []);
|
| 57 |
+
|
| 58 |
+
useEffect(() => {
|
| 59 |
+
renderDiagram(code);
|
| 60 |
+
}, [code, renderDiagram]);
|
| 61 |
+
|
| 62 |
+
const commit = useCallback(() => {
|
| 63 |
+
setEditing(false);
|
| 64 |
+
if (draft !== code) {
|
| 65 |
+
updateAttributes({ code: draft });
|
| 66 |
+
}
|
| 67 |
+
}, [draft, code, updateAttributes]);
|
| 68 |
+
|
| 69 |
+
return (
|
| 70 |
+
<NodeViewWrapper data-component="mermaid">
|
| 71 |
+
<div
|
| 72 |
+
contentEditable={false}
|
| 73 |
+
style={{
|
| 74 |
+
border: "1px solid var(--border-color)",
|
| 75 |
+
borderRadius: 8,
|
| 76 |
+
overflow: "hidden",
|
| 77 |
+
margin: "0.75em 0",
|
| 78 |
+
userSelect: "none",
|
| 79 |
+
}}
|
| 80 |
+
>
|
| 81 |
+
{/* Header */}
|
| 82 |
+
<div
|
| 83 |
+
style={{
|
| 84 |
+
display: "flex",
|
| 85 |
+
alignItems: "center",
|
| 86 |
+
justifyContent: "space-between",
|
| 87 |
+
padding: "6px 12px",
|
| 88 |
+
borderBottom: "1px solid var(--border-color)",
|
| 89 |
+
background: "var(--surface-bg)",
|
| 90 |
+
}}
|
| 91 |
+
>
|
| 92 |
+
<span style={{ fontSize: 12, fontWeight: 600, color: "var(--muted-color)" }}>
|
| 93 |
+
◈ Mermaid
|
| 94 |
+
</span>
|
| 95 |
+
<button
|
| 96 |
+
onClick={() => {
|
| 97 |
+
if (editing) commit();
|
| 98 |
+
else setEditing(true);
|
| 99 |
+
}}
|
| 100 |
+
style={{
|
| 101 |
+
background: "none",
|
| 102 |
+
border: "1px solid var(--border-color)",
|
| 103 |
+
borderRadius: 4,
|
| 104 |
+
padding: "2px 10px",
|
| 105 |
+
fontSize: 11,
|
| 106 |
+
color: "var(--muted-color)",
|
| 107 |
+
cursor: "pointer",
|
| 108 |
+
}}
|
| 109 |
+
>
|
| 110 |
+
{editing ? "Done" : "Edit"}
|
| 111 |
+
</button>
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
{/* Code editor (shown when editing) */}
|
| 115 |
+
{editing && (
|
| 116 |
+
<div style={{ borderBottom: "1px solid var(--border-color)" }}>
|
| 117 |
+
<textarea
|
| 118 |
+
ref={textareaRef}
|
| 119 |
+
value={draft}
|
| 120 |
+
onChange={(e) => setDraft(e.target.value)}
|
| 121 |
+
onBlur={commit}
|
| 122 |
+
onKeyDown={(e) => {
|
| 123 |
+
if (e.key === "Escape") {
|
| 124 |
+
setDraft(code);
|
| 125 |
+
setEditing(false);
|
| 126 |
+
}
|
| 127 |
+
if (e.key === "Tab") {
|
| 128 |
+
e.preventDefault();
|
| 129 |
+
const ta = e.currentTarget;
|
| 130 |
+
const start = ta.selectionStart;
|
| 131 |
+
const end = ta.selectionEnd;
|
| 132 |
+
const val = ta.value;
|
| 133 |
+
const updated = val.substring(0, start) + " " + val.substring(end);
|
| 134 |
+
setDraft(updated);
|
| 135 |
+
requestAnimationFrame(() => {
|
| 136 |
+
ta.selectionStart = ta.selectionEnd = start + 2;
|
| 137 |
+
});
|
| 138 |
+
}
|
| 139 |
+
}}
|
| 140 |
+
spellCheck={false}
|
| 141 |
+
style={{
|
| 142 |
+
width: "100%",
|
| 143 |
+
minHeight: 120,
|
| 144 |
+
padding: "12px 16px",
|
| 145 |
+
border: "none",
|
| 146 |
+
outline: "none",
|
| 147 |
+
resize: "vertical",
|
| 148 |
+
fontFamily: "var(--font-mono)",
|
| 149 |
+
fontSize: 13,
|
| 150 |
+
lineHeight: 1.5,
|
| 151 |
+
background: "var(--code-bg)",
|
| 152 |
+
color: "var(--text-color)",
|
| 153 |
+
boxSizing: "border-box",
|
| 154 |
+
}}
|
| 155 |
+
/>
|
| 156 |
+
</div>
|
| 157 |
+
)}
|
| 158 |
+
|
| 159 |
+
{/* Preview */}
|
| 160 |
+
{error ? (
|
| 161 |
+
<div style={{ padding: "16px", color: "var(--danger-color, #dc2626)", fontSize: 12 }}>
|
| 162 |
+
{error}
|
| 163 |
+
</div>
|
| 164 |
+
) : svgHtml ? (
|
| 165 |
+
<div
|
| 166 |
+
style={{ padding: "16px", display: "flex", justifyContent: "center" }}
|
| 167 |
+
dangerouslySetInnerHTML={{ __html: svgHtml }}
|
| 168 |
+
/>
|
| 169 |
+
) : (
|
| 170 |
+
<div style={{ padding: "24px", textAlign: "center", color: "var(--muted-color)", fontSize: 13 }}>
|
| 171 |
+
Click "Edit" to write a Mermaid diagram
|
| 172 |
+
</div>
|
| 173 |
+
)}
|
| 174 |
+
</div>
|
| 175 |
+
</NodeViewWrapper>
|
| 176 |
+
);
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
MermaidNodeView.displayName = "MermaidView";
|
|
@@ -9,6 +9,7 @@ import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
| 9 |
import type { ComponentDef } from "./registry";
|
| 10 |
import { makeWrapperView } from "./WrapperView";
|
| 11 |
import { makeAtomicView } from "./AtomicView";
|
|
|
|
| 12 |
|
| 13 |
/**
|
| 14 |
* Build a TipTap Node for a "wrapper" component (has editable children).
|
|
@@ -128,7 +129,8 @@ export function createAtomicExtension(def: ComponentDef) {
|
|
| 128 |
},
|
| 129 |
|
| 130 |
addNodeView() {
|
| 131 |
-
|
|
|
|
| 132 |
},
|
| 133 |
});
|
| 134 |
}
|
|
|
|
| 9 |
import type { ComponentDef } from "./registry";
|
| 10 |
import { makeWrapperView } from "./WrapperView";
|
| 11 |
import { makeAtomicView } from "./AtomicView";
|
| 12 |
+
import { MermaidNodeView } from "./MermaidView";
|
| 13 |
|
| 14 |
/**
|
| 15 |
* Build a TipTap Node for a "wrapper" component (has editable children).
|
|
|
|
| 129 |
},
|
| 130 |
|
| 131 |
addNodeView() {
|
| 132 |
+
const View = def.name === "mermaid" ? MermaidNodeView : makeAtomicView(def);
|
| 133 |
+
return ReactNodeViewRenderer(View);
|
| 134 |
},
|
| 135 |
});
|
| 136 |
}
|
|
@@ -160,4 +160,15 @@ export const COMPONENTS: ComponentDef[] = [
|
|
| 160 |
{ name: "html", type: "string", label: "HTML", default: "", placeholder: "<div>…</div>" },
|
| 161 |
],
|
| 162 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
];
|
|
|
|
| 160 |
{ name: "html", type: "string", label: "HTML", default: "", placeholder: "<div>…</div>" },
|
| 161 |
],
|
| 162 |
},
|
| 163 |
+
{
|
| 164 |
+
name: "mermaid",
|
| 165 |
+
tag: "Mermaid",
|
| 166 |
+
icon: "◈",
|
| 167 |
+
label: "Mermaid diagram",
|
| 168 |
+
description: "Flowchart, sequence, Gantt, etc.",
|
| 169 |
+
kind: "atomic",
|
| 170 |
+
fields: [
|
| 171 |
+
{ name: "code", type: "string", label: "Code", default: "graph TD\n A[Start] --> B{Decision}\n B -->|Yes| C[OK]\n B -->|No| D[End]", placeholder: "graph TD\\n A --> B" },
|
| 172 |
+
],
|
| 173 |
+
},
|
| 174 |
];
|
|
@@ -3,10 +3,6 @@
|
|
| 3 |
* Covers every block/mark type supported by the editor.
|
| 4 |
*/
|
| 5 |
export const DEFAULT_CONTENT = `
|
| 6 |
-
<h1>Welcome to the Collaborative Editor</h1>
|
| 7 |
-
|
| 8 |
-
<p>This demo article showcases <strong>every content type</strong> available in the editor. Feel free to edit, delete, or rewrite anything — the AI assistant in the left panel can help you.</p>
|
| 9 |
-
|
| 10 |
<h2>Text formatting</h2>
|
| 11 |
|
| 12 |
<p>You can make text <strong>bold</strong>, <em>italic</em>, or <s>strikethrough</s>. Combine them for <strong><em>bold italic</em></strong>. Use <code>inline code</code> for technical terms, and add <a href="https://huggingface.co">links</a> to external resources.</p>
|
|
@@ -149,6 +145,8 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True))</code></pre>
|
|
| 149 |
|
| 150 |
<div data-component="htmlEmbed" src="d3-scaling-chart.html" title="Interactive scaling law visualization" desc="Explore how model size, data, and compute interact." wide="false" downloadable="true"></div>
|
| 151 |
|
|
|
|
|
|
|
| 152 |
<p>The concept of <span data-type="glossary" term="Scaling law" definition="A power-law relationship between model size, dataset size, compute budget, and performance."></span> has become central to modern AI research. Early work<span data-type="footnote" content="Hestness et al. (2017) observed similar scaling behavior in vision and translation tasks before the scaling laws paper formalized the framework."></span> suggested these relationships hold across modalities.</p>
|
| 153 |
|
| 154 |
<div data-component="stack" layout="2-column" gap="medium"><div data-type="stack-column"><p><strong>Column A</strong></p><p>Multi-column layouts let you place content side by side. Each column is fully editable.</p></div><div data-type="stack-column"><p><strong>Column B</strong></p><p>Use the layout selector in the header to switch between 2, 3, or 4 columns.</p></div></div>
|
|
|
|
| 3 |
* Covers every block/mark type supported by the editor.
|
| 4 |
*/
|
| 5 |
export const DEFAULT_CONTENT = `
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
<h2>Text formatting</h2>
|
| 7 |
|
| 8 |
<p>You can make text <strong>bold</strong>, <em>italic</em>, or <s>strikethrough</s>. Combine them for <strong><em>bold italic</em></strong>. Use <code>inline code</code> for technical terms, and add <a href="https://huggingface.co">links</a> to external resources.</p>
|
|
|
|
| 145 |
|
| 146 |
<div data-component="htmlEmbed" src="d3-scaling-chart.html" title="Interactive scaling law visualization" desc="Explore how model size, data, and compute interact." wide="false" downloadable="true"></div>
|
| 147 |
|
| 148 |
+
<div data-component="mermaid" code="graph TD\n A[Data Collection] --> B[Preprocessing]\n B --> C[Training]\n C --> D{Evaluation}\n D -->|Pass| E[Deploy]\n D -->|Fail| B"></div>
|
| 149 |
+
|
| 150 |
<p>The concept of <span data-type="glossary" term="Scaling law" definition="A power-law relationship between model size, dataset size, compute budget, and performance."></span> has become central to modern AI research. Early work<span data-type="footnote" content="Hestness et al. (2017) observed similar scaling behavior in vision and translation tasks before the scaling laws paper formalized the framework."></span> suggested these relationships hold across modalities.</p>
|
| 151 |
|
| 152 |
<div data-component="stack" layout="2-column" gap="medium"><div data-type="stack-column"><p><strong>Column A</strong></p><p>Multi-column layouts let you place content side by side. Each column is fully editable.</p></div><div data-type="stack-column"><p><strong>Column B</strong></p><p>Use the layout selector in the header to switch between 2, 3, or 4 columns.</p></div></div>
|
|
@@ -22,7 +22,7 @@ export function FrontmatterHero({ store }: FrontmatterHeroProps) {
|
|
| 22 |
const [showAuthorForm, setShowAuthorForm] = useState(false);
|
| 23 |
|
| 24 |
if (!data) {
|
| 25 |
-
return <
|
| 26 |
}
|
| 27 |
|
| 28 |
const hasAuthors = data.authors.length > 0;
|
|
@@ -31,170 +31,126 @@ export function FrontmatterHero({ store }: FrontmatterHeroProps) {
|
|
| 31 |
const hasMeta = hasAuthors || data.published || data.doi;
|
| 32 |
|
| 33 |
return (
|
| 34 |
-
<
|
| 35 |
-
{/* Hero section -
|
| 36 |
-
<
|
| 37 |
-
<
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
fontWeight: 800,
|
| 45 |
-
lineHeight: 1.12,
|
| 46 |
-
letterSpacing: "-0.02em",
|
| 47 |
-
color: "text.primary",
|
| 48 |
-
mb: 1,
|
| 49 |
-
textWrap: "balance",
|
| 50 |
-
}}
|
| 51 |
-
multiline
|
| 52 |
-
center
|
| 53 |
-
/>
|
| 54 |
-
</Box>
|
| 55 |
|
| 56 |
-
<
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
fontWeight: 400,
|
| 64 |
-
lineHeight: 1.6,
|
| 65 |
-
color: "text.secondary",
|
| 66 |
-
fontStyle: "italic",
|
| 67 |
-
}}
|
| 68 |
-
center
|
| 69 |
-
/>
|
| 70 |
-
</Box>
|
| 71 |
-
</Box>
|
| 72 |
|
| 73 |
-
{/* Meta bar -
|
| 74 |
{hasMeta && (
|
| 75 |
-
<
|
| 76 |
-
|
| 77 |
-
borderTop: "1px solid",
|
| 78 |
-
borderBottom: "1px solid",
|
| 79 |
-
borderColor: "divider",
|
| 80 |
-
py: 2,
|
| 81 |
-
fontSize: "0.9rem",
|
| 82 |
-
}}
|
| 83 |
-
>
|
| 84 |
-
<Box
|
| 85 |
-
sx={{
|
| 86 |
-
maxWidth: 980,
|
| 87 |
-
mx: "auto",
|
| 88 |
-
px: 2,
|
| 89 |
-
display: "flex",
|
| 90 |
-
flexDirection: "row",
|
| 91 |
-
justifyContent: "space-between",
|
| 92 |
-
gap: 1,
|
| 93 |
-
flexWrap: "wrap",
|
| 94 |
-
rowGap: 1.5,
|
| 95 |
-
}}
|
| 96 |
-
>
|
| 97 |
{/* Authors cell */}
|
| 98 |
-
<
|
| 99 |
-
<
|
|
|
|
| 100 |
{data.authors.map((author, i) => (
|
| 101 |
-
<
|
| 102 |
-
<
|
| 103 |
-
|
| 104 |
onClick={() => setEditingAuthorIdx(i)}
|
| 105 |
-
sx={{
|
| 106 |
-
cursor: "pointer",
|
| 107 |
-
borderRadius: 0.5,
|
| 108 |
-
transition: "background 0.15s",
|
| 109 |
-
"&:hover": { bgcolor: "rgba(255,255,255,0.06)" },
|
| 110 |
-
}}
|
| 111 |
>
|
| 112 |
{author.url ? (
|
| 113 |
-
<
|
| 114 |
{author.name}
|
| 115 |
-
</
|
| 116 |
) : (
|
| 117 |
author.name
|
| 118 |
)}
|
| 119 |
{multipleAffiliations && author.affiliations?.length > 0 && (
|
| 120 |
<sup>{author.affiliations.join(",")}</sup>
|
| 121 |
)}
|
| 122 |
-
</
|
| 123 |
{i < data.authors.length - 1 && <>, </>}
|
| 124 |
-
</
|
| 125 |
))}
|
| 126 |
-
<
|
| 127 |
<Tooltip title="Add author" arrow>
|
| 128 |
<IconButton
|
| 129 |
size="small"
|
| 130 |
onClick={() => setShowAuthorForm(true)}
|
| 131 |
-
sx={{ color: "
|
| 132 |
>
|
| 133 |
<AddIcon sx={{ fontSize: 14 }} />
|
| 134 |
</IconButton>
|
| 135 |
</Tooltip>
|
| 136 |
-
</
|
| 137 |
-
</
|
| 138 |
-
</
|
| 139 |
|
| 140 |
{/* Affiliations cell */}
|
| 141 |
{hasAffiliations && (
|
| 142 |
-
<
|
|
|
|
| 143 |
{multipleAffiliations ? (
|
| 144 |
-
<
|
| 145 |
{data.affiliations.map((aff, i) => (
|
| 146 |
-
<
|
| 147 |
{aff.url ? (
|
| 148 |
-
<a href={aff.url} target="_blank" rel="noopener noreferrer"
|
| 149 |
{aff.name}
|
| 150 |
</a>
|
| 151 |
) : (
|
| 152 |
aff.name
|
| 153 |
)}
|
| 154 |
-
</
|
| 155 |
))}
|
| 156 |
-
</
|
| 157 |
) : (
|
| 158 |
-
<
|
| 159 |
{data.affiliations[0].url ? (
|
| 160 |
-
<a href={data.affiliations[0].url} target="_blank" rel="noopener noreferrer"
|
| 161 |
{data.affiliations[0].name}
|
| 162 |
</a>
|
| 163 |
) : (
|
| 164 |
data.affiliations[0].name
|
| 165 |
)}
|
| 166 |
-
</
|
| 167 |
)}
|
| 168 |
-
</
|
| 169 |
)}
|
| 170 |
|
| 171 |
{/* Published cell */}
|
| 172 |
-
<
|
|
|
|
| 173 |
<EditableText
|
| 174 |
value={data.published}
|
| 175 |
placeholder="Date"
|
| 176 |
onChange={(v) => update("published", v)}
|
| 177 |
-
typographySx={{ fontSize: "0.9rem", color: "text.primary" }}
|
| 178 |
inline
|
| 179 |
/>
|
| 180 |
-
</
|
| 181 |
|
| 182 |
{/* DOI cell */}
|
| 183 |
-
<
|
|
|
|
| 184 |
<EditableText
|
| 185 |
value={data.doi}
|
| 186 |
placeholder="10.xxxx/xxxxx"
|
| 187 |
onChange={(v) => update("doi", v)}
|
| 188 |
-
typographySx={{ fontSize: "0.9rem", color: "text.primary", fontFamily: "monospace" }}
|
| 189 |
inline
|
| 190 |
/>
|
| 191 |
-
</
|
| 192 |
-
</
|
| 193 |
-
</
|
| 194 |
)}
|
| 195 |
|
| 196 |
-
{/* Author forms */}
|
| 197 |
-
<
|
| 198 |
{showAuthorForm && (
|
| 199 |
<AuthorInlineForm
|
| 200 |
affiliations={data.affiliations}
|
|
@@ -225,47 +181,23 @@ export function FrontmatterHero({ store }: FrontmatterHeroProps) {
|
|
| 225 |
onCancel={() => setEditingAuthorIdx(null)}
|
| 226 |
/>
|
| 227 |
)}
|
| 228 |
-
</
|
| 229 |
-
</
|
| 230 |
);
|
| 231 |
}
|
| 232 |
|
| 233 |
-
// ----
|
| 234 |
-
|
| 235 |
-
function MetaCell({ label, children }: { label: string; children: React.ReactNode }) {
|
| 236 |
-
return (
|
| 237 |
-
<Box sx={{ display: "flex", flexDirection: "column", gap: 1, maxWidth: 400 }}>
|
| 238 |
-
<Typography
|
| 239 |
-
component="h3"
|
| 240 |
-
sx={{
|
| 241 |
-
m: 0,
|
| 242 |
-
fontSize: "12px",
|
| 243 |
-
fontWeight: 400,
|
| 244 |
-
color: "text.disabled",
|
| 245 |
-
textTransform: "uppercase",
|
| 246 |
-
letterSpacing: "0.02em",
|
| 247 |
-
}}
|
| 248 |
-
>
|
| 249 |
-
{label}
|
| 250 |
-
</Typography>
|
| 251 |
-
<Box sx={{ m: 0 }}>{children}</Box>
|
| 252 |
-
</Box>
|
| 253 |
-
);
|
| 254 |
-
}
|
| 255 |
-
|
| 256 |
-
// ---- Editable text field (click-to-edit) ----
|
| 257 |
|
| 258 |
interface EditableTextProps {
|
| 259 |
value: string;
|
| 260 |
placeholder: string;
|
| 261 |
onChange: (value: string) => void;
|
| 262 |
-
|
| 263 |
multiline?: boolean;
|
| 264 |
inline?: boolean;
|
| 265 |
-
center?: boolean;
|
| 266 |
}
|
| 267 |
|
| 268 |
-
function EditableText({ value, placeholder, onChange,
|
| 269 |
const [editing, setEditing] = useState(false);
|
| 270 |
const [draft, setDraft] = useState(value);
|
| 271 |
const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
|
|
@@ -302,11 +234,10 @@ function EditableText({ value, placeholder, onChange, typographySx = {}, multili
|
|
| 302 |
|
| 303 |
const displayValue = value || placeholder;
|
| 304 |
const isEmpty = !value;
|
| 305 |
-
const textAlign = center ? "center" : undefined;
|
| 306 |
|
| 307 |
if (editing) {
|
| 308 |
return (
|
| 309 |
-
<
|
| 310 |
<TextField
|
| 311 |
inputRef={inputRef}
|
| 312 |
value={draft}
|
|
@@ -320,43 +251,30 @@ function EditableText({ value, placeholder, onChange, typographySx = {}, multili
|
|
| 320 |
slotProps={{
|
| 321 |
input: {
|
| 322 |
disableUnderline: true,
|
| 323 |
-
sx: {
|
| 324 |
-
...typographySx,
|
| 325 |
-
textAlign,
|
| 326 |
-
p: 0,
|
| 327 |
-
m: 0,
|
| 328 |
-
},
|
| 329 |
},
|
| 330 |
}}
|
| 331 |
/>
|
| 332 |
-
</
|
| 333 |
);
|
| 334 |
}
|
| 335 |
|
| 336 |
return (
|
| 337 |
-
<
|
|
|
|
| 338 |
onClick={() => setEditing(true)}
|
| 339 |
-
|
| 340 |
-
...typographySx,
|
| 341 |
-
textAlign,
|
| 342 |
-
cursor: "text",
|
| 343 |
-
opacity: isEmpty ? 0.35 : 1,
|
| 344 |
-
borderRadius: 1,
|
| 345 |
-
transition: "background 0.15s",
|
| 346 |
-
px: 0.5,
|
| 347 |
-
mx: -0.5,
|
| 348 |
display: inline ? "inline" : "block",
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
},
|
| 352 |
}}
|
| 353 |
>
|
| 354 |
{displayValue}
|
| 355 |
-
</
|
| 356 |
);
|
| 357 |
}
|
| 358 |
|
| 359 |
-
// ---- Author inline form ----
|
| 360 |
|
| 361 |
function AuthorInlineForm({
|
| 362 |
initial,
|
|
|
|
| 22 |
const [showAuthorForm, setShowAuthorForm] = useState(false);
|
| 23 |
|
| 24 |
if (!data) {
|
| 25 |
+
return <div className="hero" />;
|
| 26 |
}
|
| 27 |
|
| 28 |
const hasAuthors = data.authors.length > 0;
|
|
|
|
| 31 |
const hasMeta = hasAuthors || data.published || data.doi;
|
| 32 |
|
| 33 |
return (
|
| 34 |
+
<div>
|
| 35 |
+
{/* Hero section - uses .hero from _hero.css (same as HeroArticle.astro) */}
|
| 36 |
+
<section className="hero">
|
| 37 |
+
<EditableText
|
| 38 |
+
value={data.title}
|
| 39 |
+
placeholder="Article title"
|
| 40 |
+
onChange={(v) => update("title", v)}
|
| 41 |
+
className="hero-title"
|
| 42 |
+
multiline
|
| 43 |
+
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
<EditableText
|
| 46 |
+
value={data.subtitle}
|
| 47 |
+
placeholder="Subtitle (optional)"
|
| 48 |
+
onChange={(v) => update("subtitle", v)}
|
| 49 |
+
className="hero-desc"
|
| 50 |
+
/>
|
| 51 |
+
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
+
{/* Meta bar - uses .meta from _hero.css (same as HeroArticle.astro) */}
|
| 54 |
{hasMeta && (
|
| 55 |
+
<header className="meta" aria-label="Article meta information">
|
| 56 |
+
<div className="meta-container">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
{/* Authors cell */}
|
| 58 |
+
<div className="meta-container-cell">
|
| 59 |
+
<h3>Authors</h3>
|
| 60 |
+
<ul className="authors">
|
| 61 |
{data.authors.map((author, i) => (
|
| 62 |
+
<li key={`author-${i}`}>
|
| 63 |
+
<span
|
| 64 |
+
className="author-editable"
|
| 65 |
onClick={() => setEditingAuthorIdx(i)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
>
|
| 67 |
{author.url ? (
|
| 68 |
+
<a href={author.url} target="_blank" rel="noopener noreferrer">
|
| 69 |
{author.name}
|
| 70 |
+
</a>
|
| 71 |
) : (
|
| 72 |
author.name
|
| 73 |
)}
|
| 74 |
{multipleAffiliations && author.affiliations?.length > 0 && (
|
| 75 |
<sup>{author.affiliations.join(",")}</sup>
|
| 76 |
)}
|
| 77 |
+
</span>
|
| 78 |
{i < data.authors.length - 1 && <>, </>}
|
| 79 |
+
</li>
|
| 80 |
))}
|
| 81 |
+
<li className="author-add-btn">
|
| 82 |
<Tooltip title="Add author" arrow>
|
| 83 |
<IconButton
|
| 84 |
size="small"
|
| 85 |
onClick={() => setShowAuthorForm(true)}
|
| 86 |
+
sx={{ color: "var(--muted-color)", p: 0.25 }}
|
| 87 |
>
|
| 88 |
<AddIcon sx={{ fontSize: 14 }} />
|
| 89 |
</IconButton>
|
| 90 |
</Tooltip>
|
| 91 |
+
</li>
|
| 92 |
+
</ul>
|
| 93 |
+
</div>
|
| 94 |
|
| 95 |
{/* Affiliations cell */}
|
| 96 |
{hasAffiliations && (
|
| 97 |
+
<div className="meta-container-cell">
|
| 98 |
+
<h3>Affiliations</h3>
|
| 99 |
{multipleAffiliations ? (
|
| 100 |
+
<ol className="affiliations">
|
| 101 |
{data.affiliations.map((aff, i) => (
|
| 102 |
+
<li key={`aff-${i}`}>
|
| 103 |
{aff.url ? (
|
| 104 |
+
<a href={aff.url} target="_blank" rel="noopener noreferrer">
|
| 105 |
{aff.name}
|
| 106 |
</a>
|
| 107 |
) : (
|
| 108 |
aff.name
|
| 109 |
)}
|
| 110 |
+
</li>
|
| 111 |
))}
|
| 112 |
+
</ol>
|
| 113 |
) : (
|
| 114 |
+
<p>
|
| 115 |
{data.affiliations[0].url ? (
|
| 116 |
+
<a href={data.affiliations[0].url} target="_blank" rel="noopener noreferrer">
|
| 117 |
{data.affiliations[0].name}
|
| 118 |
</a>
|
| 119 |
) : (
|
| 120 |
data.affiliations[0].name
|
| 121 |
)}
|
| 122 |
+
</p>
|
| 123 |
)}
|
| 124 |
+
</div>
|
| 125 |
)}
|
| 126 |
|
| 127 |
{/* Published cell */}
|
| 128 |
+
<div className="meta-container-cell">
|
| 129 |
+
<h3>Published</h3>
|
| 130 |
<EditableText
|
| 131 |
value={data.published}
|
| 132 |
placeholder="Date"
|
| 133 |
onChange={(v) => update("published", v)}
|
|
|
|
| 134 |
inline
|
| 135 |
/>
|
| 136 |
+
</div>
|
| 137 |
|
| 138 |
{/* DOI cell */}
|
| 139 |
+
<div className="meta-container-cell">
|
| 140 |
+
<h3>DOI</h3>
|
| 141 |
<EditableText
|
| 142 |
value={data.doi}
|
| 143 |
placeholder="10.xxxx/xxxxx"
|
| 144 |
onChange={(v) => update("doi", v)}
|
|
|
|
| 145 |
inline
|
| 146 |
/>
|
| 147 |
+
</div>
|
| 148 |
+
</div>
|
| 149 |
+
</header>
|
| 150 |
)}
|
| 151 |
|
| 152 |
+
{/* Author forms (editor-only, MUI is fine here) */}
|
| 153 |
+
<div style={{ maxWidth: 680, margin: "0 auto", padding: "0 16px" }}>
|
| 154 |
{showAuthorForm && (
|
| 155 |
<AuthorInlineForm
|
| 156 |
affiliations={data.affiliations}
|
|
|
|
| 181 |
onCancel={() => setEditingAuthorIdx(null)}
|
| 182 |
/>
|
| 183 |
)}
|
| 184 |
+
</div>
|
| 185 |
+
</div>
|
| 186 |
);
|
| 187 |
}
|
| 188 |
|
| 189 |
+
// ---- Editable text field (click-to-edit, editor-only behavior) ----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
|
| 191 |
interface EditableTextProps {
|
| 192 |
value: string;
|
| 193 |
placeholder: string;
|
| 194 |
onChange: (value: string) => void;
|
| 195 |
+
className?: string;
|
| 196 |
multiline?: boolean;
|
| 197 |
inline?: boolean;
|
|
|
|
| 198 |
}
|
| 199 |
|
| 200 |
+
function EditableText({ value, placeholder, onChange, className, multiline, inline }: EditableTextProps) {
|
| 201 |
const [editing, setEditing] = useState(false);
|
| 202 |
const [draft, setDraft] = useState(value);
|
| 203 |
const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
|
|
|
|
| 234 |
|
| 235 |
const displayValue = value || placeholder;
|
| 236 |
const isEmpty = !value;
|
|
|
|
| 237 |
|
| 238 |
if (editing) {
|
| 239 |
return (
|
| 240 |
+
<span className={className} style={{ display: inline ? "inline-flex" : "flex" }}>
|
| 241 |
<TextField
|
| 242 |
inputRef={inputRef}
|
| 243 |
value={draft}
|
|
|
|
| 251 |
slotProps={{
|
| 252 |
input: {
|
| 253 |
disableUnderline: true,
|
| 254 |
+
sx: { p: 0, m: 0, font: "inherit", color: "inherit", textAlign: "inherit" },
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
},
|
| 256 |
}}
|
| 257 |
/>
|
| 258 |
+
</span>
|
| 259 |
);
|
| 260 |
}
|
| 261 |
|
| 262 |
return (
|
| 263 |
+
<span
|
| 264 |
+
className={`editable-text ${className || ""}`}
|
| 265 |
onClick={() => setEditing(true)}
|
| 266 |
+
style={{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
display: inline ? "inline" : "block",
|
| 268 |
+
opacity: isEmpty ? 0.35 : 1,
|
| 269 |
+
cursor: "text",
|
|
|
|
| 270 |
}}
|
| 271 |
>
|
| 272 |
{displayValue}
|
| 273 |
+
</span>
|
| 274 |
);
|
| 275 |
}
|
| 276 |
|
| 277 |
+
// ---- Author inline form (editor-only, MUI is fine) ----
|
| 278 |
|
| 279 |
function AuthorInlineForm({
|
| 280 |
initial,
|
|
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useRef, useState, useEffect, useCallback } from "react";
|
| 2 |
+
import { Box, Typography } from "@mui/material";
|
| 3 |
+
|
| 4 |
+
const L = 0.75;
|
| 5 |
+
const C = 0.12;
|
| 6 |
+
|
| 7 |
+
const COLOR_NAMES = [
|
| 8 |
+
{ name: "Candy Apple Red", hue: 0 },
|
| 9 |
+
{ name: "Boiling Magma", hue: 15 },
|
| 10 |
+
{ name: "Aerospace Orange", hue: 25 },
|
| 11 |
+
{ name: "Burtuqali Orange", hue: 33 },
|
| 12 |
+
{ name: "American Orange", hue: 40 },
|
| 13 |
+
{ name: "Cheese", hue: 48 },
|
| 14 |
+
{ name: "Amber", hue: 55 },
|
| 15 |
+
{ name: "Demonic Yellow", hue: 65 },
|
| 16 |
+
{ name: "Bat-Signal", hue: 72 },
|
| 17 |
+
{ name: "Bright Yellow Green", hue: 85 },
|
| 18 |
+
{ name: "Lasting Lime", hue: 95 },
|
| 19 |
+
{ name: "Bright Green", hue: 110 },
|
| 20 |
+
{ name: "Chlorophyll Green", hue: 120 },
|
| 21 |
+
{ name: "Green Screen", hue: 130 },
|
| 22 |
+
{ name: "Cathode Green", hue: 148 },
|
| 23 |
+
{ name: "Booger Buster", hue: 160 },
|
| 24 |
+
{ name: "Enthusiasm", hue: 170 },
|
| 25 |
+
{ name: "Ice Ice Baby", hue: 180 },
|
| 26 |
+
{ name: "Vivid Sky Blue", hue: 195 },
|
| 27 |
+
{ name: "Azure", hue: 214 },
|
| 28 |
+
{ name: "Blue Ribbon", hue: 225 },
|
| 29 |
+
{ name: "Icelandic Water", hue: 238 },
|
| 30 |
+
{ name: "Blue Pencil", hue: 250 },
|
| 31 |
+
{ name: "Electric Ultramarine", hue: 260 },
|
| 32 |
+
{ name: "Purple Climax", hue: 275 },
|
| 33 |
+
{ name: "Amethyst Ganzstar", hue: 285 },
|
| 34 |
+
{ name: "Electric Purple", hue: 295 },
|
| 35 |
+
{ name: "Phlox", hue: 305 },
|
| 36 |
+
{ name: "Brusque Pink", hue: 315 },
|
| 37 |
+
{ name: "Bright Magenta", hue: 325 },
|
| 38 |
+
{ name: "Pink", hue: 335 },
|
| 39 |
+
{ name: "Hot Flamingoes", hue: 345 },
|
| 40 |
+
{ name: "Carmine Red", hue: 355 },
|
| 41 |
+
];
|
| 42 |
+
|
| 43 |
+
function getColorName(hue: number): string {
|
| 44 |
+
let best = COLOR_NAMES[0].name;
|
| 45 |
+
let bestDist = 361;
|
| 46 |
+
for (const c of COLOR_NAMES) {
|
| 47 |
+
const d = Math.abs(c.hue - hue);
|
| 48 |
+
const dist = Math.min(d, 360 - d);
|
| 49 |
+
if (dist < bestDist) {
|
| 50 |
+
bestDist = dist;
|
| 51 |
+
best = c.name;
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
return best;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// OKLCH -> sRGB -> hex
|
| 58 |
+
function oklchToHex(l: number, c: number, h: number): string {
|
| 59 |
+
const hRad = (h * Math.PI) / 180;
|
| 60 |
+
const a = c * Math.cos(hRad);
|
| 61 |
+
const b = c * Math.sin(hRad);
|
| 62 |
+
|
| 63 |
+
const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
|
| 64 |
+
const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
|
| 65 |
+
const s_ = l - 0.0894841775 * a - 1.291485548 * b;
|
| 66 |
+
|
| 67 |
+
const ll = l_ * l_ * l_;
|
| 68 |
+
const mm = m_ * m_ * m_;
|
| 69 |
+
const ss = s_ * s_ * s_;
|
| 70 |
+
|
| 71 |
+
const toSrgb = (u: number) =>
|
| 72 |
+
u <= 0.0031308 ? 12.92 * u : 1.055 * Math.pow(Math.max(0, u), 1 / 2.4) - 0.055;
|
| 73 |
+
|
| 74 |
+
const r = toSrgb(+4.0767416621 * ll - 3.3077115913 * mm + 0.2309699292 * ss);
|
| 75 |
+
const g = toSrgb(-1.2684380046 * ll + 2.6097574011 * mm - 0.3413193965 * ss);
|
| 76 |
+
const bVal = toSrgb(-0.0041960863 * ll - 0.7034186147 * mm + 1.707614701 * ss);
|
| 77 |
+
|
| 78 |
+
const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v * 255)));
|
| 79 |
+
const hex = (v: number) => clamp(v).toString(16).padStart(2, "0");
|
| 80 |
+
return `#${hex(r)}${hex(g)}${hex(bVal)}`;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
interface HueSliderProps {
|
| 84 |
+
hue: number;
|
| 85 |
+
onChange: (hue: number) => void;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
export function HueSlider({ hue, onChange }: HueSliderProps) {
|
| 89 |
+
const sliderRef = useRef<HTMLDivElement>(null);
|
| 90 |
+
const [dragging, setDragging] = useState(false);
|
| 91 |
+
|
| 92 |
+
const hexColor = oklchToHex(L, C, hue);
|
| 93 |
+
const colorName = getColorName(hue);
|
| 94 |
+
|
| 95 |
+
const hueFromClientX = useCallback((clientX: number) => {
|
| 96 |
+
const rect = sliderRef.current?.getBoundingClientRect();
|
| 97 |
+
if (!rect) return hue;
|
| 98 |
+
const x = Math.max(0, Math.min(clientX - rect.left, rect.width));
|
| 99 |
+
return (x / rect.width) * 360;
|
| 100 |
+
}, [hue]);
|
| 101 |
+
|
| 102 |
+
const handlePointerDown = useCallback((e: React.PointerEvent) => {
|
| 103 |
+
e.preventDefault();
|
| 104 |
+
(e.target as HTMLElement).setPointerCapture(e.pointerId);
|
| 105 |
+
setDragging(true);
|
| 106 |
+
onChange(hueFromClientX(e.clientX));
|
| 107 |
+
}, [hueFromClientX, onChange]);
|
| 108 |
+
|
| 109 |
+
const handlePointerMove = useCallback((e: React.PointerEvent) => {
|
| 110 |
+
if (!dragging) return;
|
| 111 |
+
onChange(hueFromClientX(e.clientX));
|
| 112 |
+
}, [dragging, hueFromClientX, onChange]);
|
| 113 |
+
|
| 114 |
+
const handlePointerUp = useCallback(() => {
|
| 115 |
+
setDragging(false);
|
| 116 |
+
}, []);
|
| 117 |
+
|
| 118 |
+
// Keyboard support
|
| 119 |
+
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
| 120 |
+
const step = e.shiftKey ? 10 : 2;
|
| 121 |
+
if (e.key === "ArrowLeft") { e.preventDefault(); onChange(((hue - step) % 360 + 360) % 360); }
|
| 122 |
+
if (e.key === "ArrowRight") { e.preventDefault(); onChange((hue + step) % 360); }
|
| 123 |
+
}, [hue, onChange]);
|
| 124 |
+
|
| 125 |
+
return (
|
| 126 |
+
<Box sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}>
|
| 127 |
+
{/* Swatch + info */}
|
| 128 |
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
|
| 129 |
+
<Box
|
| 130 |
+
sx={{
|
| 131 |
+
width: 44,
|
| 132 |
+
height: 44,
|
| 133 |
+
borderRadius: "8px",
|
| 134 |
+
bgcolor: hexColor,
|
| 135 |
+
border: "1px solid",
|
| 136 |
+
borderColor: "divider",
|
| 137 |
+
flexShrink: 0,
|
| 138 |
+
}}
|
| 139 |
+
/>
|
| 140 |
+
<Box sx={{ minWidth: 0 }}>
|
| 141 |
+
<Typography variant="body2" sx={{ fontWeight: 700, fontSize: "0.8rem", lineHeight: 1.3 }}>
|
| 142 |
+
{colorName}
|
| 143 |
+
</Typography>
|
| 144 |
+
<Typography variant="caption" sx={{ color: "text.secondary", fontSize: "0.7rem", fontFamily: "monospace" }}>
|
| 145 |
+
{hexColor.toUpperCase()} - {Math.round(hue)}°
|
| 146 |
+
</Typography>
|
| 147 |
+
</Box>
|
| 148 |
+
</Box>
|
| 149 |
+
|
| 150 |
+
{/* Hue slider */}
|
| 151 |
+
<Box
|
| 152 |
+
ref={sliderRef}
|
| 153 |
+
role="slider"
|
| 154 |
+
tabIndex={0}
|
| 155 |
+
aria-label="Hue"
|
| 156 |
+
aria-valuemin={0}
|
| 157 |
+
aria-valuemax={360}
|
| 158 |
+
aria-valuenow={Math.round(hue)}
|
| 159 |
+
onPointerDown={handlePointerDown}
|
| 160 |
+
onPointerMove={handlePointerMove}
|
| 161 |
+
onPointerUp={handlePointerUp}
|
| 162 |
+
onKeyDown={handleKeyDown}
|
| 163 |
+
sx={{
|
| 164 |
+
position: "relative",
|
| 165 |
+
height: 16,
|
| 166 |
+
borderRadius: "10px",
|
| 167 |
+
border: "1px solid",
|
| 168 |
+
borderColor: "divider",
|
| 169 |
+
background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)",
|
| 170 |
+
cursor: "ew-resize",
|
| 171 |
+
touchAction: "none",
|
| 172 |
+
"&:focus-visible": { outline: "2px solid", outlineColor: "primary.main", outlineOffset: 2 },
|
| 173 |
+
}}
|
| 174 |
+
>
|
| 175 |
+
{/* Knob */}
|
| 176 |
+
<Box
|
| 177 |
+
sx={{
|
| 178 |
+
position: "absolute",
|
| 179 |
+
top: "50%",
|
| 180 |
+
left: `${(hue / 360) * 100}%`,
|
| 181 |
+
width: 14,
|
| 182 |
+
height: 14,
|
| 183 |
+
borderRadius: "50%",
|
| 184 |
+
border: "2px solid #fff",
|
| 185 |
+
transform: "translate(-50%, -50%)",
|
| 186 |
+
bgcolor: hexColor,
|
| 187 |
+
boxShadow: "0 0 0 1px rgba(0,0,0,0.15), 0 1px 3px rgba(0,0,0,0.3)",
|
| 188 |
+
pointerEvents: "none",
|
| 189 |
+
}}
|
| 190 |
+
/>
|
| 191 |
+
</Box>
|
| 192 |
+
</Box>
|
| 193 |
+
);
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
export { oklchToHex, L as OKLCH_L, C as OKLCH_C };
|
|
@@ -15,6 +15,7 @@ import { useState, useEffect } from "react";
|
|
| 15 |
import { useFrontmatter } from "./useFrontmatter";
|
| 16 |
import type { FrontmatterStore, FrontmatterData } from "./frontmatter-store";
|
| 17 |
import type * as Y from "yjs";
|
|
|
|
| 18 |
|
| 19 |
interface SettingsDrawerProps {
|
| 20 |
open: boolean;
|
|
@@ -26,12 +27,15 @@ interface SettingsDrawerProps {
|
|
| 26 |
export function SettingsDrawer({ open, onClose, store, settingsMap }: SettingsDrawerProps) {
|
| 27 |
const { data, update } = useFrontmatter(store);
|
| 28 |
const [citationStyle, setCitationStyle] = useState("apa");
|
|
|
|
| 29 |
|
| 30 |
useEffect(() => {
|
| 31 |
if (!settingsMap) return;
|
| 32 |
const sync = () => {
|
| 33 |
-
const
|
| 34 |
-
if (
|
|
|
|
|
|
|
| 35 |
};
|
| 36 |
sync();
|
| 37 |
settingsMap.observe(sync);
|
|
@@ -127,6 +131,17 @@ export function SettingsDrawer({ open, onClose, store, settingsMap }: SettingsDr
|
|
| 127 |
</Select>
|
| 128 |
</FieldGroup>
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
<Divider />
|
| 131 |
|
| 132 |
{/* Toggles */}
|
|
@@ -206,3 +221,4 @@ function FieldGroup({ label, children }: { label: string; children: React.ReactN
|
|
| 206 |
</Box>
|
| 207 |
);
|
| 208 |
}
|
|
|
|
|
|
| 15 |
import { useFrontmatter } from "./useFrontmatter";
|
| 16 |
import type { FrontmatterStore, FrontmatterData } from "./frontmatter-store";
|
| 17 |
import type * as Y from "yjs";
|
| 18 |
+
import { HueSlider, oklchToHex, OKLCH_L, OKLCH_C } from "./HueSlider";
|
| 19 |
|
| 20 |
interface SettingsDrawerProps {
|
| 21 |
open: boolean;
|
|
|
|
| 27 |
export function SettingsDrawer({ open, onClose, store, settingsMap }: SettingsDrawerProps) {
|
| 28 |
const { data, update } = useFrontmatter(store);
|
| 29 |
const [citationStyle, setCitationStyle] = useState("apa");
|
| 30 |
+
const [hue, setHue] = useState(47);
|
| 31 |
|
| 32 |
useEffect(() => {
|
| 33 |
if (!settingsMap) return;
|
| 34 |
const sync = () => {
|
| 35 |
+
const cit = settingsMap.get("citationStyle");
|
| 36 |
+
if (cit) setCitationStyle(cit as string);
|
| 37 |
+
const h = settingsMap.get("primaryHue");
|
| 38 |
+
if (h !== undefined) setHue(h as number);
|
| 39 |
};
|
| 40 |
sync();
|
| 41 |
settingsMap.observe(sync);
|
|
|
|
| 131 |
</Select>
|
| 132 |
</FieldGroup>
|
| 133 |
|
| 134 |
+
{/* Primary color (hue slider like the template) */}
|
| 135 |
+
<FieldGroup label="Primary color">
|
| 136 |
+
<HueSlider
|
| 137 |
+
hue={hue}
|
| 138 |
+
onChange={(h) => {
|
| 139 |
+
setHue(h);
|
| 140 |
+
settingsMap?.set("primaryHue", h);
|
| 141 |
+
}}
|
| 142 |
+
/>
|
| 143 |
+
</FieldGroup>
|
| 144 |
+
|
| 145 |
<Divider />
|
| 146 |
|
| 147 |
{/* Toggles */}
|
|
|
|
| 221 |
</Box>
|
| 222 |
);
|
| 223 |
}
|
| 224 |
+
|
|
@@ -1,17 +1,34 @@
|
|
| 1 |
import React from "react";
|
| 2 |
import ReactDOM from "react-dom/client";
|
| 3 |
-
import {
|
| 4 |
-
import { theme } from "./theme";
|
| 5 |
import App from "./App";
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
import "./styles/article.css";
|
|
|
|
| 8 |
import "./styles/editing.css";
|
| 9 |
|
| 10 |
ReactDOM.createRoot(document.getElementById("root")!).render(
|
| 11 |
<React.StrictMode>
|
| 12 |
-
<
|
| 13 |
-
|
| 14 |
-
<App />
|
| 15 |
-
</ThemeProvider>
|
| 16 |
</React.StrictMode>
|
| 17 |
);
|
|
|
|
| 1 |
import React from "react";
|
| 2 |
import ReactDOM from "react-dom/client";
|
| 3 |
+
import { CssBaseline } from "@mui/material";
|
|
|
|
| 4 |
import App from "./App";
|
| 5 |
+
|
| 6 |
+
// Template foundation (source of truth - same as research-article-template)
|
| 7 |
+
import "./styles/_variables.css";
|
| 8 |
+
import "./styles/_reset.css";
|
| 9 |
+
import "./styles/_base.css";
|
| 10 |
+
import "./styles/_layout.css";
|
| 11 |
+
import "./styles/_print.css";
|
| 12 |
+
import "./styles/components/_code.css";
|
| 13 |
+
import "./styles/components/_table.css";
|
| 14 |
+
import "./styles/components/_tag.css";
|
| 15 |
+
import "./styles/components/_card.css";
|
| 16 |
+
import "./styles/components/_mermaid.css";
|
| 17 |
+
import "./styles/components/_hero.css";
|
| 18 |
+
import "./styles/components/_toc.css";
|
| 19 |
+
// _button.css and _form.css are NOT imported here: they style bare
|
| 20 |
+
// <button>, <input>, <select>, <label> globally and would override MUI.
|
| 21 |
+
// The publisher injects them in the static HTML where there is no MUI.
|
| 22 |
+
|
| 23 |
+
// Editor extensions
|
| 24 |
+
import "./styles/_editor-tokens.css";
|
| 25 |
import "./styles/article.css";
|
| 26 |
+
import "./styles/toc.css";
|
| 27 |
import "./styles/editing.css";
|
| 28 |
|
| 29 |
ReactDOM.createRoot(document.getElementById("root")!).render(
|
| 30 |
<React.StrictMode>
|
| 31 |
+
<CssBaseline />
|
| 32 |
+
<App />
|
|
|
|
|
|
|
| 33 |
</React.StrictMode>
|
| 34 |
);
|
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@import "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200..900;1,200..900&display=swap";
|
| 2 |
+
|
| 3 |
+
/*
|
| 4 |
+
* Template originally sets html { font-size; line-height; background-color;
|
| 5 |
+
* overflow-x }. In the editor we scope font-size/line-height to the article
|
| 6 |
+
* area so MUI portals (Dialog, Menu, Tooltip) keep their own defaults.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
.content-grid,
|
| 10 |
+
.hero,
|
| 11 |
+
.meta {
|
| 12 |
+
font-size: 16px;
|
| 13 |
+
line-height: 1.6;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.content-grid main {
|
| 17 |
+
color: var(--text-color);
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
.content-grid main p {
|
| 21 |
+
margin: 0 0 var(--spacing-3);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.content-grid main h2 {
|
| 25 |
+
font-weight: 600;
|
| 26 |
+
font-size: clamp(22px, 2.6vw, 32px);
|
| 27 |
+
line-height: 1.2;
|
| 28 |
+
margin: var(--spacing-10) 0 var(--spacing-5);
|
| 29 |
+
padding-bottom: var(--spacing-2);
|
| 30 |
+
border-bottom: 1px solid var(--border-color);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.content-grid main h3 {
|
| 34 |
+
font-weight: 700;
|
| 35 |
+
font-size: clamp(18px, 2.1vw, 22px);
|
| 36 |
+
line-height: 1.25;
|
| 37 |
+
margin: var(--spacing-8) 0 var(--spacing-4);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.content-grid main h4 {
|
| 41 |
+
font-weight: 600;
|
| 42 |
+
text-transform: uppercase;
|
| 43 |
+
font-size: 16px;
|
| 44 |
+
line-height: 1.2;
|
| 45 |
+
margin: var(--spacing-6) 0 var(--spacing-4);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.content-grid main a {
|
| 49 |
+
color: var(--primary-color);
|
| 50 |
+
text-decoration: none;
|
| 51 |
+
background: var(--surface-bg);
|
| 52 |
+
border-bottom: 1px solid color-mix(in srgb, var(--primary-color, #007AFF) 40%, transparent);
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.content-grid main a:hover {
|
| 56 |
+
color: var(--primary-color-hover);
|
| 57 |
+
border-bottom: 1px solid color-mix(in srgb, var(--primary-color, #007AFF) 40%, transparent);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
/* Do not underline heading links inside the article (not the TOC) */
|
| 61 |
+
.content-grid main h2 a,
|
| 62 |
+
.content-grid main h3 a,
|
| 63 |
+
.content-grid main h4 a,
|
| 64 |
+
.content-grid main h5 a,
|
| 65 |
+
.content-grid main h6 a {
|
| 66 |
+
color: inherit;
|
| 67 |
+
background: none;
|
| 68 |
+
border-bottom: none;
|
| 69 |
+
text-decoration: none;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
.content-grid main h2 a:hover,
|
| 73 |
+
.content-grid main h3 a:hover,
|
| 74 |
+
.content-grid main h4 a:hover,
|
| 75 |
+
.content-grid main h5 a:hover,
|
| 76 |
+
.content-grid main h6 a:hover {
|
| 77 |
+
color: inherit;
|
| 78 |
+
border-bottom: none;
|
| 79 |
+
text-decoration: none;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.content-grid main ul,
|
| 83 |
+
.content-grid main ol {
|
| 84 |
+
padding-left: 24px;
|
| 85 |
+
margin: 0 0 var(--spacing-3);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
.content-grid main li {
|
| 89 |
+
margin-bottom: var(--spacing-2);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.content-grid main li:last-child {
|
| 93 |
+
margin-bottom: 0;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
.content-grid main blockquote {
|
| 97 |
+
border-left: 2px solid var(--border-color);
|
| 98 |
+
padding-left: var(--spacing-4);
|
| 99 |
+
font-style: italic;
|
| 100 |
+
color: var(--muted-color);
|
| 101 |
+
margin: var(--spacing-4) 0;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
.content-grid main hr {
|
| 105 |
+
border: none;
|
| 106 |
+
border-bottom: 1px solid var(--border-color);
|
| 107 |
+
margin: var(--spacing-5) 0;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
.muted {
|
| 111 |
+
color: var(--muted-color);
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
[data-footnote-ref] {
|
| 115 |
+
margin-left: 4px;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
.content-grid main mark {
|
| 119 |
+
background-color: color-mix(in srgb, var(--primary-color, #007AFF) 10%, transparent);
|
| 120 |
+
border: 1px solid color-mix(in srgb, var(--primary-color) 18%, transparent);
|
| 121 |
+
color: inherit;
|
| 122 |
+
padding: 4px 6px;
|
| 123 |
+
border-radius: 4px;
|
| 124 |
+
font-weight: 500;
|
| 125 |
+
box-decoration-break: clone;
|
| 126 |
+
-webkit-box-decoration-break: clone;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
.feature-grid {
|
| 130 |
+
display: grid;
|
| 131 |
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
| 132 |
+
gap: 12px;
|
| 133 |
+
margin: 46px 0;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
.feature-card {
|
| 137 |
+
display: flex;
|
| 138 |
+
flex-direction: column;
|
| 139 |
+
padding: 16px;
|
| 140 |
+
border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
|
| 141 |
+
;
|
| 142 |
+
background: color-mix(in srgb, var(--primary-color, #007AFF) 05%, transparent) !important;
|
| 143 |
+
border-radius: 8px;
|
| 144 |
+
text-decoration: none;
|
| 145 |
+
color: inherit;
|
| 146 |
+
transition: all 0.2s ease;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
.feature-card:hover {
|
| 150 |
+
transform: translateY(-2px);
|
| 151 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.feature-card strong {
|
| 155 |
+
font-size: 14px;
|
| 156 |
+
font-weight: 600;
|
| 157 |
+
color: var(--text-color);
|
| 158 |
+
color: var(--primary-color) !important;
|
| 159 |
+
margin-bottom: 0px !important;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
.feature-card span {
|
| 163 |
+
font-size: 12px;
|
| 164 |
+
color: var(--muted-color);
|
| 165 |
+
color: var(--primary-color) !important;
|
| 166 |
+
margin-bottom: 0px !important;
|
| 167 |
+
opacity: 1;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.katex .tag {
|
| 171 |
+
background: none;
|
| 172 |
+
border: none;
|
| 173 |
+
opacity: 0.4;
|
| 174 |
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* -----------------------------------------------------------------------
|
| 2 |
+
Editor-specific design tokens
|
| 3 |
+
|
| 4 |
+
Extends _variables.css with tokens needed only by the collaborative
|
| 5 |
+
editor UI (not the published article). Syntax highlighting, hover
|
| 6 |
+
states, accent variants, shadows, tooltips, etc.
|
| 7 |
+
----------------------------------------------------------------------- */
|
| 8 |
+
|
| 9 |
+
:root {
|
| 10 |
+
/* Text variants (editor chrome) */
|
| 11 |
+
--text-heading: var(--neutral-900);
|
| 12 |
+
--text-heading-secondary: #222;
|
| 13 |
+
--text-strong: #000;
|
| 14 |
+
--text-faint: #aaa;
|
| 15 |
+
|
| 16 |
+
/* Background variants (editor chrome) */
|
| 17 |
+
--bg-hover: rgba(0, 0, 0, 0.03);
|
| 18 |
+
--bg-overlay: rgba(0, 0, 0, 0.5);
|
| 19 |
+
--bg-tooltip: #ffffff;
|
| 20 |
+
--bg-code-block: #fafafa;
|
| 21 |
+
|
| 22 |
+
/* Border variants */
|
| 23 |
+
--border-light: #eeeeee;
|
| 24 |
+
--border-focus: rgba(124, 58, 237, 0.5);
|
| 25 |
+
|
| 26 |
+
/* Accent (editor interactive elements - links, citations) */
|
| 27 |
+
--accent: #7c3aed;
|
| 28 |
+
--accent-light: #958DF1;
|
| 29 |
+
--accent-bg: rgba(124, 58, 237, 0.08);
|
| 30 |
+
--accent-bg-hover: rgba(124, 58, 237, 0.15);
|
| 31 |
+
--accent-text: #6d28d9;
|
| 32 |
+
|
| 33 |
+
/* Syntax highlighting (One Dark inspired) */
|
| 34 |
+
--code-text: #d63384;
|
| 35 |
+
--code-comment: #6a737d;
|
| 36 |
+
--code-keyword: #8250df;
|
| 37 |
+
--code-string: #0a6640;
|
| 38 |
+
--code-number: #b35900;
|
| 39 |
+
--code-variable: #d63384;
|
| 40 |
+
--code-type: #b35900;
|
| 41 |
+
--code-function: #0550ae;
|
| 42 |
+
--code-tag: #d63384;
|
| 43 |
+
--code-attr: #b35900;
|
| 44 |
+
--code-symbol: #0a6640;
|
| 45 |
+
--code-meta: #0550ae;
|
| 46 |
+
--code-deletion: #d63384;
|
| 47 |
+
|
| 48 |
+
/* Danger */
|
| 49 |
+
--danger-color: #dc2626;
|
| 50 |
+
--danger-bg: rgba(220, 38, 38, 0.08);
|
| 51 |
+
--danger-bg-hover: rgba(220, 38, 38, 0.15);
|
| 52 |
+
|
| 53 |
+
/* Shadows */
|
| 54 |
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
|
| 55 |
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
|
| 56 |
+
--shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.12);
|
| 57 |
+
|
| 58 |
+
/* KaTeX */
|
| 59 |
+
--katex-color: #1a1a1a;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
[data-theme="dark"] {
|
| 63 |
+
--text-heading: #fff;
|
| 64 |
+
--text-heading-secondary: rgba(255, 255, 255, 0.9);
|
| 65 |
+
--text-strong: rgba(255, 255, 255, 0.95);
|
| 66 |
+
--text-faint: rgba(255, 255, 255, 0.25);
|
| 67 |
+
|
| 68 |
+
--bg-hover: rgba(255, 255, 255, 0.03);
|
| 69 |
+
--bg-overlay: rgba(0, 0, 0, 0.5);
|
| 70 |
+
--bg-tooltip: #1e1e2e;
|
| 71 |
+
--bg-code-block: rgba(255, 255, 255, 0.03);
|
| 72 |
+
|
| 73 |
+
--border-light: rgba(255, 255, 255, 0.06);
|
| 74 |
+
--border-focus: rgba(149, 141, 241, 0.5);
|
| 75 |
+
|
| 76 |
+
--accent: #7c3aed;
|
| 77 |
+
--accent-light: #958DF1;
|
| 78 |
+
--accent-bg: rgba(149, 141, 241, 0.15);
|
| 79 |
+
--accent-bg-hover: rgba(149, 141, 241, 0.25);
|
| 80 |
+
--accent-text: #b4aef7;
|
| 81 |
+
|
| 82 |
+
--code-text: #e06c75;
|
| 83 |
+
--code-comment: #5c6370;
|
| 84 |
+
--code-keyword: #c678dd;
|
| 85 |
+
--code-string: #98c379;
|
| 86 |
+
--code-number: #d19a66;
|
| 87 |
+
--code-variable: #e06c75;
|
| 88 |
+
--code-type: #e5c07b;
|
| 89 |
+
--code-function: #61afef;
|
| 90 |
+
--code-tag: #e06c75;
|
| 91 |
+
--code-attr: #d19a66;
|
| 92 |
+
--code-symbol: #56b6c2;
|
| 93 |
+
--code-meta: #61afef;
|
| 94 |
+
--code-deletion: #e06c75;
|
| 95 |
+
|
| 96 |
+
--danger-color: #e06c75;
|
| 97 |
+
--danger-bg: rgba(224, 108, 117, 0.12);
|
| 98 |
+
--danger-bg-hover: rgba(224, 108, 117, 0.25);
|
| 99 |
+
|
| 100 |
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
|
| 101 |
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
|
| 102 |
+
--shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.5);
|
| 103 |
+
|
| 104 |
+
--katex-color: rgba(255, 255, 255, 0.85);
|
| 105 |
+
}
|
|
@@ -0,0 +1,363 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Layout – 3-column grid (Table of Contents / Article / Aside) */
|
| 3 |
+
/* ============================================================================ */
|
| 4 |
+
|
| 5 |
+
.content-grid {
|
| 6 |
+
max-width: 1280px;
|
| 7 |
+
margin: 0 auto;
|
| 8 |
+
padding: 0 var(--content-padding-x);
|
| 9 |
+
margin-top: 40px;
|
| 10 |
+
display: grid;
|
| 11 |
+
grid-template-columns: 260px minmax(0, 680px) 260px;
|
| 12 |
+
gap: 32px;
|
| 13 |
+
align-items: start;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.content-grid>main {
|
| 17 |
+
max-width: 100%;
|
| 18 |
+
margin: 0;
|
| 19 |
+
padding: 0;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.content-grid>main>*:first-child {
|
| 23 |
+
margin-top: 0;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
@media (--bp-content-collapse) {
|
| 27 |
+
.content-grid {
|
| 28 |
+
overflow: hidden;
|
| 29 |
+
display: block;
|
| 30 |
+
margin-top: var(--spacing-2);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.content-grid {
|
| 34 |
+
grid-template-columns: 1fr;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.table-of-contents {
|
| 38 |
+
position: static;
|
| 39 |
+
display: none;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
.toc-mobile-toggle {
|
| 43 |
+
display: flex;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
.toc-mobile-backdrop {
|
| 47 |
+
display: block;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.toc-mobile-sidebar {
|
| 51 |
+
display: flex;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.footer-inner {
|
| 55 |
+
grid-template-columns: 1fr;
|
| 56 |
+
gap: 16px;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.footer-inner>.footer-heading {
|
| 60 |
+
grid-column: auto;
|
| 61 |
+
margin-top: 16px;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.footer-inner {
|
| 65 |
+
display: block;
|
| 66 |
+
padding: 40px 16px;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
/* ============================================================================ */
|
| 73 |
+
/* Width helpers – slightly wider than main column, and full-width to viewport */
|
| 74 |
+
/* ---------------------------------------------------------------------------- */
|
| 75 |
+
|
| 76 |
+
.wide,
|
| 77 |
+
.full-width {
|
| 78 |
+
box-sizing: border-box;
|
| 79 |
+
position: relative;
|
| 80 |
+
z-index: var(--z-elevated);
|
| 81 |
+
background-color: var(--page-bg);
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.wide {
|
| 85 |
+
/* Target up to ~1100px while staying within viewport minus page gutters */
|
| 86 |
+
width: min(1100px, 100vw - var(--content-padding-x) * 4);
|
| 87 |
+
margin-left: 50%;
|
| 88 |
+
transform: translateX(-50%);
|
| 89 |
+
padding: calc(var(--content-padding-x)*4);
|
| 90 |
+
border-radius: calc(var(--button-radius)*4);
|
| 91 |
+
background-color: var(--page-bg);
|
| 92 |
+
-webkit-mask:
|
| 93 |
+
linear-gradient(to right, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%),
|
| 94 |
+
linear-gradient(to bottom, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%);
|
| 95 |
+
-webkit-mask-composite: intersect;
|
| 96 |
+
mask:
|
| 97 |
+
linear-gradient(to right, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%),
|
| 98 |
+
linear-gradient(to bottom, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%);
|
| 99 |
+
mask-composite: intersect;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.wide>* {
|
| 103 |
+
margin-bottom: 0 !important;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.full-width {
|
| 107 |
+
/* Span the full viewport width and center relative to viewport */
|
| 108 |
+
width: 100vw;
|
| 109 |
+
margin-left: calc(50% - 50vw);
|
| 110 |
+
margin-right: calc(50% - 50vw);
|
| 111 |
+
padding: calc(var(--content-padding-x)*4);
|
| 112 |
+
border-radius: calc(var(--button-radius)*4);
|
| 113 |
+
background-color: var(--page-bg);
|
| 114 |
+
-webkit-mask:
|
| 115 |
+
linear-gradient(to bottom, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%);
|
| 116 |
+
mask:
|
| 117 |
+
linear-gradient(to bottom, transparent 0px, black 20px, black calc(100% - 20px), transparent 100%);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.full-width figure figcaption {
|
| 121 |
+
text-align: center !important;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
@media (--bp-content-collapse) {
|
| 125 |
+
|
| 126 |
+
.wide,
|
| 127 |
+
.full-width {
|
| 128 |
+
width: 100%;
|
| 129 |
+
margin-left: 0;
|
| 130 |
+
margin-right: 0;
|
| 131 |
+
padding: 0;
|
| 132 |
+
transform: none;
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
/* ============================================================================ */
|
| 137 |
+
/* Theme toggle placement */
|
| 138 |
+
/* ============================================================================ */
|
| 139 |
+
|
| 140 |
+
#theme-toggle {
|
| 141 |
+
position: absolute;
|
| 142 |
+
top: var(--spacing-4);
|
| 143 |
+
left: var(--spacing-4);
|
| 144 |
+
margin: 0;
|
| 145 |
+
z-index: var(--z-overlay);
|
| 146 |
+
width: 40px;
|
| 147 |
+
height: 40px;
|
| 148 |
+
border-radius: 50%;
|
| 149 |
+
border: 1px solid var(--border-color);
|
| 150 |
+
background: var(--page-bg);
|
| 151 |
+
box-shadow: 0 2px 12px rgba(0,0,0,.08);
|
| 152 |
+
display: flex;
|
| 153 |
+
align-items: center;
|
| 154 |
+
justify-content: center;
|
| 155 |
+
padding: 0;
|
| 156 |
+
cursor: pointer;
|
| 157 |
+
color: var(--text-color);
|
| 158 |
+
transition: transform 150ms ease, box-shadow 150ms ease;
|
| 159 |
+
}
|
| 160 |
+
#theme-toggle:active {
|
| 161 |
+
transform: scale(0.92);
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
@media (--bp-content-collapse) {
|
| 165 |
+
#theme-toggle {
|
| 166 |
+
display: none;
|
| 167 |
+
}
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
/* ------------------------------------------------------------------------- */
|
| 171 |
+
/* Hero meta bar responsiveness */
|
| 172 |
+
/* Two columns at collapse breakpoint, then one column below small screens */
|
| 173 |
+
/* ------------------------------------------------------------------------- */
|
| 174 |
+
@media (--bp-md) {
|
| 175 |
+
header.meta .meta-container {
|
| 176 |
+
display: flex;
|
| 177 |
+
flex-wrap: wrap;
|
| 178 |
+
row-gap: 12px;
|
| 179 |
+
column-gap: 8px;
|
| 180 |
+
max-width: 100%;
|
| 181 |
+
padding: 0 var(--spacing-4);
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
header.meta .meta-container .meta-container-cell {
|
| 185 |
+
flex: 1 1 calc(50% - 8px);
|
| 186 |
+
min-width: 0;
|
| 187 |
+
}
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
@media (--bp-xxs) {
|
| 191 |
+
header.meta .meta-container .meta-container-cell {
|
| 192 |
+
flex-basis: 100%;
|
| 193 |
+
text-align: center;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
/* Center ordered list numbers within meta (e.g., affiliations) */
|
| 197 |
+
header.meta .affiliations {
|
| 198 |
+
list-style-position: inside;
|
| 199 |
+
padding-left: 0;
|
| 200 |
+
margin-left: 0;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
header.meta .affiliations li {
|
| 204 |
+
text-align: center;
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
/* ------------------------------------------------------------------------- */
|
| 210 |
+
/* D3 neural embed responsiveness */
|
| 211 |
+
/* Stack canvas (left) over network (right) on small screens */
|
| 212 |
+
/* ------------------------------------------------------------------------- */
|
| 213 |
+
@media (--bp-md) {
|
| 214 |
+
.d3-neural .panel {
|
| 215 |
+
flex-direction: column;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
.d3-neural .panel .left {
|
| 219 |
+
flex: 0 0 auto;
|
| 220 |
+
width: 100%;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.d3-neural .panel .right {
|
| 224 |
+
flex: 0 0 auto;
|
| 225 |
+
width: 100%;
|
| 226 |
+
min-width: 0;
|
| 227 |
+
}
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
/* ============================================================================ */
|
| 231 |
+
/* Auto figure numbering */
|
| 232 |
+
/* Applies a CSS counter across all figure-bearing components: */
|
| 233 |
+
/* Reference (.reference-wrapper), Image (.image-wrapper figure), */
|
| 234 |
+
/* and HtmlEmbed (.html-embed) */
|
| 235 |
+
/* ============================================================================ */
|
| 236 |
+
|
| 237 |
+
.content-grid > main {
|
| 238 |
+
counter-reset: figure;
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
/* Increment on every figure-like component */
|
| 242 |
+
.content-grid > main .reference-wrapper,
|
| 243 |
+
.content-grid > main .image-wrapper > figure,
|
| 244 |
+
.content-grid > main figure.html-embed {
|
| 245 |
+
counter-increment: figure;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
/* Display "Figure N · " before each figcaption */
|
| 249 |
+
.content-grid > main .reference-wrapper .reference__caption::before,
|
| 250 |
+
.content-grid > main .image-wrapper > figure > figcaption::before,
|
| 251 |
+
.content-grid > main figure.html-embed > .html-embed__desc::before {
|
| 252 |
+
content: "Figure " counter(figure) " · ";
|
| 253 |
+
font-weight: 600;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
/* ============================================================================ */
|
| 257 |
+
/* "paper" template - academic project-page layout (single centered column) */
|
| 258 |
+
/* Activated by frontmatter `template: "paper"` -> data-template="paper" */
|
| 259 |
+
/* Reference: academic project pages like diffusion-cot.github.io */
|
| 260 |
+
/* ============================================================================ */
|
| 261 |
+
|
| 262 |
+
/* ---- Paper hero banner: placed between meta and content in index.astro ---- */
|
| 263 |
+
|
| 264 |
+
.paper-hero-banner {
|
| 265 |
+
max-width: 920px;
|
| 266 |
+
margin: 32px auto 0;
|
| 267 |
+
padding: 0 16px;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
.paper-hero-banner :global(.html-embed) {
|
| 271 |
+
border-radius: 8px;
|
| 272 |
+
overflow: hidden;
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
.paper-hero-banner :global(.html-embed__card) {
|
| 276 |
+
border-radius: 8px;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
/* Thin separator between banner area and content */
|
| 280 |
+
[data-template="paper"] .paper-hero-banner + .content-grid {
|
| 281 |
+
margin-top: 48px;
|
| 282 |
+
border-top: 1px solid var(--border-color);
|
| 283 |
+
padding-top: 40px;
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
/* When no banner, separator is directly below meta */
|
| 287 |
+
[data-template="paper"] .meta + .content-grid,
|
| 288 |
+
[data-template="paper"] .hero-paper-meta + .content-grid {
|
| 289 |
+
margin-top: 32px;
|
| 290 |
+
border-top: 1px solid var(--border-color);
|
| 291 |
+
padding-top: 40px;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
/* ---- Content grid: single centered column, no TOC ---- */
|
| 295 |
+
|
| 296 |
+
[data-template="paper"] .content-grid {
|
| 297 |
+
grid-template-columns: minmax(0, 780px);
|
| 298 |
+
justify-content: center;
|
| 299 |
+
margin-top: 0;
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
[data-template="paper"] .table-of-contents {
|
| 303 |
+
display: none;
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
/* ---- Typography: clean left-aligned headings ---- */
|
| 307 |
+
|
| 308 |
+
[data-template="paper"] .content-grid > main h2 {
|
| 309 |
+
text-align: left;
|
| 310 |
+
font-size: 1.75em;
|
| 311 |
+
font-weight: 700;
|
| 312 |
+
margin-top: 2.5em;
|
| 313 |
+
margin-bottom: 0.8em;
|
| 314 |
+
border-bottom: none;
|
| 315 |
+
padding-bottom: 0;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
[data-template="paper"] .content-grid > main h2 a {
|
| 319 |
+
background: none;
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
[data-template="paper"] .content-grid > main h2:first-child,
|
| 323 |
+
[data-template="paper"] .content-grid > main > *:first-child h2 {
|
| 324 |
+
margin-top: 0;
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
[data-template="paper"] .content-grid > main h3 {
|
| 328 |
+
font-size: 1.3em;
|
| 329 |
+
font-weight: 600;
|
| 330 |
+
margin-top: 2em;
|
| 331 |
+
margin-bottom: 0.6em;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
/* ---- No figure numbering ---- */
|
| 335 |
+
|
| 336 |
+
[data-template="paper"] .content-grid > main {
|
| 337 |
+
counter-reset: none;
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
[data-template="paper"] .content-grid > main .reference-wrapper .reference__caption::before,
|
| 341 |
+
[data-template="paper"] .content-grid > main .image-wrapper > figure > figcaption::before,
|
| 342 |
+
[data-template="paper"] .content-grid > main figure.html-embed > .html-embed__desc::before {
|
| 343 |
+
content: none;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
/* ---- Footer: simple single-column block layout ---- */
|
| 347 |
+
|
| 348 |
+
[data-template="paper"] .footer-inner {
|
| 349 |
+
display: block;
|
| 350 |
+
max-width: 780px;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
[data-template="paper"] .references-block > .footer-heading,
|
| 354 |
+
[data-template="paper"] .reuse-block > .footer-heading {
|
| 355 |
+
text-align: left;
|
| 356 |
+
padding-right: 0;
|
| 357 |
+
margin-top: 16px;
|
| 358 |
+
margin-bottom: 8px;
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
[data-template="paper"] .template-credit p {
|
| 362 |
+
margin-top: 32px;
|
| 363 |
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Print styles */
|
| 3 |
+
/* ========================================================================= */
|
| 4 |
+
@media print {
|
| 5 |
+
|
| 6 |
+
html,
|
| 7 |
+
body {
|
| 8 |
+
background: #fff;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
/* Margins handled by Playwright; avoid extra global margins */
|
| 12 |
+
body {
|
| 13 |
+
margin: 0;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
/* Keep the banner (hero), hide non-essential UI elements */
|
| 17 |
+
#theme-toggle {
|
| 18 |
+
display: none !important;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
/* Links: remove underline and background */
|
| 22 |
+
.content-grid main a {
|
| 23 |
+
text-decoration: none;
|
| 24 |
+
background: none;
|
| 25 |
+
border-bottom: 1px solid rgba(0, 0, 0, .2);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/* Avoid breaks inside complex blocks */
|
| 29 |
+
.content-grid main pre,
|
| 30 |
+
.content-grid main blockquote,
|
| 31 |
+
.content-grid main table,
|
| 32 |
+
.content-grid main figure {
|
| 33 |
+
break-inside: avoid;
|
| 34 |
+
page-break-inside: avoid;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/* Soft page breaks around main headings */
|
| 38 |
+
.content-grid main h2 {
|
| 39 |
+
page-break-before: auto;
|
| 40 |
+
page-break-after: avoid;
|
| 41 |
+
break-after: avoid-page;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/* Small icon labels not needed when printing */
|
| 45 |
+
.code-lang-chip {
|
| 46 |
+
display: none !important;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
/* Adjust more contrasty colors for print */
|
| 50 |
+
:root {
|
| 51 |
+
--surface-bg: #fff;
|
| 52 |
+
--border-color: rgba(0, 0, 0, .2);
|
| 53 |
+
--link-underline: rgba(0, 0, 0, .3);
|
| 54 |
+
--link-underline-hover: rgba(0, 0, 0, .4);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
/* Force single column to reduce widows/orphans and awkward breaks */
|
| 58 |
+
.content-grid {
|
| 59 |
+
grid-template-columns: 1fr !important;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.table-of-contents,
|
| 63 |
+
.right-aside,
|
| 64 |
+
.toc-mobile-toggle,
|
| 65 |
+
.toc-mobile-backdrop,
|
| 66 |
+
.toc-mobile-sidebar {
|
| 67 |
+
display: none !important;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
main>nav:first-of-type {
|
| 71 |
+
display: none !important;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/* Avoid page breaks inside complex visual blocks */
|
| 75 |
+
.hero,
|
| 76 |
+
.hero-banner,
|
| 77 |
+
.html-embed__card,
|
| 78 |
+
.js-plotly-plot,
|
| 79 |
+
figure,
|
| 80 |
+
pre,
|
| 81 |
+
table,
|
| 82 |
+
blockquote,
|
| 83 |
+
.wide,
|
| 84 |
+
.full-width,
|
| 85 |
+
.stack > *,
|
| 86 |
+
.card,
|
| 87 |
+
.palettes,
|
| 88 |
+
.palette-card,
|
| 89 |
+
.color-picker,
|
| 90 |
+
.note {
|
| 91 |
+
break-inside: avoid;
|
| 92 |
+
page-break-inside: avoid;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
/* Prefer keeping header+lead together */
|
| 96 |
+
.hero {
|
| 97 |
+
page-break-after: avoid;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
/* Center the hero banner and constrain all its children generically */
|
| 101 |
+
.hero-banner {
|
| 102 |
+
width: 100% !important;
|
| 103 |
+
max-width: 980px !important;
|
| 104 |
+
margin-left: auto !important;
|
| 105 |
+
margin-right: auto !important;
|
| 106 |
+
overflow: hidden;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.hero-banner > *,
|
| 110 |
+
.hero-banner svg,
|
| 111 |
+
.hero-banner canvas,
|
| 112 |
+
.hero-banner img,
|
| 113 |
+
.hero-banner video {
|
| 114 |
+
max-width: 100% !important;
|
| 115 |
+
width: 100% !important;
|
| 116 |
+
height: auto !important;
|
| 117 |
+
margin-left: auto !important;
|
| 118 |
+
margin-right: auto !important;
|
| 119 |
+
display: block;
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
@media print {
|
| 125 |
+
.meta-container-cell--pdf {
|
| 126 |
+
display: none !important;
|
| 127 |
+
}
|
| 128 |
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
html { box-sizing: border-box; }
|
| 2 |
+
*, *::before, *::after { box-sizing: inherit; }
|
| 3 |
+
body { margin: 0; }
|
| 4 |
+
audio { display: block; width: 100%; }
|
| 5 |
+
|
| 6 |
+
img,
|
| 7 |
+
picture {
|
| 8 |
+
max-width: 100%;
|
| 9 |
+
height: auto;
|
| 10 |
+
display: block;
|
| 11 |
+
position: relative;
|
| 12 |
+
z-index: var(--z-elevated);
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
/*
|
| 16 |
+
* Article-specific font and color are scoped to the article area
|
| 17 |
+
* to avoid overriding MUI theme on portals (Dialog, Menu, Tooltip).
|
| 18 |
+
* The template's original `body { font-family; color }` is moved here.
|
| 19 |
+
*/
|
| 20 |
+
.content-grid,
|
| 21 |
+
.hero,
|
| 22 |
+
.meta {
|
| 23 |
+
font-family: var(--default-font-family);
|
| 24 |
+
color: var(--text-color);
|
| 25 |
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Design Tokens */
|
| 3 |
+
/* ============================================================================ */
|
| 4 |
+
:root {
|
| 5 |
+
/* Neutrals */
|
| 6 |
+
--neutral-900: rgb(17, 24, 39);
|
| 7 |
+
--neutral-600: rgb(107, 114, 128);
|
| 8 |
+
--neutral-400: rgb(185, 185, 185);
|
| 9 |
+
--neutral-300: rgb(228, 228, 228);
|
| 10 |
+
--neutral-200: rgb(245, 245, 245);
|
| 11 |
+
--neutral-50: rgb(249, 250, 251);
|
| 12 |
+
|
| 13 |
+
--default-font-family: Source Sans Pro, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
| 14 |
+
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
| 15 |
+
|
| 16 |
+
/* Brand (OKLCH base + derived states) */
|
| 17 |
+
--primary-base: oklch(0.75 0.12 47);
|
| 18 |
+
--primary-color: var(--primary-base);
|
| 19 |
+
--primary-color-hover: oklch(from var(--primary-color) calc(l - 0.05) c h);
|
| 20 |
+
--primary-color-active: oklch(from var(--primary-color) calc(l - 0.10) c h);
|
| 21 |
+
--on-primary: #ffffff;
|
| 22 |
+
|
| 23 |
+
/* Semantic colors */
|
| 24 |
+
--danger-color: oklch(0.65 0.19 25);
|
| 25 |
+
--success-color: oklch(0.65 0.15 145);
|
| 26 |
+
--info-color: oklch(0.65 0.12 230);
|
| 27 |
+
|
| 28 |
+
/* Text & Surfaces */
|
| 29 |
+
--page-bg: #fff;
|
| 30 |
+
--surface-bg: #f9f9f9;
|
| 31 |
+
--text-color: rgba(0, 0, 0, .85);
|
| 32 |
+
--transparent-page-contrast: rgba(255, 255, 255, .85);
|
| 33 |
+
--muted-color: rgba(0, 0, 0, .6);
|
| 34 |
+
--border-color: rgba(0, 0, 0, .1);
|
| 35 |
+
--code-bg: #f6f8fa;
|
| 36 |
+
|
| 37 |
+
/* Links */
|
| 38 |
+
--link-underline: var(--primary-color);
|
| 39 |
+
--link-underline-hover: var(--primary-color-hover);
|
| 40 |
+
|
| 41 |
+
/* Spacing scale */
|
| 42 |
+
--spacing-1: 8px;
|
| 43 |
+
--spacing-2: 12px;
|
| 44 |
+
--spacing-3: 16px;
|
| 45 |
+
--spacing-4: 24px;
|
| 46 |
+
--spacing-5: 32px;
|
| 47 |
+
--spacing-6: 40px;
|
| 48 |
+
--spacing-7: 48px;
|
| 49 |
+
--spacing-8: 56px;
|
| 50 |
+
--spacing-9: 64px;
|
| 51 |
+
--spacing-10: 72px;
|
| 52 |
+
|
| 53 |
+
/* Custom Media aliases compiled by PostCSS */
|
| 54 |
+
@custom-media --bp-xxs (max-width: 320px);
|
| 55 |
+
@custom-media --bp-xs (max-width: 480px);
|
| 56 |
+
@custom-media --bp-sm (max-width: 640px);
|
| 57 |
+
@custom-media --bp-md (max-width: 768px);
|
| 58 |
+
@custom-media --bp-lg (max-width: 1024px);
|
| 59 |
+
@custom-media --bp-xl (max-width: 1280px);
|
| 60 |
+
@custom-media --bp-content-collapse (max-width: 1100px);
|
| 61 |
+
|
| 62 |
+
/* Layout */
|
| 63 |
+
--content-padding-x: 16px;
|
| 64 |
+
/* default page gutter */
|
| 65 |
+
--block-spacing-y: var(--spacing-4);
|
| 66 |
+
/* default vertical spacing between block components */
|
| 67 |
+
|
| 68 |
+
/* Config */
|
| 69 |
+
--palette-count: 8;
|
| 70 |
+
|
| 71 |
+
/* Button tokens */
|
| 72 |
+
--button-radius: 6px;
|
| 73 |
+
--button-padding-x: 16px;
|
| 74 |
+
--button-padding-y: 10px;
|
| 75 |
+
--button-font-size: 14px;
|
| 76 |
+
--button-icon-padding: 8px;
|
| 77 |
+
/* Big button */
|
| 78 |
+
--button-big-padding-x: 16px;
|
| 79 |
+
--button-big-padding-y: 12px;
|
| 80 |
+
--button-big-font-size: 16px;
|
| 81 |
+
--button-big-icon-padding: 12px;
|
| 82 |
+
|
| 83 |
+
/* Table tokens */
|
| 84 |
+
--table-border-radius: 8px;
|
| 85 |
+
--table-header-bg: oklch(from var(--surface-bg) calc(l - 0.02) c h);
|
| 86 |
+
--table-row-odd-bg: oklch(from var(--surface-bg) calc(l - 0.01) c h);
|
| 87 |
+
|
| 88 |
+
/* Z-index */
|
| 89 |
+
--z-base: 0;
|
| 90 |
+
--z-content: 1;
|
| 91 |
+
--z-elevated: 10;
|
| 92 |
+
--z-overlay: 1000;
|
| 93 |
+
--z-modal: 1100;
|
| 94 |
+
--z-tooltip: 1200;
|
| 95 |
+
|
| 96 |
+
/* Charts (global) */
|
| 97 |
+
--axis-color: var(--muted-color);
|
| 98 |
+
--tick-color: var(--text-color);
|
| 99 |
+
--grid-color: rgba(0, 0, 0, .08);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
/* ============================================================================ */
|
| 103 |
+
/* Dark Theme Overrides */
|
| 104 |
+
/* ============================================================================ */
|
| 105 |
+
[data-theme="dark"] {
|
| 106 |
+
--page-bg: #0f1115;
|
| 107 |
+
--surface-bg: #07080a;
|
| 108 |
+
--text-color: rgba(255, 255, 255, .9);
|
| 109 |
+
--muted-color: rgba(255, 255, 255, .7);
|
| 110 |
+
--border-color: rgba(255, 255, 255, .15);
|
| 111 |
+
--code-bg: #12151b;
|
| 112 |
+
--transparent-page-contrast: rgba(0, 0, 0, .85);
|
| 113 |
+
|
| 114 |
+
/* Charts (global) */
|
| 115 |
+
--axis-color: var(--muted-color);
|
| 116 |
+
--tick-color: var(--muted-color);
|
| 117 |
+
--grid-color: rgba(255, 255, 255, .10);
|
| 118 |
+
|
| 119 |
+
/* Primary (lower L in dark) */
|
| 120 |
+
--primary-color-hover: oklch(from var(--primary-color) calc(l - 0.05) c h);
|
| 121 |
+
--primary-color-active: oklch(from var(--primary-color) calc(l - 0.10) c h);
|
| 122 |
+
--on-primary: #0f1115;
|
| 123 |
+
|
| 124 |
+
color-scheme: dark;
|
| 125 |
+
background: var(--page-bg);
|
| 126 |
+
}
|
|
@@ -8,10 +8,10 @@
|
|
| 8 |
/* Base typography */
|
| 9 |
.tiptap {
|
| 10 |
outline: none;
|
| 11 |
-
font-family: -
|
| 12 |
font-size: 1rem;
|
| 13 |
line-height: 1.7;
|
| 14 |
-
color: var(--text-
|
| 15 |
max-width: 780px;
|
| 16 |
margin-left: auto;
|
| 17 |
margin-right: auto;
|
|
@@ -51,7 +51,7 @@
|
|
| 51 |
.tiptap h3 {
|
| 52 |
font-size: 1.2rem;
|
| 53 |
font-weight: 600;
|
| 54 |
-
color: var(--text-
|
| 55 |
line-height: 1.4;
|
| 56 |
margin: 1.5em 0 0.3em;
|
| 57 |
}
|
|
@@ -78,10 +78,10 @@
|
|
| 78 |
|
| 79 |
/* Blockquote */
|
| 80 |
.tiptap blockquote {
|
| 81 |
-
border-left: 3px solid var(--border);
|
| 82 |
padding-left: 1rem;
|
| 83 |
margin: 1em 0;
|
| 84 |
-
color: var(--
|
| 85 |
}
|
| 86 |
|
| 87 |
.tiptap blockquote p {
|
|
@@ -91,7 +91,7 @@
|
|
| 91 |
/* Inline code */
|
| 92 |
.tiptap code {
|
| 93 |
font-family: "SFMono-Regular", "Fira Code", "Fira Mono", Menlo, Consolas, monospace;
|
| 94 |
-
background: var(--
|
| 95 |
padding: 0.15em 0.4em;
|
| 96 |
border-radius: 4px;
|
| 97 |
font-size: 0.88em;
|
|
@@ -111,7 +111,7 @@
|
|
| 111 |
.tiptap pre code {
|
| 112 |
background: none;
|
| 113 |
padding: 0;
|
| 114 |
-
color: var(--
|
| 115 |
font-size: 0.875rem;
|
| 116 |
line-height: 1.6;
|
| 117 |
}
|
|
@@ -196,7 +196,7 @@
|
|
| 196 |
/* Horizontal rule */
|
| 197 |
.tiptap hr {
|
| 198 |
border: none;
|
| 199 |
-
border-top: 1px solid var(--border);
|
| 200 |
margin: 2em 0;
|
| 201 |
}
|
| 202 |
|
|
@@ -220,8 +220,8 @@
|
|
| 220 |
}
|
| 221 |
|
| 222 |
.tiptap th {
|
| 223 |
-
background: var(--
|
| 224 |
-
color: var(--
|
| 225 |
font-weight: 600;
|
| 226 |
font-size: 0.8125rem;
|
| 227 |
text-transform: uppercase;
|
|
@@ -229,26 +229,27 @@
|
|
| 229 |
}
|
| 230 |
|
| 231 |
.tiptap td {
|
| 232 |
-
color: var(--text-
|
| 233 |
}
|
| 234 |
|
| 235 |
.tiptap tr:hover td {
|
| 236 |
background: var(--bg-hover);
|
| 237 |
}
|
| 238 |
|
| 239 |
-
/* Links */
|
| 240 |
.tiptap a,
|
| 241 |
.tiptap .editor-link {
|
| 242 |
-
color: var(--
|
| 243 |
-
text-decoration:
|
| 244 |
-
|
| 245 |
text-underline-offset: 2px;
|
| 246 |
-
transition:
|
| 247 |
}
|
| 248 |
|
| 249 |
.tiptap a:hover,
|
| 250 |
.tiptap .editor-link:hover {
|
| 251 |
-
|
|
|
|
| 252 |
}
|
| 253 |
|
| 254 |
/* Bold */
|
|
@@ -273,7 +274,7 @@
|
|
| 273 |
}
|
| 274 |
|
| 275 |
.tiptap [data-type="inline-math"] .tiptap-mathematics-render:hover {
|
| 276 |
-
background: var(--
|
| 277 |
}
|
| 278 |
|
| 279 |
/* Math - block */
|
|
@@ -322,7 +323,7 @@
|
|
| 322 |
left: 50%;
|
| 323 |
transform: translateX(-50%);
|
| 324 |
background: var(--bg-tooltip);
|
| 325 |
-
border: 1px solid var(--border);
|
| 326 |
border-radius: 8px;
|
| 327 |
padding: 0.75rem;
|
| 328 |
min-width: 240px;
|
|
@@ -342,7 +343,7 @@
|
|
| 342 |
}
|
| 343 |
|
| 344 |
.citation-tooltip-journal {
|
| 345 |
-
color: var(--
|
| 346 |
font-size: 0.75rem;
|
| 347 |
font-style: italic;
|
| 348 |
line-height: 1.3;
|
|
@@ -380,7 +381,7 @@
|
|
| 380 |
.bibliography-block {
|
| 381 |
margin: 2em 0 1em;
|
| 382 |
padding-top: 1.5em;
|
| 383 |
-
border-top: 1px solid var(--border);
|
| 384 |
}
|
| 385 |
|
| 386 |
.bibliography-title {
|
|
@@ -399,7 +400,7 @@
|
|
| 399 |
.bibliography-content {
|
| 400 |
font-size: 0.875rem;
|
| 401 |
line-height: 1.7;
|
| 402 |
-
color: var(--
|
| 403 |
}
|
| 404 |
|
| 405 |
.bibliography-content .csl-entry {
|
|
@@ -436,7 +437,7 @@
|
|
| 436 |
left: 50%;
|
| 437 |
transform: translateX(-50%);
|
| 438 |
background: var(--bg-tooltip);
|
| 439 |
-
border: 1px solid var(--border);
|
| 440 |
border-radius: 8px;
|
| 441 |
padding: 10px 14px;
|
| 442 |
min-width: 200px;
|
|
@@ -454,7 +455,7 @@
|
|
| 454 |
|
| 455 |
.glossary-tooltip-def {
|
| 456 |
font-size: 12px;
|
| 457 |
-
color: var(--
|
| 458 |
line-height: 1.5;
|
| 459 |
}
|
| 460 |
|
|
@@ -493,7 +494,7 @@
|
|
| 493 |
left: 50%;
|
| 494 |
transform: translateX(-50%);
|
| 495 |
background: var(--bg-tooltip);
|
| 496 |
-
border: 1px solid var(--border);
|
| 497 |
border-radius: 8px;
|
| 498 |
padding: 10px 14px;
|
| 499 |
min-width: 220px;
|
|
@@ -504,7 +505,7 @@
|
|
| 504 |
|
| 505 |
.footnote-tooltip-content {
|
| 506 |
font-size: 12px;
|
| 507 |
-
color: var(--
|
| 508 |
line-height: 1.5;
|
| 509 |
}
|
| 510 |
|
|
|
|
| 8 |
/* Base typography */
|
| 9 |
.tiptap {
|
| 10 |
outline: none;
|
| 11 |
+
font-family: var(--default-font-family);
|
| 12 |
font-size: 1rem;
|
| 13 |
line-height: 1.7;
|
| 14 |
+
color: var(--text-color);
|
| 15 |
max-width: 780px;
|
| 16 |
margin-left: auto;
|
| 17 |
margin-right: auto;
|
|
|
|
| 51 |
.tiptap h3 {
|
| 52 |
font-size: 1.2rem;
|
| 53 |
font-weight: 600;
|
| 54 |
+
color: var(--text-color);
|
| 55 |
line-height: 1.4;
|
| 56 |
margin: 1.5em 0 0.3em;
|
| 57 |
}
|
|
|
|
| 78 |
|
| 79 |
/* Blockquote */
|
| 80 |
.tiptap blockquote {
|
| 81 |
+
border-left: 3px solid var(--border-color);
|
| 82 |
padding-left: 1rem;
|
| 83 |
margin: 1em 0;
|
| 84 |
+
color: var(--muted-color);
|
| 85 |
}
|
| 86 |
|
| 87 |
.tiptap blockquote p {
|
|
|
|
| 91 |
/* Inline code */
|
| 92 |
.tiptap code {
|
| 93 |
font-family: "SFMono-Regular", "Fira Code", "Fira Mono", Menlo, Consolas, monospace;
|
| 94 |
+
background: var(--code-bg);
|
| 95 |
padding: 0.15em 0.4em;
|
| 96 |
border-radius: 4px;
|
| 97 |
font-size: 0.88em;
|
|
|
|
| 111 |
.tiptap pre code {
|
| 112 |
background: none;
|
| 113 |
padding: 0;
|
| 114 |
+
color: var(--muted-color);
|
| 115 |
font-size: 0.875rem;
|
| 116 |
line-height: 1.6;
|
| 117 |
}
|
|
|
|
| 196 |
/* Horizontal rule */
|
| 197 |
.tiptap hr {
|
| 198 |
border: none;
|
| 199 |
+
border-top: 1px solid var(--border-color);
|
| 200 |
margin: 2em 0;
|
| 201 |
}
|
| 202 |
|
|
|
|
| 220 |
}
|
| 221 |
|
| 222 |
.tiptap th {
|
| 223 |
+
background: var(--code-bg);
|
| 224 |
+
color: var(--muted-color);
|
| 225 |
font-weight: 600;
|
| 226 |
font-size: 0.8125rem;
|
| 227 |
text-transform: uppercase;
|
|
|
|
| 229 |
}
|
| 230 |
|
| 231 |
.tiptap td {
|
| 232 |
+
color: var(--text-color);
|
| 233 |
}
|
| 234 |
|
| 235 |
.tiptap tr:hover td {
|
| 236 |
background: var(--bg-hover);
|
| 237 |
}
|
| 238 |
|
| 239 |
+
/* Links - aligned with template (_base.css .content-grid main a) */
|
| 240 |
.tiptap a,
|
| 241 |
.tiptap .editor-link {
|
| 242 |
+
color: var(--primary-color);
|
| 243 |
+
text-decoration: none;
|
| 244 |
+
border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
|
| 245 |
text-underline-offset: 2px;
|
| 246 |
+
transition: border-color 0.15s;
|
| 247 |
}
|
| 248 |
|
| 249 |
.tiptap a:hover,
|
| 250 |
.tiptap .editor-link:hover {
|
| 251 |
+
color: var(--primary-color-hover);
|
| 252 |
+
border-bottom-color: color-mix(in srgb, var(--primary-color) 70%, transparent);
|
| 253 |
}
|
| 254 |
|
| 255 |
/* Bold */
|
|
|
|
| 274 |
}
|
| 275 |
|
| 276 |
.tiptap [data-type="inline-math"] .tiptap-mathematics-render:hover {
|
| 277 |
+
background: var(--code-bg);
|
| 278 |
}
|
| 279 |
|
| 280 |
/* Math - block */
|
|
|
|
| 323 |
left: 50%;
|
| 324 |
transform: translateX(-50%);
|
| 325 |
background: var(--bg-tooltip);
|
| 326 |
+
border: 1px solid var(--border-color);
|
| 327 |
border-radius: 8px;
|
| 328 |
padding: 0.75rem;
|
| 329 |
min-width: 240px;
|
|
|
|
| 343 |
}
|
| 344 |
|
| 345 |
.citation-tooltip-journal {
|
| 346 |
+
color: var(--muted-color);
|
| 347 |
font-size: 0.75rem;
|
| 348 |
font-style: italic;
|
| 349 |
line-height: 1.3;
|
|
|
|
| 381 |
.bibliography-block {
|
| 382 |
margin: 2em 0 1em;
|
| 383 |
padding-top: 1.5em;
|
| 384 |
+
border-top: 1px solid var(--border-color);
|
| 385 |
}
|
| 386 |
|
| 387 |
.bibliography-title {
|
|
|
|
| 400 |
.bibliography-content {
|
| 401 |
font-size: 0.875rem;
|
| 402 |
line-height: 1.7;
|
| 403 |
+
color: var(--muted-color);
|
| 404 |
}
|
| 405 |
|
| 406 |
.bibliography-content .csl-entry {
|
|
|
|
| 437 |
left: 50%;
|
| 438 |
transform: translateX(-50%);
|
| 439 |
background: var(--bg-tooltip);
|
| 440 |
+
border: 1px solid var(--border-color);
|
| 441 |
border-radius: 8px;
|
| 442 |
padding: 10px 14px;
|
| 443 |
min-width: 200px;
|
|
|
|
| 455 |
|
| 456 |
.glossary-tooltip-def {
|
| 457 |
font-size: 12px;
|
| 458 |
+
color: var(--muted-color);
|
| 459 |
line-height: 1.5;
|
| 460 |
}
|
| 461 |
|
|
|
|
| 494 |
left: 50%;
|
| 495 |
transform: translateX(-50%);
|
| 496 |
background: var(--bg-tooltip);
|
| 497 |
+
border: 1px solid var(--border-color);
|
| 498 |
border-radius: 8px;
|
| 499 |
padding: 10px 14px;
|
| 500 |
min-width: 220px;
|
|
|
|
| 505 |
|
| 506 |
.footnote-tooltip-content {
|
| 507 |
font-size: 12px;
|
| 508 |
+
color: var(--muted-color);
|
| 509 |
line-height: 1.5;
|
| 510 |
}
|
| 511 |
|
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
button, .button {
|
| 2 |
+
appearance: none;
|
| 3 |
+
background: linear-gradient(15deg, var(--primary-color) 0%, var(--primary-color-hover) 35%);
|
| 4 |
+
color: white;
|
| 5 |
+
border: 1px solid transparent;
|
| 6 |
+
border-radius: var(--button-radius);
|
| 7 |
+
padding: var(--button-padding-y) var(--button-padding-x);
|
| 8 |
+
font-size: var(--button-font-size);
|
| 9 |
+
line-height: 1;
|
| 10 |
+
cursor: pointer;
|
| 11 |
+
display: inline-block;
|
| 12 |
+
text-decoration: none;
|
| 13 |
+
transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease, transform .02s ease;
|
| 14 |
+
}
|
| 15 |
+
/* Icon-only buttons: equal X/Y padding */
|
| 16 |
+
button:has(> svg:only-child),
|
| 17 |
+
.button:has(> svg:only-child) {
|
| 18 |
+
padding: var(--button-icon-padding);
|
| 19 |
+
}
|
| 20 |
+
button:hover, .button:hover {
|
| 21 |
+
filter: brightness(96%);
|
| 22 |
+
}
|
| 23 |
+
button:active, .button:active {
|
| 24 |
+
transform: translateY(1px);
|
| 25 |
+
}
|
| 26 |
+
button:focus-visible, .button:focus-visible {
|
| 27 |
+
outline: none;
|
| 28 |
+
}
|
| 29 |
+
button:disabled, .button:disabled {
|
| 30 |
+
opacity: .6;
|
| 31 |
+
cursor: not-allowed;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* Ghost/Muted button: subtle outline, primary color text/border */
|
| 35 |
+
.button--ghost {
|
| 36 |
+
background: transparent !important;
|
| 37 |
+
color: var(--primary-color) !important;
|
| 38 |
+
border-color: var(--primary-color) !important;
|
| 39 |
+
}
|
| 40 |
+
.button--ghost:hover {
|
| 41 |
+
color: var(--primary-color-hover) !important;
|
| 42 |
+
border-color: var(--primary-color-hover) !important;
|
| 43 |
+
filter: none;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
/* Big button: larger padding and font size */
|
| 47 |
+
.button.button--big {
|
| 48 |
+
padding: var(--button-big-padding-y) var(--button-big-padding-x);
|
| 49 |
+
font-size: var(--button-big-font-size);
|
| 50 |
+
}
|
| 51 |
+
.button.button--big:has(> svg:only-child) {
|
| 52 |
+
padding: var(--button-big-icon-padding);
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.button-group .button {
|
| 56 |
+
margin: 5px;
|
| 57 |
+
}
|
| 58 |
+
|
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.card {
|
| 2 |
+
background: var(--surface-bg);
|
| 3 |
+
border: 1px solid var(--border-color) !important;
|
| 4 |
+
border-radius: 12px;
|
| 5 |
+
padding: var(--spacing-3);
|
| 6 |
+
z-index: calc(var(--z-elevated) + 1);
|
| 7 |
+
position: relative;
|
| 8 |
+
margin-bottom: 0;
|
| 9 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
| 10 |
+
transition: all 0.2s ease;
|
| 11 |
+
overflow: hidden;
|
| 12 |
+
text-decoration: none;
|
| 13 |
+
color: inherit;
|
| 14 |
+
display: block;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.card:hover {
|
| 18 |
+
text-decoration: none;
|
| 19 |
+
color: inherit;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.card.no-padding,
|
| 23 |
+
.card.card--p0 {
|
| 24 |
+
padding: 0;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
.card:hover {
|
| 28 |
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
.card figcaption {
|
| 33 |
+
color: var(--text-color) !important;
|
| 34 |
+
font-weight: 600 !important;
|
| 35 |
+
font-size: 1rem !important;
|
| 36 |
+
text-align: center !important;
|
| 37 |
+
padding: var(--spacing-3) !important;
|
| 38 |
+
margin: 0 !important;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
.card .image-wrapper,
|
| 42 |
+
.card .image-wrapper figure {
|
| 43 |
+
margin: 0 !important;
|
| 44 |
+
width: 100% !important;
|
| 45 |
+
display: block !important;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.card img {
|
| 49 |
+
border-radius: 8px 8px 0 0 !important;
|
| 50 |
+
width: 100% !important;
|
| 51 |
+
max-width: 100% !important;
|
| 52 |
+
height: 120px !important;
|
| 53 |
+
object-fit: cover !important;
|
| 54 |
+
display: block !important;
|
| 55 |
+
border-bottom: 1px solid var(--border-color) !important;
|
| 56 |
+
transition: all 0.2s ease;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.card.template-card img {
|
| 60 |
+
height: auto !important;
|
| 61 |
+
object-fit: contain !important;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
.card h3,
|
| 66 |
+
.card h4,
|
| 67 |
+
.card h5 {
|
| 68 |
+
margin-top: 0 !important;
|
| 69 |
+
font-weight: 900 !important;
|
| 70 |
+
width: 100%;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.card::after {
|
| 74 |
+
display: none !important;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.card-title-container {
|
| 78 |
+
padding: var(--spacing-3) var(--spacing-4) var(--spacing-4) var(--spacing-4);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.card-title {
|
| 82 |
+
color: var(--text-color);
|
| 83 |
+
font-size: 0.9rem;
|
| 84 |
+
margin: 0 0 var(--spacing-1) 0 !important;
|
| 85 |
+
font-weight: 600;
|
| 86 |
+
line-height: 1.4;
|
| 87 |
+
white-space: normal;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.card-subtitle {
|
| 91 |
+
color: var(--muted-color);
|
| 92 |
+
font-size: 0.75rem;
|
| 93 |
+
margin: 0 !important;
|
| 94 |
+
line-height: 1.5;
|
| 95 |
+
white-space: normal;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.card-cta {
|
| 99 |
+
flex: 1;
|
| 100 |
+
min-width: 0;
|
| 101 |
+
display: flex;
|
| 102 |
+
align-items: center;
|
| 103 |
+
justify-content: center;
|
| 104 |
+
background: var(--surface-bg);
|
| 105 |
+
border: 2px dashed var(--border-color) !important;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
.card-cta:hover {
|
| 109 |
+
transform: none;
|
| 110 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
| 111 |
+
border: 2px dashed var(--border-color) !important;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.card-cta-content {
|
| 115 |
+
text-align: center;
|
| 116 |
+
padding: var(--spacing-4);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.card-cta h3,
|
| 120 |
+
.card-cta h4,
|
| 121 |
+
.card-cta h5 {
|
| 122 |
+
color: var(--text-color);
|
| 123 |
+
font-weight: 900 !important;
|
| 124 |
+
margin-bottom: var(--spacing-1) !important;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.card-cta p {
|
| 128 |
+
color: var(--muted-color);
|
| 129 |
+
font-size: 0.9rem;
|
| 130 |
+
margin: 0 !important;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
@media print {
|
| 134 |
+
.card,
|
| 135 |
+
.card-cta {
|
| 136 |
+
box-shadow: none;
|
| 137 |
+
}
|
| 138 |
+
}
|
|
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Inline code */
|
| 3 |
+
/* ============================================================================ */
|
| 4 |
+
code {
|
| 5 |
+
font-size: 14px;
|
| 6 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
| 7 |
+
border-radius: 0.3em;
|
| 8 |
+
border: 1px solid var(--border-color);
|
| 9 |
+
color: var(--text-color);
|
| 10 |
+
font-weight: 400;
|
| 11 |
+
line-height: 1.5;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
p code,
|
| 15 |
+
.note code {
|
| 16 |
+
white-space: nowrap;
|
| 17 |
+
padding: calc(var(--spacing-1)/3) calc(var(--spacing-1)/2);
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
/* ============================================================================ */
|
| 22 |
+
/* Shiki code blocks */
|
| 23 |
+
/* ============================================================================ */
|
| 24 |
+
.astro-code {
|
| 25 |
+
position: relative;
|
| 26 |
+
border: 1px solid var(--border-color);
|
| 27 |
+
background-color: var(--surface-bg) !important;
|
| 28 |
+
border-radius: 6px;
|
| 29 |
+
padding: 0;
|
| 30 |
+
font-size: 14px;
|
| 31 |
+
--code-gutter-width: 2.5em;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* Shared sizing & horizontal scroll for code containers */
|
| 35 |
+
.astro-code,
|
| 36 |
+
section.content-grid pre {
|
| 37 |
+
width: 100%;
|
| 38 |
+
max-width: 100%;
|
| 39 |
+
box-sizing: border-box;
|
| 40 |
+
-webkit-overflow-scrolling: touch;
|
| 41 |
+
padding: 0;
|
| 42 |
+
margin-bottom: var(--block-spacing-y) !important;
|
| 43 |
+
overflow-x: auto;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
section.content-grid pre.astro-code {
|
| 47 |
+
margin: 0;
|
| 48 |
+
padding: var(--spacing-1) 0;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
section.content-grid pre code {
|
| 52 |
+
display: inline-block;
|
| 53 |
+
min-width: 100%;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
/* Plain-text blocks: always wrap lines (prompts, prose, etc.) */
|
| 57 |
+
.astro-code[data-language="text"] {
|
| 58 |
+
white-space: pre-wrap;
|
| 59 |
+
overflow-wrap: anywhere;
|
| 60 |
+
word-break: break-word;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.astro-code[data-language="text"] .line {
|
| 64 |
+
display: block;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
/* Wrap long lines only on small screens to prevent layout overflow */
|
| 68 |
+
@media (--bp-content-collapse) {
|
| 69 |
+
|
| 70 |
+
.astro-code,
|
| 71 |
+
section.content-grid pre {
|
| 72 |
+
white-space: pre-wrap;
|
| 73 |
+
overflow-wrap: anywhere;
|
| 74 |
+
word-break: break-word;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
section.content-grid pre code {
|
| 78 |
+
white-space: pre-wrap;
|
| 79 |
+
display: block;
|
| 80 |
+
min-width: 0;
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
/* Themes */
|
| 85 |
+
[data-theme='light'] .astro-code {
|
| 86 |
+
background-color: var(--code-bg);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/* Apply token color from per-span vars exposed by Shiki dual themes */
|
| 90 |
+
[data-theme='light'] .astro-code span {
|
| 91 |
+
color: var(--shiki-light) !important;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
[data-theme='dark'] .astro-code span {
|
| 95 |
+
color: var(--shiki-dark) !important;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/* Optional: boost contrast for light theme */
|
| 99 |
+
[data-theme='light'] .astro-code {
|
| 100 |
+
--shiki-foreground: #24292f;
|
| 101 |
+
--shiki-background: #ffffff;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
/* Line numbers for Shiki-rendered code blocks */
|
| 105 |
+
.astro-code code {
|
| 106 |
+
counter-reset: astro-code-line;
|
| 107 |
+
display: block;
|
| 108 |
+
background: none;
|
| 109 |
+
border: none;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.astro-code .line {
|
| 113 |
+
display: inline-block;
|
| 114 |
+
position: relative;
|
| 115 |
+
padding-left: calc(var(--code-gutter-width) + var(--spacing-1));
|
| 116 |
+
min-height: 1.25em;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.astro-code .line::before {
|
| 120 |
+
counter-increment: astro-code-line;
|
| 121 |
+
content: counter(astro-code-line);
|
| 122 |
+
position: absolute;
|
| 123 |
+
left: 0;
|
| 124 |
+
top: 0;
|
| 125 |
+
bottom: 0;
|
| 126 |
+
width: calc(var(--code-gutter-width));
|
| 127 |
+
text-align: right;
|
| 128 |
+
color: var(--muted-color);
|
| 129 |
+
opacity: .3;
|
| 130 |
+
user-select: none;
|
| 131 |
+
padding-right: var(--spacing-2);
|
| 132 |
+
border-right: 1px solid var(--border-color);
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
.astro-code .line:empty::after {
|
| 136 |
+
content: "\00a0";
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
/* Hide trailing empty line added by parsers */
|
| 140 |
+
.astro-code code>.line:last-child:empty {
|
| 141 |
+
display: none;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
/* ============================================================================ */
|
| 145 |
+
/* Non-Shiki pre wrapper (rehype) */
|
| 146 |
+
/* ============================================================================ */
|
| 147 |
+
.code-card {
|
| 148 |
+
position: relative;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.code-card .code-copy {
|
| 152 |
+
position: absolute;
|
| 153 |
+
top: var(--spacing-2);
|
| 154 |
+
right: var(--spacing-2);
|
| 155 |
+
z-index: 3;
|
| 156 |
+
display: none;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
.code-card:hover .code-copy {
|
| 160 |
+
display: block;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.code-card .code-copy svg {
|
| 164 |
+
width: 16px;
|
| 165 |
+
height: 16px;
|
| 166 |
+
display: block;
|
| 167 |
+
fill: currentColor;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.code-card pre {
|
| 171 |
+
margin: 0 0 var(--spacing-1);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
/* When no copy button (single-line), keep the label in the top-right corner */
|
| 175 |
+
.code-card.no-copy::after {
|
| 176 |
+
top: 8px;
|
| 177 |
+
right: 8px;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
/* ============================================================================ */
|
| 181 |
+
/* Contextual overrides */
|
| 182 |
+
/* ============================================================================ */
|
| 183 |
+
/* Inside Accordions: remove padding and border on code containers */
|
| 184 |
+
.accordion .astro-code {
|
| 185 |
+
padding: 0;
|
| 186 |
+
border: none;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.accordion .astro-code {
|
| 190 |
+
margin-bottom: 0 !important;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
.accordion .code-output {
|
| 194 |
+
border: none;
|
| 195 |
+
border-top: 1px solid var(--border-color) !important;
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
.accordion pre {
|
| 199 |
+
margin-bottom: 0 !important;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
.accordion .code-card pre {
|
| 203 |
+
margin: 0 !important;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
/* ============================================================================ */
|
| 207 |
+
/* Language/extension vignette (bottom-right, discreet) */
|
| 208 |
+
/* ============================================================================ */
|
| 209 |
+
/* .astro-code::after {
|
| 210 |
+
content: attr(data-language);
|
| 211 |
+
position: absolute;
|
| 212 |
+
right: 0;
|
| 213 |
+
bottom: 0;
|
| 214 |
+
font-size: 10px;
|
| 215 |
+
line-height: 1;
|
| 216 |
+
text-transform: uppercase;
|
| 217 |
+
color: var(--muted-color);
|
| 218 |
+
background: var(--surface-bg);
|
| 219 |
+
border-top: 1px solid var(--border-color);
|
| 220 |
+
border-left: 1px solid var(--border-color);
|
| 221 |
+
opacity: 1;
|
| 222 |
+
border-radius: 8px 0 0 0;
|
| 223 |
+
padding: 4px 6px;
|
| 224 |
+
pointer-events: none;
|
| 225 |
+
} */
|
| 226 |
+
|
| 227 |
+
/* Fallback if Shiki uses data-lang instead of data-language */
|
| 228 |
+
/* .astro-code[data-lang]::after { content: attr(data-lang); }
|
| 229 |
+
.astro-code[data-language="typescript"]::after { content: "ts"; }
|
| 230 |
+
.astro-code[data-language="tsx"]::after { content: "tsx"; }
|
| 231 |
+
.astro-code[data-language="javascript"]::after,
|
| 232 |
+
.astro-code[data-language="node"]::after,
|
| 233 |
+
.astro-code[data-language="jsx"]::after { content: "js"; }
|
| 234 |
+
.astro-code[data-language="python"]::after { content: "py"; }
|
| 235 |
+
.astro-code[data-language="bash"]::after,
|
| 236 |
+
.astro-code[data-language="shell"]::after,
|
| 237 |
+
.astro-code[data-language="sh"]::after { content: "sh"; }
|
| 238 |
+
.astro-code[data-language="markdown"]::after { content: "md"; }
|
| 239 |
+
.astro-code[data-language="yaml"]::after,
|
| 240 |
+
.astro-code[data-language="yml"]::after { content: "yml"; }
|
| 241 |
+
.astro-code[data-language="html"]::after { content: "html"; }
|
| 242 |
+
.astro-code[data-language="css"]::after { content: "css"; }
|
| 243 |
+
.astro-code[data-language="json"]::after { content: "json"; } */
|
| 244 |
+
|
| 245 |
+
/* In Accordions, keep same bottom-right placement */
|
| 246 |
+
.accordion .astro-code::after {
|
| 247 |
+
right: 0;
|
| 248 |
+
bottom: 0;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
/* ============================================================================ */
|
| 252 |
+
/* Results blocks glued to code blocks */
|
| 253 |
+
/* ============================================================================ */
|
| 254 |
+
.code-output {
|
| 255 |
+
position: relative;
|
| 256 |
+
background: oklch(from var(--code-bg) calc(l - 0.005) c h);
|
| 257 |
+
border: 1px solid var(--border-color);
|
| 258 |
+
border-radius: 6px;
|
| 259 |
+
margin-top: 0;
|
| 260 |
+
margin-bottom: var(--block-spacing-y);
|
| 261 |
+
padding: 0 !important;
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
.code-output pre {
|
| 265 |
+
padding: calc(var(--spacing-3) + 6px) var(--spacing-3) var(--spacing-3) var(--spacing-3) !important;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
/* If immediately following a code container, keep tight visual connection */
|
| 269 |
+
.code-card+.code-output,
|
| 270 |
+
.astro-code+.code-output,
|
| 271 |
+
section.content-grid pre+.code-output {
|
| 272 |
+
margin-top: 0;
|
| 273 |
+
border-top: none;
|
| 274 |
+
border-top-left-radius: 0;
|
| 275 |
+
border-top-right-radius: 0;
|
| 276 |
+
box-shadow: inset 0 8px 12px -12px rgba(0, 0, 0, 0.15);
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
/* Remove bottom margin on code when immediately followed by results */
|
| 280 |
+
.astro-code:has(+ .code-output) {
|
| 281 |
+
margin-bottom: 0 !important;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.code-card:has(+ .code-output) .astro-code {
|
| 285 |
+
margin-bottom: 0 !important;
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
section.content-grid pre:has(+ .code-output) {
|
| 289 |
+
margin-bottom: 0 !important;
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
/* Remove bottom border radius on code when followed by results */
|
| 293 |
+
.astro-code:has(+ .code-output) {
|
| 294 |
+
border-bottom-left-radius: 0;
|
| 295 |
+
border-bottom-right-radius: 0;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
.code-card:has(+ .code-output) .astro-code {
|
| 299 |
+
border-bottom-left-radius: 0;
|
| 300 |
+
border-bottom-right-radius: 0;
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
section.content-grid pre:has(+ .code-output) {
|
| 304 |
+
border-bottom-left-radius: 0;
|
| 305 |
+
border-bottom-right-radius: 0;
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
/* Small top-left label */
|
| 309 |
+
.code-output::before {
|
| 310 |
+
content: "Output";
|
| 311 |
+
position: absolute;
|
| 312 |
+
top: 0;
|
| 313 |
+
right: 0;
|
| 314 |
+
font-size: 10px;
|
| 315 |
+
line-height: 1;
|
| 316 |
+
color: var(--muted-color);
|
| 317 |
+
text-transform: uppercase;
|
| 318 |
+
letter-spacing: 0.04em;
|
| 319 |
+
border-top: none;
|
| 320 |
+
border-right: none;
|
| 321 |
+
border-radius: 0 0 0 6px;
|
| 322 |
+
padding: 10px 10px;
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
/* Very subtle top shadow so results feels under the code */
|
| 326 |
+
.code-output {}
|
| 327 |
+
|
| 328 |
+
.code-output> :where(*):first-child {
|
| 329 |
+
margin-top: 0 !important;
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.code-output> :where(*):last-child {
|
| 333 |
+
margin-bottom: 0 !important;
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
/* ============================================================================ */
|
| 337 |
+
/* Optional filename tag above code blocks */
|
| 338 |
+
/* ============================================================================ */
|
| 339 |
+
.code-filename {
|
| 340 |
+
display: inline-block;
|
| 341 |
+
font-size: 12px;
|
| 342 |
+
line-height: 1;
|
| 343 |
+
color: var(--muted-color);
|
| 344 |
+
background: var(--surface-bg);
|
| 345 |
+
border: 1px solid var(--border-color);
|
| 346 |
+
border-bottom: none;
|
| 347 |
+
border-radius: 6px 6px 0 0;
|
| 348 |
+
padding: 4px 8px;
|
| 349 |
+
margin: 0;
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
.code-filename+.code-card .astro-code,
|
| 353 |
+
.code-filename+.astro-code,
|
| 354 |
+
.code-filename+section.content-grid pre {
|
| 355 |
+
border-top-left-radius: 0;
|
| 356 |
+
border-top-right-radius: 6px;
|
| 357 |
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Form Elements - Modern Minimal Design */
|
| 3 |
+
/* ============================================================================ */
|
| 4 |
+
|
| 5 |
+
/* Select styling with modern chevron */
|
| 6 |
+
select {
|
| 7 |
+
background-color: var(--page-bg);
|
| 8 |
+
border: 1px solid color-mix(in srgb, var(--primary-color) 50%, var(--border-color));
|
| 9 |
+
border-radius: var(--button-radius);
|
| 10 |
+
padding: var(--button-padding-y) calc(var(--button-padding-x)*2) var(--button-padding-y) var(--button-padding-x);
|
| 11 |
+
font-family: var(--default-font-family);
|
| 12 |
+
font-size: var(--button-font-size);
|
| 13 |
+
color: var(--text-color);
|
| 14 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8.825L1.175 4 2.35 2.825 6 6.475 9.65 2.825 10.825 4z'/%3E%3C/svg%3E");
|
| 15 |
+
background-repeat: no-repeat;
|
| 16 |
+
background-position: right calc(var(--button-padding-x) + 2px) center;
|
| 17 |
+
background-size: 12px;
|
| 18 |
+
cursor: pointer;
|
| 19 |
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
| 20 |
+
-webkit-appearance: none;
|
| 21 |
+
-moz-appearance: none;
|
| 22 |
+
appearance: none;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
select:hover,
|
| 26 |
+
select:focus,
|
| 27 |
+
select:active {
|
| 28 |
+
border-color: var(--primary-color);
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
select:focus {
|
| 32 |
+
outline: none;
|
| 33 |
+
border-color: var(--primary-color);
|
| 34 |
+
box-shadow: 0 0 0 2px rgba(from var(--primary-color) r g b / 0.1);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
select:disabled {
|
| 38 |
+
opacity: 0.6;
|
| 39 |
+
cursor: not-allowed;
|
| 40 |
+
background-color: var(--surface-bg);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/* Dark theme select chevron */
|
| 44 |
+
[data-theme="dark"] select {
|
| 45 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23bbb' d='M6 8.825L1.175 4 2.35 2.825 6 6.475 9.65 2.825 10.825 4z'/%3E%3C/svg%3E");
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
/* Checkbox styling */
|
| 49 |
+
input[type="checkbox"] {
|
| 50 |
+
appearance: none;
|
| 51 |
+
width: 16px;
|
| 52 |
+
height: 16px;
|
| 53 |
+
border: 2px solid var(--border-color);
|
| 54 |
+
border-radius: 3px;
|
| 55 |
+
background-color: var(--page-bg);
|
| 56 |
+
cursor: pointer;
|
| 57 |
+
position: relative;
|
| 58 |
+
transition: all 0.2s ease;
|
| 59 |
+
margin-right: var(--spacing-2);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
input[type="checkbox"]:hover {
|
| 63 |
+
border-color: var(--primary-color);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
input[type="checkbox"]:focus {
|
| 67 |
+
outline: none;
|
| 68 |
+
border-color: var(--primary-color);
|
| 69 |
+
box-shadow: 0 0 0 2px rgba(from var(--primary-color) r g b / 0.1);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
input[type="checkbox"]:checked {
|
| 73 |
+
background-color: var(--primary-color);
|
| 74 |
+
border-color: var(--primary-color);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
input[type="checkbox"]:checked::before {
|
| 78 |
+
content: '';
|
| 79 |
+
position: absolute;
|
| 80 |
+
top: 1px;
|
| 81 |
+
left: 4px;
|
| 82 |
+
width: 4px;
|
| 83 |
+
height: 8px;
|
| 84 |
+
border: solid var(--on-primary);
|
| 85 |
+
border-width: 0 2px 2px 0;
|
| 86 |
+
transform: rotate(45deg);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
input[type="checkbox"]:disabled {
|
| 90 |
+
opacity: 0.6;
|
| 91 |
+
cursor: not-allowed;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
/* Radio button styling */
|
| 95 |
+
input[type="radio"] {
|
| 96 |
+
appearance: none;
|
| 97 |
+
width: 16px;
|
| 98 |
+
height: 16px;
|
| 99 |
+
border: 2px solid var(--border-color);
|
| 100 |
+
border-radius: 50%;
|
| 101 |
+
background-color: var(--page-bg);
|
| 102 |
+
cursor: pointer;
|
| 103 |
+
position: relative;
|
| 104 |
+
transition: all 0.2s ease;
|
| 105 |
+
margin-right: var(--spacing-2);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
input[type="radio"]:hover {
|
| 109 |
+
border-color: var(--primary-color);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
input[type="radio"]:focus {
|
| 113 |
+
outline: none;
|
| 114 |
+
border-color: var(--primary-color);
|
| 115 |
+
box-shadow: 0 0 0 2px rgba(from var(--primary-color) r g b / 0.1);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
input[type="radio"]:checked {
|
| 119 |
+
border-color: var(--primary-color);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
input[type="radio"]:checked::before {
|
| 123 |
+
content: '';
|
| 124 |
+
position: absolute;
|
| 125 |
+
top: 2px;
|
| 126 |
+
left: 2px;
|
| 127 |
+
width: 8px;
|
| 128 |
+
height: 8px;
|
| 129 |
+
border-radius: 50%;
|
| 130 |
+
background-color: var(--primary-color);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
input[type="radio"]:disabled {
|
| 134 |
+
opacity: 0.6;
|
| 135 |
+
cursor: not-allowed;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
/* Input text styling for consistency */
|
| 139 |
+
input[type="text"],
|
| 140 |
+
input[type="email"],
|
| 141 |
+
input[type="password"],
|
| 142 |
+
input[type="number"],
|
| 143 |
+
input[type="url"],
|
| 144 |
+
input[type="search"],
|
| 145 |
+
textarea {
|
| 146 |
+
appearance: none;
|
| 147 |
+
background-color: var(--page-bg);
|
| 148 |
+
border: 1px solid var(--border-color);
|
| 149 |
+
border-radius: var(--button-radius);
|
| 150 |
+
padding: var(--button-padding-y) var(--button-padding-x);
|
| 151 |
+
font-family: var(--default-font-family);
|
| 152 |
+
font-size: var(--button-font-size);
|
| 153 |
+
color: var(--text-color);
|
| 154 |
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
| 155 |
+
width: 100%;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
input[type="text"]:hover,
|
| 159 |
+
input[type="email"]:hover,
|
| 160 |
+
input[type="password"]:hover,
|
| 161 |
+
input[type="number"]:hover,
|
| 162 |
+
input[type="url"]:hover,
|
| 163 |
+
input[type="search"]:hover,
|
| 164 |
+
textarea:hover {
|
| 165 |
+
border-color: var(--primary-color);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
input[type="text"]:focus,
|
| 169 |
+
input[type="email"]:focus,
|
| 170 |
+
input[type="password"]:focus,
|
| 171 |
+
input[type="number"]:focus,
|
| 172 |
+
input[type="url"]:focus,
|
| 173 |
+
input[type="search"]:focus,
|
| 174 |
+
textarea:focus {
|
| 175 |
+
outline: none;
|
| 176 |
+
border-color: var(--primary-color);
|
| 177 |
+
box-shadow: 0 0 0 2px rgba(from var(--primary-color) r g b / 0.1);
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
input[type="text"]:disabled,
|
| 181 |
+
input[type="email"]:disabled,
|
| 182 |
+
input[type="password"]:disabled,
|
| 183 |
+
input[type="number"]:disabled,
|
| 184 |
+
input[type="url"]:disabled,
|
| 185 |
+
input[type="search"]:disabled,
|
| 186 |
+
textarea:disabled {
|
| 187 |
+
opacity: 0.6;
|
| 188 |
+
cursor: not-allowed;
|
| 189 |
+
background-color: var(--surface-bg);
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
/* Label styling */
|
| 193 |
+
label {
|
| 194 |
+
display: flex;
|
| 195 |
+
align-items: center;
|
| 196 |
+
font-size: var(--button-font-size);
|
| 197 |
+
color: var(--text-color);
|
| 198 |
+
cursor: pointer;
|
| 199 |
+
margin-bottom: 0;
|
| 200 |
+
line-height: 1.4;
|
| 201 |
+
user-select: none;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
/* Form group spacing */
|
| 205 |
+
.form-group {
|
| 206 |
+
margin-bottom: var(--spacing-4);
|
| 207 |
+
display: flex;
|
| 208 |
+
align-items: center;
|
| 209 |
+
gap: var(--spacing-2);
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
.form-group label {
|
| 213 |
+
margin-bottom: 0;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
/* Alternative: for vertical form groups */
|
| 217 |
+
.form-group.vertical {
|
| 218 |
+
flex-direction: column;
|
| 219 |
+
align-items: flex-start;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
.form-group.vertical label {
|
| 223 |
+
margin-bottom: var(--spacing-1);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
/* For inline form elements */
|
| 227 |
+
.form-inline {
|
| 228 |
+
display: flex;
|
| 229 |
+
align-items: center;
|
| 230 |
+
gap: var(--spacing-2);
|
| 231 |
+
margin-bottom: var(--spacing-3);
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.form-inline label {
|
| 235 |
+
margin-bottom: 0;
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
/* Ensure labels in flex containers don't break alignment */
|
| 239 |
+
div[style*="display: flex"] label,
|
| 240 |
+
div[class*="flex"] label {
|
| 241 |
+
margin-bottom: 0 !important;
|
| 242 |
+
align-self: center;
|
| 243 |
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Hero + Meta bar */
|
| 3 |
+
/* Extracted from HeroArticle.astro scoped styles. */
|
| 4 |
+
/* Shared between editor (FrontmatterHero.tsx) and publisher (html-renderer). */
|
| 5 |
+
/* ============================================================================ */
|
| 6 |
+
|
| 7 |
+
/* ---- Hero section ---- */
|
| 8 |
+
|
| 9 |
+
.hero {
|
| 10 |
+
width: 100%;
|
| 11 |
+
padding: 64px 16px 16px;
|
| 12 |
+
text-align: center;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
.hero-title {
|
| 16 |
+
font-size: clamp(34px, 5vw, 54px);
|
| 17 |
+
font-weight: 800;
|
| 18 |
+
line-height: 1.12;
|
| 19 |
+
letter-spacing: -0.02em;
|
| 20 |
+
margin: 0 auto 8px;
|
| 21 |
+
max-width: 780px;
|
| 22 |
+
text-wrap: balance;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.hero-title[data-title-size="md"] {
|
| 26 |
+
font-size: clamp(28px, 4vw, 44px);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.hero-title[data-title-size="sm"] {
|
| 30 |
+
font-size: clamp(24px, 3.2vw, 38px);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.hero-banner {
|
| 34 |
+
max-width: 980px;
|
| 35 |
+
margin: 0 auto;
|
| 36 |
+
aspect-ratio: 5 / 2;
|
| 37 |
+
overflow: hidden;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.hero-desc {
|
| 41 |
+
color: var(--muted-color);
|
| 42 |
+
font-style: italic;
|
| 43 |
+
margin: 0 auto 16px;
|
| 44 |
+
max-width: 55%;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
@media (max-width: 768px) {
|
| 48 |
+
.hero-banner { aspect-ratio: auto; }
|
| 49 |
+
.hero-desc { max-width: 90%; }
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
/* ---- Meta bar ---- */
|
| 53 |
+
|
| 54 |
+
.meta {
|
| 55 |
+
border-top: 1px solid var(--border-color);
|
| 56 |
+
border-bottom: 1px solid var(--border-color);
|
| 57 |
+
padding: 1rem 0;
|
| 58 |
+
font-size: 0.9rem;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.meta-container {
|
| 62 |
+
max-width: 980px;
|
| 63 |
+
display: flex;
|
| 64 |
+
flex-direction: row;
|
| 65 |
+
justify-content: space-between;
|
| 66 |
+
margin: 0 auto;
|
| 67 |
+
padding: 0 var(--content-padding-x, 16px);
|
| 68 |
+
gap: 8px;
|
| 69 |
+
flex-wrap: wrap;
|
| 70 |
+
row-gap: 12px;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.meta-container a:not(.button) {
|
| 74 |
+
color: var(--primary-color);
|
| 75 |
+
text-decoration: underline;
|
| 76 |
+
text-underline-offset: 2px;
|
| 77 |
+
text-decoration-thickness: 0.06em;
|
| 78 |
+
text-decoration-color: var(--link-underline);
|
| 79 |
+
transition: text-decoration-color 0.15s ease-in-out;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.meta-container a:hover {
|
| 83 |
+
text-decoration-color: var(--link-underline-hover);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.meta-container-cell {
|
| 87 |
+
display: flex;
|
| 88 |
+
flex-direction: column;
|
| 89 |
+
gap: 8px;
|
| 90 |
+
max-width: 400px;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.meta-container-cell h3 {
|
| 94 |
+
margin: 0;
|
| 95 |
+
font-size: 12px;
|
| 96 |
+
font-weight: 400;
|
| 97 |
+
color: var(--muted-color);
|
| 98 |
+
text-transform: uppercase;
|
| 99 |
+
letter-spacing: 0.02em;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.meta-container-cell p {
|
| 103 |
+
margin: 0;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.authors {
|
| 107 |
+
margin: 0;
|
| 108 |
+
list-style-type: none;
|
| 109 |
+
padding-left: 0;
|
| 110 |
+
display: flex;
|
| 111 |
+
flex-wrap: wrap;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.authors li {
|
| 115 |
+
white-space: nowrap;
|
| 116 |
+
padding: 0;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.affiliations {
|
| 120 |
+
margin: 0;
|
| 121 |
+
padding-left: 1.25em;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.affiliations li {
|
| 125 |
+
margin: 0;
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
@media (max-width: 768px) {
|
| 129 |
+
.meta-container-cell:nth-child(even) { text-align: right; }
|
| 130 |
+
.meta-container-cell:last-child:nth-child(odd) {
|
| 131 |
+
flex-grow: 0;
|
| 132 |
+
flex-basis: auto;
|
| 133 |
+
margin-left: auto;
|
| 134 |
+
text-align: right;
|
| 135 |
+
}
|
| 136 |
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.mermaid .nodeLabel p {
|
| 2 |
+
color: var(--text-color) !important;
|
| 3 |
+
}
|
| 4 |
+
|
| 5 |
+
.mermaid .cluster-label .nodeLabel {
|
| 6 |
+
color: var(--text-color) !important;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
/* Styles pour le texte des subgraphs/clusters - gérer les foreignObject */
|
| 10 |
+
.mermaid .cluster-label text,
|
| 11 |
+
.mermaid .cluster-label .nodeLabel text,
|
| 12 |
+
.mermaid .cluster-label foreignObject,
|
| 13 |
+
.mermaid .cluster-label foreignObject div,
|
| 14 |
+
.mermaid .cluster-label foreignObject span {
|
| 15 |
+
color: var(--text-color) !important;
|
| 16 |
+
fill: var(--text-color) !important;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
/* Styles spécifiques pour les clusters/subgraphs */
|
| 20 |
+
.mermaid .cluster rect {
|
| 21 |
+
fill: transparent !important;
|
| 22 |
+
stroke: var(--border-color) !important;
|
| 23 |
+
stroke-width: 1px !important;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.mermaid .cluster-label {
|
| 27 |
+
color: var(--text-color) !important;
|
| 28 |
+
fill: var(--text-color) !important;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/* Masquer le flicker pendant la conversion */
|
| 32 |
+
.mermaid-zoom-wrapper.converting {
|
| 33 |
+
opacity: 0.7;
|
| 34 |
+
transition: opacity 0.2s ease;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.mermaid-zoom-wrapper.converting .mermaid {
|
| 38 |
+
opacity: 0.7;
|
| 39 |
+
transition: opacity 0.2s ease;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
/* Assurer que les diagrammes Mermaid prennent toute la largeur */
|
| 43 |
+
.mermaid {
|
| 44 |
+
width: 100% !important;
|
| 45 |
+
max-width: 100% !important;
|
| 46 |
+
display: block !important;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
/* Styles pour les SVG Mermaid */
|
| 50 |
+
.mermaid svg {
|
| 51 |
+
width: 100% !important;
|
| 52 |
+
max-width: 100% !important;
|
| 53 |
+
height: auto !important;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
/* Styles pour les wrappers de zoom Mermaid */
|
| 57 |
+
.mermaid-zoom-wrapper {
|
| 58 |
+
display: block !important;
|
| 59 |
+
width: 100% !important;
|
| 60 |
+
max-width: 100% !important;
|
| 61 |
+
cursor: zoom-in;
|
| 62 |
+
position: relative;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
.mermaid-zoom-wrapper .mermaid {
|
| 66 |
+
width: 100% !important;
|
| 67 |
+
max-width: 100% !important;
|
| 68 |
+
display: block !important;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.mermaid-zoom-wrapper .mermaid svg {
|
| 72 |
+
width: 100% !important;
|
| 73 |
+
max-width: 100% !important;
|
| 74 |
+
height: auto !important;
|
| 75 |
+
display: block !important;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/* Styles pour les nœuds avec bords arrondis et bordure interne */
|
| 79 |
+
.mermaid rect:not(.flowchart-link),
|
| 80 |
+
.mermaid .node rect,
|
| 81 |
+
.mermaid .nodeLabel rect,
|
| 82 |
+
.mermaid .cluster rect {
|
| 83 |
+
rx: 8px !important;
|
| 84 |
+
ry: 8px !important;
|
| 85 |
+
stroke: color-mix(in srgb, var(--text-color) 20%, transparent) !important;
|
| 86 |
+
stroke-width: 1px !important;
|
| 87 |
+
/* Décalage pour créer l'effet de bordure interne */
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
/* Styles pour les diagrammes Mermaid zoomables */
|
| 91 |
+
.mermaid-zoom-wrapper:hover {
|
| 92 |
+
opacity: 0.95;
|
| 93 |
+
transition: opacity 0.2s ease;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
/* Appliquer le même style que les images zoomables */
|
| 97 |
+
.mermaid-zoom-wrapper[data-zoomable="1"] {
|
| 98 |
+
cursor: zoom-in;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
/* Styles pour le mode zoom ouvert */
|
| 102 |
+
.medium-zoom--opened .mermaid-zoom-wrapper {
|
| 103 |
+
cursor: zoom-out;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/* Exclure les images Mermaid du filtre d'inversion en mode sombre */
|
| 107 |
+
/* Le filtre global s'applique à .medium-zoom-image--opened */
|
| 108 |
+
/* Nous devons être plus spécifique pour les images Mermaid */
|
| 109 |
+
|
| 110 |
+
/* Exception pour les images Mermaid - pas de filtre d'inversion */
|
| 111 |
+
:global([data-theme="dark"]) .mermaid-zoom-wrapper img:global(.medium-zoom-image--opened) {
|
| 112 |
+
filter: none !important;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
/* Alternative: cibler directement l'image dans le wrapper Mermaid */
|
| 116 |
+
:global([data-theme="dark"]) .mermaid-zoom-wrapper :global(.medium-zoom-image--opened) {
|
| 117 |
+
filter: none !important;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
/* Encore plus spécifique: cibler l'image générée par notre script */
|
| 121 |
+
:global([data-theme="dark"]) .mermaid-zoom-wrapper img[data-zoomable="1"]:global(.medium-zoom-image--opened) {
|
| 122 |
+
filter: none !important;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
/* Forcer un z-index très élevé pour medium-zoom (au-dessus de tout) */
|
| 126 |
+
:global(.medium-zoom-overlay) {
|
| 127 |
+
z-index: 9999999 !important;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
:global(.medium-zoom-image--opened) {
|
| 131 |
+
z-index: 10000000 !important;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
/* Cibler la classe spécifique mermaid-zoom-image */
|
| 135 |
+
:global([data-theme="dark"]) .mermaid-zoom-image:global(.medium-zoom-image--opened) {
|
| 136 |
+
filter: none !important;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
/* Overlay medium-zoom avec z-index très élevé pour Mermaid */
|
| 140 |
+
:global(.medium-zoom-overlay):has(.mermaid-zoom-wrapper) {
|
| 141 |
+
z-index: 9999999 !important;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
/* Z-index très élevé pour les images Mermaid */
|
| 145 |
+
:global(.mermaid-zoom-image):global(.medium-zoom-image--opened) {
|
| 146 |
+
z-index: 10000000 !important;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
:global(.mermaid-zoom-wrapper):has(:global(.medium-zoom-image--opened)) {
|
| 150 |
+
z-index: 10000000 !important;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/* Masquer les autres diagrammes quand un est zoomé */
|
| 154 |
+
:global(.medium-zoom--opened) .mermaid-zoom-wrapper {
|
| 155 |
+
opacity: 0;
|
| 156 |
+
z-index: calc(var(--z-base) - 1);
|
| 157 |
+
transition: opacity 0.3s ease;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
/* Le diagramme zoomé reste visible */
|
| 161 |
+
:global(.medium-zoom--opened) .mermaid-zoom-wrapper:has(.medium-zoom--opened) {
|
| 162 |
+
opacity: 1;
|
| 163 |
+
z-index: var(--z-overlay);
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
/* Fallback pour les navigateurs sans support :has() */
|
| 167 |
+
:global(.medium-zoom--opened) .mermaid-zoom-wrapper.zoom-active {
|
| 168 |
+
opacity: 1 !important;
|
| 169 |
+
z-index: var(--z-overlay) !important;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
/* Styles spécifiques pour différents types de diagrammes */
|
| 173 |
+
|
| 174 |
+
/* Flowchart/Graph - styles généraux */
|
| 175 |
+
.mermaid .node rect,
|
| 176 |
+
.mermaid .node circle,
|
| 177 |
+
.mermaid .node ellipse,
|
| 178 |
+
.mermaid .label rect {
|
| 179 |
+
rx: 8px !important;
|
| 180 |
+
ry: 8px !important;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
/* Flowchart - nœuds principaux */
|
| 184 |
+
.mermaid .flowchart-node rect,
|
| 185 |
+
.mermaid .flowchart-label rect {
|
| 186 |
+
rx: 8px !important;
|
| 187 |
+
ry: 8px !important;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
/* Sequence diagram */
|
| 191 |
+
.mermaid .actor rect,
|
| 192 |
+
.mermaid .participant rect {
|
| 193 |
+
rx: 8px !important;
|
| 194 |
+
ry: 8px !important;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
/* ER diagram */
|
| 198 |
+
.mermaid .entityBox rect,
|
| 199 |
+
.mermaid .er .entityBox rect {
|
| 200 |
+
rx: 6px !important;
|
| 201 |
+
ry: 6px !important;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
/* Gantt chart */
|
| 205 |
+
.mermaid .section0 rect,
|
| 206 |
+
.mermaid .section1 rect,
|
| 207 |
+
.mermaid .section2 rect,
|
| 208 |
+
.mermaid .section3 rect {
|
| 209 |
+
rx: 4px !important;
|
| 210 |
+
ry: 4px !important;
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
/* Gitgraph */
|
| 214 |
+
.mermaid .commit rect {
|
| 215 |
+
rx: 12px !important;
|
| 216 |
+
ry: 12px !important;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
/* Mindmap */
|
| 220 |
+
.mermaid .mindmap-node rect {
|
| 221 |
+
rx: 10px !important;
|
| 222 |
+
ry: 10px !important;
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
/* Sankey */
|
| 226 |
+
.mermaid .sankey .node rect {
|
| 227 |
+
rx: 4px !important;
|
| 228 |
+
ry: 4px !important;
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
/* Timeline */
|
| 232 |
+
.mermaid .timeline rect {
|
| 233 |
+
rx: 6px !important;
|
| 234 |
+
ry: 6px !important;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
/* Pie chart */
|
| 238 |
+
.mermaid .pieTitleText {
|
| 239 |
+
rx: 8px !important;
|
| 240 |
+
ry: 8px !important;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
/* Journey */
|
| 244 |
+
.mermaid .journey .section0 rect,
|
| 245 |
+
.mermaid .journey .section1 rect,
|
| 246 |
+
.mermaid .journey .section2 rect,
|
| 247 |
+
.mermaid .journey .section3 rect {
|
| 248 |
+
rx: 8px !important;
|
| 249 |
+
ry: 8px !important;
|
| 250 |
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.content-grid main table {
|
| 2 |
+
border-collapse: collapse;
|
| 3 |
+
table-layout: auto;
|
| 4 |
+
margin: 0;
|
| 5 |
+
background-color: var(--surface-bg);
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
.content-grid main th,
|
| 9 |
+
.content-grid main td {
|
| 10 |
+
border-bottom: 1px solid var(--border-color);
|
| 11 |
+
padding: 6px 8px;
|
| 12 |
+
font-size: 15px;
|
| 13 |
+
white-space: nowrap;
|
| 14 |
+
/* prevent squashing; allow horizontal scroll instead */
|
| 15 |
+
word-break: auto-phrase;
|
| 16 |
+
/* white-space: break-spaces; */
|
| 17 |
+
vertical-align: top;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
.content-grid main thead th {
|
| 21 |
+
border-bottom: 1px solid var(--border-color);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.content-grid main thead th {
|
| 25 |
+
border-bottom: 1px solid var(--border-color);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
.content-grid main thead th {
|
| 29 |
+
background: var(--table-header-bg);
|
| 30 |
+
padding-top: 10px;
|
| 31 |
+
padding-bottom: 10px;
|
| 32 |
+
font-weight: 600;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.content-grid main hr {
|
| 36 |
+
border: none;
|
| 37 |
+
border-bottom: 1px solid var(--border-color);
|
| 38 |
+
margin: var(--spacing-5) 0;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
/* Scroll wrapper: keeps table 100% width but enables horizontal scroll when needed */
|
| 42 |
+
.content-grid main .table-scroll {
|
| 43 |
+
width: 100%;
|
| 44 |
+
overflow-x: auto;
|
| 45 |
+
-webkit-overflow-scrolling: touch;
|
| 46 |
+
border: 1px solid var(--border-color);
|
| 47 |
+
border-radius: var(--table-border-radius);
|
| 48 |
+
background: var(--surface-bg);
|
| 49 |
+
margin: 0 0 var(--block-spacing-y);
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.content-grid main .table-scroll>table {
|
| 53 |
+
width: fit-content;
|
| 54 |
+
min-width: 100%;
|
| 55 |
+
max-width: none;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
/* Vertical dividers between columns (no outer right border) */
|
| 59 |
+
.content-grid main .table-scroll>table th,
|
| 60 |
+
.content-grid main .table-scroll>table td {
|
| 61 |
+
border-right: 1px solid var(--border-color);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.content-grid main .table-scroll>table th:last-child,
|
| 65 |
+
.content-grid main .table-scroll>table td:last-child {
|
| 66 |
+
border-right: none;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
.content-grid main .table-scroll>table thead th:first-child {
|
| 70 |
+
border-top-left-radius: var(--table-border-radius);
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.content-grid main .table-scroll>table thead th:last-child {
|
| 74 |
+
border-top-right-radius: var(--table-border-radius);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.content-grid main .table-scroll>table tbody tr:last-child td:first-child {
|
| 78 |
+
border-bottom-left-radius: var(--table-border-radius);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.content-grid main .table-scroll>table tbody tr:last-child td:last-child {
|
| 82 |
+
border-bottom-right-radius: var(--table-border-radius);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
/* Zebra striping for odd rows */
|
| 86 |
+
.content-grid main .table-scroll>table tbody tr:nth-child(odd) td {
|
| 87 |
+
background: var(--table-row-odd-bg);
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
/* Remove bottom border on last row */
|
| 91 |
+
.content-grid main .table-scroll>table tbody tr:last-child td {
|
| 92 |
+
border-bottom: none;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
/* Accordion context: remove outer borders/radius and fit content flush */
|
| 96 |
+
.accordion .accordion__content .table-scroll {
|
| 97 |
+
border: none;
|
| 98 |
+
border-radius: 0;
|
| 99 |
+
margin: 0;
|
| 100 |
+
margin-bottom: 0 !important;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
/* Ensure no bottom margin even if table isn't wrapped (fallback) */
|
| 104 |
+
.accordion .accordion__content table {
|
| 105 |
+
margin: 0 !important;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
.accordion .accordion__content .table-scroll>table thead th:first-child,
|
| 109 |
+
.accordion .accordion__content .table-scroll>table thead th:last-child,
|
| 110 |
+
.accordion .accordion__content .table-scroll>table tbody tr:last-child td:first-child,
|
| 111 |
+
.accordion .accordion__content .table-scroll>table tbody tr:last-child td:last-child {
|
| 112 |
+
border-radius: 0;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
/* Fallback for browsers without fit-content support */
|
| 116 |
+
@supports not (width: fit-content) {
|
| 117 |
+
.content-grid main .table-scroll>table {
|
| 118 |
+
width: max-content;
|
| 119 |
+
min-width: 100%;
|
| 120 |
+
}
|
| 121 |
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 16px; }
|
| 2 |
+
|
| 3 |
+
.tag {
|
| 4 |
+
display: inline-flex;
|
| 5 |
+
align-items: center;
|
| 6 |
+
gap: 6px;
|
| 7 |
+
padding: 8px 12px;
|
| 8 |
+
font-size: 12px;
|
| 9 |
+
line-height: 1;
|
| 10 |
+
border-radius: var(--button-radius);
|
| 11 |
+
background: var(--surface-bg);
|
| 12 |
+
border: 1px solid var(--border-color);
|
| 13 |
+
color: var(--text-color);
|
| 14 |
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================================ */
|
| 2 |
+
/* Table of Contents */
|
| 3 |
+
/* Extracted from TableOfContents.astro scoped styles. */
|
| 4 |
+
/* Shared between editor and publisher. */
|
| 5 |
+
/* ============================================================================ */
|
| 6 |
+
|
| 7 |
+
.table-of-contents {
|
| 8 |
+
position: sticky;
|
| 9 |
+
top: 32px;
|
| 10 |
+
margin-top: 12px;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
.table-of-contents nav {
|
| 14 |
+
border-left: 1px solid var(--border-color);
|
| 15 |
+
padding-left: 16px;
|
| 16 |
+
font-size: 13px;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
.table-of-contents .title {
|
| 20 |
+
font-weight: 600;
|
| 21 |
+
font-size: 14px;
|
| 22 |
+
margin-bottom: 8px;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.table-of-contents nav ul {
|
| 26 |
+
margin: 0 0 6px;
|
| 27 |
+
padding-left: 1em;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
.table-of-contents nav li {
|
| 31 |
+
list-style: none;
|
| 32 |
+
margin: 0.25em 0;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.table-of-contents nav a,
|
| 36 |
+
.table-of-contents nav a:link,
|
| 37 |
+
.table-of-contents nav a:visited {
|
| 38 |
+
color: var(--text-color);
|
| 39 |
+
text-decoration: none;
|
| 40 |
+
border-bottom: none;
|
| 41 |
+
background: none;
|
| 42 |
+
cursor: pointer;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.table-of-contents nav > ul > li > a {
|
| 46 |
+
font-weight: 700;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
.table-of-contents nav a:hover {
|
| 50 |
+
text-decoration: underline solid var(--muted-color);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.table-of-contents nav a.active {
|
| 54 |
+
text-decoration: underline;
|
| 55 |
+
}
|
|
@@ -6,6 +6,43 @@
|
|
| 6 |
block handles, slash menu, upload UI, panels, etc.
|
| 7 |
----------------------------------------------------------------------- */
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
/* Math editing */
|
| 10 |
.tiptap [data-type="inline-math"] {
|
| 11 |
cursor: pointer;
|
|
@@ -19,7 +56,7 @@
|
|
| 19 |
font-family: "SFMono-Regular", "Fira Code", monospace;
|
| 20 |
font-size: 0.85em;
|
| 21 |
color: var(--code-text);
|
| 22 |
-
background: var(--
|
| 23 |
padding: 0.1em 0.4em;
|
| 24 |
border-radius: 3px;
|
| 25 |
outline: none;
|
|
@@ -60,7 +97,7 @@
|
|
| 60 |
|
| 61 |
.comment-mark.resolved {
|
| 62 |
background: transparent;
|
| 63 |
-
border-bottom: 1px dashed var(--border);
|
| 64 |
}
|
| 65 |
|
| 66 |
/* Collaboration cursors */
|
|
@@ -99,7 +136,7 @@
|
|
| 99 |
|
| 100 |
/* Image upload card */
|
| 101 |
.image-upload-card {
|
| 102 |
-
border: 2px dashed var(--border);
|
| 103 |
border-radius: 12px;
|
| 104 |
padding: 2.5rem 1.5rem;
|
| 105 |
margin: 1em 0;
|
|
@@ -112,7 +149,7 @@
|
|
| 112 |
}
|
| 113 |
|
| 114 |
.image-upload-card:hover {
|
| 115 |
-
border-color: var(--
|
| 116 |
background: var(--bg-hover);
|
| 117 |
}
|
| 118 |
|
|
@@ -151,13 +188,13 @@
|
|
| 151 |
}
|
| 152 |
|
| 153 |
.image-upload-btn.secondary {
|
| 154 |
-
background: var(--
|
| 155 |
-
color: var(--
|
| 156 |
}
|
| 157 |
|
| 158 |
.image-upload-btn.secondary:hover {
|
| 159 |
-
background: var(--
|
| 160 |
-
color: var(--text-
|
| 161 |
}
|
| 162 |
|
| 163 |
.image-upload-card-hint {
|
|
@@ -178,10 +215,10 @@
|
|
| 178 |
.image-upload-url-input {
|
| 179 |
width: 100%;
|
| 180 |
padding: 0.5rem 0.75rem;
|
| 181 |
-
border: 1px solid var(--border);
|
| 182 |
border-radius: 6px;
|
| 183 |
-
background: var(--
|
| 184 |
-
color: var(--text-
|
| 185 |
font-size: 0.8125rem;
|
| 186 |
font-family: inherit;
|
| 187 |
outline: none;
|
|
@@ -235,8 +272,8 @@
|
|
| 235 |
}
|
| 236 |
|
| 237 |
.block-handle-btn:hover {
|
| 238 |
-
color: var(--
|
| 239 |
-
background: var(--
|
| 240 |
}
|
| 241 |
|
| 242 |
.block-handle-grip {
|
|
@@ -250,7 +287,7 @@
|
|
| 250 |
/* Slash menu */
|
| 251 |
.slash-menu {
|
| 252 |
background: var(--bg-surface);
|
| 253 |
-
border: 1px solid var(--border);
|
| 254 |
border-radius: 10px;
|
| 255 |
padding: 0.35rem;
|
| 256 |
min-width: 220px;
|
|
@@ -270,14 +307,14 @@
|
|
| 270 |
background: none;
|
| 271 |
width: 100%;
|
| 272 |
text-align: left;
|
| 273 |
-
color: var(--text-
|
| 274 |
font-size: 0.875rem;
|
| 275 |
font-family: inherit;
|
| 276 |
}
|
| 277 |
|
| 278 |
.slash-menu-item:hover,
|
| 279 |
.slash-menu-item.is-selected {
|
| 280 |
-
background: var(--
|
| 281 |
}
|
| 282 |
|
| 283 |
.slash-menu-item-icon {
|
|
@@ -287,8 +324,8 @@
|
|
| 287 |
align-items: center;
|
| 288 |
justify-content: center;
|
| 289 |
border-radius: 6px;
|
| 290 |
-
background: var(--
|
| 291 |
-
color: var(--
|
| 292 |
font-size: 0.9rem;
|
| 293 |
flex-shrink: 0;
|
| 294 |
}
|
|
@@ -300,22 +337,22 @@
|
|
| 300 |
|
| 301 |
.slash-menu-item-title {
|
| 302 |
font-weight: 500;
|
| 303 |
-
color: var(--text-
|
| 304 |
font-size: 0.875rem;
|
| 305 |
}
|
| 306 |
|
| 307 |
.slash-menu-item-desc {
|
| 308 |
font-size: 0.75rem;
|
| 309 |
-
color: var(--
|
| 310 |
}
|
| 311 |
|
| 312 |
/* Footnote editing controls */
|
| 313 |
.footnote-tooltip-input {
|
| 314 |
width: 100%;
|
| 315 |
-
background: var(--
|
| 316 |
-
border: 1px solid var(--border);
|
| 317 |
border-radius: 4px;
|
| 318 |
-
color: var(--text-
|
| 319 |
font-size: 12px;
|
| 320 |
padding: 6px 8px;
|
| 321 |
resize: vertical;
|
|
@@ -369,7 +406,7 @@
|
|
| 369 |
|
| 370 |
.citation-panel {
|
| 371 |
background: var(--bg-surface);
|
| 372 |
-
border: 1px solid var(--border);
|
| 373 |
border-radius: 12px;
|
| 374 |
width: 480px;
|
| 375 |
max-height: 80vh;
|
|
@@ -397,7 +434,7 @@
|
|
| 397 |
.citation-panel-close {
|
| 398 |
background: none;
|
| 399 |
border: none;
|
| 400 |
-
color: var(--
|
| 401 |
font-size: 1.4rem;
|
| 402 |
cursor: pointer;
|
| 403 |
padding: 0;
|
|
@@ -405,7 +442,7 @@
|
|
| 405 |
}
|
| 406 |
|
| 407 |
.citation-panel-close:hover {
|
| 408 |
-
color: var(--text-
|
| 409 |
}
|
| 410 |
|
| 411 |
.citation-panel-body {
|
|
@@ -419,10 +456,10 @@
|
|
| 419 |
.citation-input {
|
| 420 |
width: 100%;
|
| 421 |
padding: 0.55rem 0.75rem;
|
| 422 |
-
border: 1px solid var(--border);
|
| 423 |
border-radius: 6px;
|
| 424 |
-
background: var(--
|
| 425 |
-
color: var(--text-
|
| 426 |
font-size: 0.8125rem;
|
| 427 |
font-family: inherit;
|
| 428 |
outline: none;
|
|
@@ -504,7 +541,7 @@
|
|
| 504 |
}
|
| 505 |
|
| 506 |
.citation-library-item:hover {
|
| 507 |
-
background: var(--
|
| 508 |
}
|
| 509 |
|
| 510 |
.citation-library-info {
|
|
@@ -516,13 +553,13 @@
|
|
| 516 |
}
|
| 517 |
|
| 518 |
.citation-library-meta {
|
| 519 |
-
color: var(--
|
| 520 |
font-size: 0.75rem;
|
| 521 |
font-weight: 500;
|
| 522 |
}
|
| 523 |
|
| 524 |
.citation-library-title {
|
| 525 |
-
color: var(--
|
| 526 |
font-size: 0.75rem;
|
| 527 |
white-space: nowrap;
|
| 528 |
overflow: hidden;
|
|
@@ -554,3 +591,37 @@
|
|
| 554 |
.citation-library-insert:hover {
|
| 555 |
background: var(--accent-bg-hover);
|
| 556 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
block handles, slash menu, upload UI, panels, etc.
|
| 7 |
----------------------------------------------------------------------- */
|
| 8 |
|
| 9 |
+
/* ---- Editor grid overrides ---- */
|
| 10 |
+
/* The template _layout.css defines .content-grid for the published
|
| 11 |
+
3-column layout (260px toc | 680px article | 260px).
|
| 12 |
+
The editor uses a different column ratio for the editing UI. */
|
| 13 |
+
|
| 14 |
+
.editor-app .content-grid {
|
| 15 |
+
grid-template-columns: 200px 1fr 240px;
|
| 16 |
+
grid-template-rows: auto 1fr;
|
| 17 |
+
max-width: none;
|
| 18 |
+
margin-top: 0;
|
| 19 |
+
padding: 0;
|
| 20 |
+
gap: 0;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
.content-grid__hero {
|
| 24 |
+
grid-column: 2;
|
| 25 |
+
grid-row: 1;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
.content-grid__toc {
|
| 29 |
+
grid-column: 1;
|
| 30 |
+
grid-row: 2;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.content-grid__editor {
|
| 34 |
+
grid-column: 2;
|
| 35 |
+
grid-row: 2;
|
| 36 |
+
padding-top: 24px;
|
| 37 |
+
padding-bottom: 32px;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.content-grid__comments {
|
| 41 |
+
grid-column: 3;
|
| 42 |
+
grid-row: 2;
|
| 43 |
+
padding: 16px 0 16px 16px;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
/* Math editing */
|
| 47 |
.tiptap [data-type="inline-math"] {
|
| 48 |
cursor: pointer;
|
|
|
|
| 56 |
font-family: "SFMono-Regular", "Fira Code", monospace;
|
| 57 |
font-size: 0.85em;
|
| 58 |
color: var(--code-text);
|
| 59 |
+
background: var(--code-bg);
|
| 60 |
padding: 0.1em 0.4em;
|
| 61 |
border-radius: 3px;
|
| 62 |
outline: none;
|
|
|
|
| 97 |
|
| 98 |
.comment-mark.resolved {
|
| 99 |
background: transparent;
|
| 100 |
+
border-bottom: 1px dashed var(--border-color);
|
| 101 |
}
|
| 102 |
|
| 103 |
/* Collaboration cursors */
|
|
|
|
| 136 |
|
| 137 |
/* Image upload card */
|
| 138 |
.image-upload-card {
|
| 139 |
+
border: 2px dashed var(--border-color);
|
| 140 |
border-radius: 12px;
|
| 141 |
padding: 2.5rem 1.5rem;
|
| 142 |
margin: 1em 0;
|
|
|
|
| 149 |
}
|
| 150 |
|
| 151 |
.image-upload-card:hover {
|
| 152 |
+
border-color: var(--muted-color);
|
| 153 |
background: var(--bg-hover);
|
| 154 |
}
|
| 155 |
|
|
|
|
| 188 |
}
|
| 189 |
|
| 190 |
.image-upload-btn.secondary {
|
| 191 |
+
background: var(--code-bg);
|
| 192 |
+
color: var(--muted-color);
|
| 193 |
}
|
| 194 |
|
| 195 |
.image-upload-btn.secondary:hover {
|
| 196 |
+
background: var(--code-bg);
|
| 197 |
+
color: var(--text-color);
|
| 198 |
}
|
| 199 |
|
| 200 |
.image-upload-card-hint {
|
|
|
|
| 215 |
.image-upload-url-input {
|
| 216 |
width: 100%;
|
| 217 |
padding: 0.5rem 0.75rem;
|
| 218 |
+
border: 1px solid var(--border-color);
|
| 219 |
border-radius: 6px;
|
| 220 |
+
background: var(--code-bg);
|
| 221 |
+
color: var(--text-color);
|
| 222 |
font-size: 0.8125rem;
|
| 223 |
font-family: inherit;
|
| 224 |
outline: none;
|
|
|
|
| 272 |
}
|
| 273 |
|
| 274 |
.block-handle-btn:hover {
|
| 275 |
+
color: var(--muted-color);
|
| 276 |
+
background: var(--code-bg);
|
| 277 |
}
|
| 278 |
|
| 279 |
.block-handle-grip {
|
|
|
|
| 287 |
/* Slash menu */
|
| 288 |
.slash-menu {
|
| 289 |
background: var(--bg-surface);
|
| 290 |
+
border: 1px solid var(--border-color);
|
| 291 |
border-radius: 10px;
|
| 292 |
padding: 0.35rem;
|
| 293 |
min-width: 220px;
|
|
|
|
| 307 |
background: none;
|
| 308 |
width: 100%;
|
| 309 |
text-align: left;
|
| 310 |
+
color: var(--text-color);
|
| 311 |
font-size: 0.875rem;
|
| 312 |
font-family: inherit;
|
| 313 |
}
|
| 314 |
|
| 315 |
.slash-menu-item:hover,
|
| 316 |
.slash-menu-item.is-selected {
|
| 317 |
+
background: var(--code-bg);
|
| 318 |
}
|
| 319 |
|
| 320 |
.slash-menu-item-icon {
|
|
|
|
| 324 |
align-items: center;
|
| 325 |
justify-content: center;
|
| 326 |
border-radius: 6px;
|
| 327 |
+
background: var(--code-bg);
|
| 328 |
+
color: var(--muted-color);
|
| 329 |
font-size: 0.9rem;
|
| 330 |
flex-shrink: 0;
|
| 331 |
}
|
|
|
|
| 337 |
|
| 338 |
.slash-menu-item-title {
|
| 339 |
font-weight: 500;
|
| 340 |
+
color: var(--text-color);
|
| 341 |
font-size: 0.875rem;
|
| 342 |
}
|
| 343 |
|
| 344 |
.slash-menu-item-desc {
|
| 345 |
font-size: 0.75rem;
|
| 346 |
+
color: var(--muted-color);
|
| 347 |
}
|
| 348 |
|
| 349 |
/* Footnote editing controls */
|
| 350 |
.footnote-tooltip-input {
|
| 351 |
width: 100%;
|
| 352 |
+
background: var(--code-bg);
|
| 353 |
+
border: 1px solid var(--border-color);
|
| 354 |
border-radius: 4px;
|
| 355 |
+
color: var(--text-color);
|
| 356 |
font-size: 12px;
|
| 357 |
padding: 6px 8px;
|
| 358 |
resize: vertical;
|
|
|
|
| 406 |
|
| 407 |
.citation-panel {
|
| 408 |
background: var(--bg-surface);
|
| 409 |
+
border: 1px solid var(--border-color);
|
| 410 |
border-radius: 12px;
|
| 411 |
width: 480px;
|
| 412 |
max-height: 80vh;
|
|
|
|
| 434 |
.citation-panel-close {
|
| 435 |
background: none;
|
| 436 |
border: none;
|
| 437 |
+
color: var(--muted-color);
|
| 438 |
font-size: 1.4rem;
|
| 439 |
cursor: pointer;
|
| 440 |
padding: 0;
|
|
|
|
| 442 |
}
|
| 443 |
|
| 444 |
.citation-panel-close:hover {
|
| 445 |
+
color: var(--text-color);
|
| 446 |
}
|
| 447 |
|
| 448 |
.citation-panel-body {
|
|
|
|
| 456 |
.citation-input {
|
| 457 |
width: 100%;
|
| 458 |
padding: 0.55rem 0.75rem;
|
| 459 |
+
border: 1px solid var(--border-color);
|
| 460 |
border-radius: 6px;
|
| 461 |
+
background: var(--code-bg);
|
| 462 |
+
color: var(--text-color);
|
| 463 |
font-size: 0.8125rem;
|
| 464 |
font-family: inherit;
|
| 465 |
outline: none;
|
|
|
|
| 541 |
}
|
| 542 |
|
| 543 |
.citation-library-item:hover {
|
| 544 |
+
background: var(--code-bg);
|
| 545 |
}
|
| 546 |
|
| 547 |
.citation-library-info {
|
|
|
|
| 553 |
}
|
| 554 |
|
| 555 |
.citation-library-meta {
|
| 556 |
+
color: var(--muted-color);
|
| 557 |
font-size: 0.75rem;
|
| 558 |
font-weight: 500;
|
| 559 |
}
|
| 560 |
|
| 561 |
.citation-library-title {
|
| 562 |
+
color: var(--muted-color);
|
| 563 |
font-size: 0.75rem;
|
| 564 |
white-space: nowrap;
|
| 565 |
overflow: hidden;
|
|
|
|
| 591 |
.citation-library-insert:hover {
|
| 592 |
background: var(--accent-bg-hover);
|
| 593 |
}
|
| 594 |
+
|
| 595 |
+
/* ---- Hero editable elements ---- */
|
| 596 |
+
|
| 597 |
+
.editable-text {
|
| 598 |
+
border-radius: 4px;
|
| 599 |
+
transition: background 0.15s;
|
| 600 |
+
padding: 2px 4px;
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
/* Negative margin to visually align padding - but NOT on elements
|
| 604 |
+
that rely on margin: auto for centering (e.g. .hero-desc). */
|
| 605 |
+
.editable-text:not(.hero-desc):not(.hero-title) {
|
| 606 |
+
margin: -2px -4px;
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
.editable-text:hover {
|
| 610 |
+
background: var(--bg-hover);
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
.author-editable {
|
| 614 |
+
cursor: pointer;
|
| 615 |
+
border-radius: 4px;
|
| 616 |
+
transition: background 0.15s;
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
.author-editable:hover {
|
| 620 |
+
background: var(--bg-hover);
|
| 621 |
+
}
|
| 622 |
+
|
| 623 |
+
.author-add-btn {
|
| 624 |
+
display: inline-flex;
|
| 625 |
+
align-items: center;
|
| 626 |
+
margin-left: 4px;
|
| 627 |
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* -----------------------------------------------------------------------
|
| 2 |
+
Table of contents - Editor overrides
|
| 3 |
+
|
| 4 |
+
Base styles are in components/_toc.css (from template).
|
| 5 |
+
This file adds editor-specific adjustments (smaller TOC column,
|
| 6 |
+
tighter padding, collapse animation).
|
| 7 |
+
----------------------------------------------------------------------- */
|
| 8 |
+
|
| 9 |
+
/* The template's _layout.css sets align-items:start on .content-grid,
|
| 10 |
+
which prevents grid cells from stretching. The TOC cell MUST stretch
|
| 11 |
+
to full row height so the sticky child has room to travel. */
|
| 12 |
+
.content-grid__toc {
|
| 13 |
+
align-self: stretch;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.content-grid__toc .table-of-contents--sticky {
|
| 17 |
+
position: sticky;
|
| 18 |
+
top: 0;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
/* Override the template's own sticky (handled by --sticky wrapper instead) */
|
| 22 |
+
.content-grid__toc .table-of-contents {
|
| 23 |
+
position: static;
|
| 24 |
+
margin-top: 0;
|
| 25 |
+
padding: 24px 8px 0;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
.content-grid__toc .table-of-contents .title {
|
| 29 |
+
font-size: 0.65rem;
|
| 30 |
+
text-transform: uppercase;
|
| 31 |
+
letter-spacing: 0.05em;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* Collapse animation for React-driven expand/collapse */
|
| 35 |
+
.toc-children {
|
| 36 |
+
overflow: hidden;
|
| 37 |
+
transition: max-height 200ms ease, opacity 200ms ease;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/* Ensure TOC empty message inherits article font */
|
| 41 |
+
.toc-empty {
|
| 42 |
+
font-size: 12px;
|
| 43 |
+
color: var(--muted-color);
|
| 44 |
+
padding-top: 4px;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
/* TOC title label */
|
| 48 |
+
.toc-title {
|
| 49 |
+
font-weight: 600;
|
| 50 |
+
font-size: 14px;
|
| 51 |
+
margin-bottom: 8px;
|
| 52 |
+
}
|
|
@@ -1,36 +1,47 @@
|
|
| 1 |
import { createTheme } from "@mui/material/styles";
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
},
|
| 10 |
-
|
| 11 |
-
|
|
|
|
| 12 |
},
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
secondary: "#888",
|
| 16 |
},
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
borderRadius: 8,
|
| 25 |
-
},
|
| 26 |
-
components: {
|
| 27 |
-
MuiIconButton: {
|
| 28 |
-
styleOverrides: {
|
| 29 |
-
root: {
|
| 30 |
-
borderRadius: 6,
|
| 31 |
-
padding: 6,
|
| 32 |
},
|
| 33 |
},
|
| 34 |
},
|
| 35 |
-
}
|
| 36 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import { createTheme } from "@mui/material/styles";
|
| 2 |
|
| 3 |
+
/**
|
| 4 |
+
* Build a MUI theme whose primary color matches the article's
|
| 5 |
+
* --primary-color CSS variable (stored in Yjs settings).
|
| 6 |
+
*/
|
| 7 |
+
export function buildTheme(primaryColor: string) {
|
| 8 |
+
return createTheme({
|
| 9 |
+
palette: {
|
| 10 |
+
mode: "dark",
|
| 11 |
+
background: {
|
| 12 |
+
default: "#0f0f0f",
|
| 13 |
+
paper: "#1a1a1a",
|
| 14 |
+
},
|
| 15 |
+
primary: {
|
| 16 |
+
main: primaryColor,
|
| 17 |
+
},
|
| 18 |
+
text: {
|
| 19 |
+
primary: "#e0e0e0",
|
| 20 |
+
secondary: "#888",
|
| 21 |
+
},
|
| 22 |
+
divider: "#2a2a2a",
|
| 23 |
},
|
| 24 |
+
typography: {
|
| 25 |
+
fontFamily:
|
| 26 |
+
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
| 27 |
},
|
| 28 |
+
shape: {
|
| 29 |
+
borderRadius: 8,
|
|
|
|
| 30 |
},
|
| 31 |
+
components: {
|
| 32 |
+
MuiIconButton: {
|
| 33 |
+
styleOverrides: {
|
| 34 |
+
root: {
|
| 35 |
+
borderRadius: 6,
|
| 36 |
+
padding: 6,
|
| 37 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
},
|
| 39 |
},
|
| 40 |
},
|
| 41 |
+
});
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
export const DEFAULT_HUE = 47;
|
| 45 |
+
export const DEFAULT_PRIMARY = "#c87533";
|
| 46 |
+
|
| 47 |
+
export const theme = buildTheme(DEFAULT_PRIMARY);
|