texlite 0.7.7 → 0.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ import { performance } from "node:perf_hooks";
5
5
  import { requireUser } from "../auth.js";
6
6
  import { accessibleProject, canEdit } from "../projects.js";
7
7
  import { resolveSourcePath, safeRelativePath, texFileStem } from "../files.js";
8
- import { captureCompileSnapshot, cleanCompileArtifacts, cleanCompileCache, compileProject, discardCompileSnapshot, hasCompileCache, publishCompileArtifacts, publishedCompileArtifacts } from "../compiler.js";
8
+ import { captureCompileSnapshot, cleanCompileArtifacts, cleanCompileCache, CompileCancelledError, compileProject, discardCompileSnapshot, hasCompileCache, publishCompileArtifacts, publishedCompileArtifacts } from "../compiler.js";
9
9
  import { parseCompileDiagnostics } from "../compileDiagnostics.js";
10
10
  import { pdfToSource, sourceToPdf } from "../synctex.js";
11
11
  import { availablePdf, compileRunPdf, compileMainFile, compilePdfUrl, isTextCompileArtifact, listCompileArtifacts, pdfLoadingMode, syncArtifacts } from "../compileArtifacts.js";
@@ -32,6 +32,10 @@ function pdfResponseMetadata(config, pdfPath) {
32
32
  function mainDocumentChangedError() {
33
33
  return httpError(409, "MAIN_DOCUMENT_CHANGED");
34
34
  }
35
+ function throwIfCompileCancelled(signal) {
36
+ if (signal.aborted)
37
+ throw new CompileCancelledError();
38
+ }
35
39
  class CompileSnapshotBusyError extends Error {
36
40
  code = "COMPILE_SNAPSHOT_BUSY";
37
41
  constructor() {
@@ -292,6 +296,21 @@ export function registerCompileRoutes(app, context) {
292
296
  throw httpError(404, "PROJECT_NOT_FOUND");
293
297
  } });
294
298
  });
299
+ app.post("/api/projects/:id/compile/cancel", async (request, reply) => {
300
+ const user = requireUser(request, reply, db);
301
+ if (!user)
302
+ return;
303
+ const { id } = request.params;
304
+ const project = accessibleProject(db, id, user);
305
+ if (!project || !canEdit(project))
306
+ return apiError(reply, 403, "COMPILE_FORBIDDEN");
307
+ const body = (request.body ?? {});
308
+ const mainFile = compileMainFile(config, id, project.main_file, body.mainFile);
309
+ if (!mainFile)
310
+ return apiError(reply, 400, "MAIN_DOCUMENT_INVALID");
311
+ const cancelled = compileCoordinator.cancel(id, mainFile);
312
+ return { cancelled: Boolean(cancelled), mainFile, runId: cancelled?.runId ?? null, status: cancelled?.status ?? null };
313
+ });
295
314
  app.post("/api/projects/:id/compile", async (request, reply) => {
296
315
  const requestStartedAt = performance.now();
297
316
  const user = requireUser(request, reply, db);
@@ -363,8 +382,8 @@ export function registerCompileRoutes(app, context) {
363
382
  if (currentGeneration !== snapshotGeneration)
364
383
  snapshotStale = true;
365
384
  };
366
- const broadcast = () => collaboration.signalCompileState(id, {
367
- mainFile, runId, status: phase, requestedBy, updatedAt: now(),
385
+ const broadcast = (stateRunId = runId) => collaboration.signalCompileState(id, {
386
+ mainFile, runId: stateRunId, status: phase, requestedBy, updatedAt: now(),
368
387
  ...(phase === "succeeded" && snapshotStale ? { stale: true } : {})
369
388
  });
370
389
  const result = await compileCoordinator.request({
@@ -380,19 +399,28 @@ export function registerCompileRoutes(app, context) {
380
399
  onDiscarded: () => {
381
400
  db.prepare("DELETE FROM compile_runs WHERE id = ? AND status = 'queued'").run(runId);
382
401
  },
402
+ onCancelled: () => {
403
+ phase = "failed";
404
+ db.prepare("UPDATE compile_runs SET status = 'failed', log = ?, finished_at = ? WHERE id = ? AND status IN ('queued', 'running')")
405
+ .run(new CompileCancelledError().message, now(), runId);
406
+ broadcast();
407
+ },
383
408
  // The compile reservation protects the shared compiler cache and
384
409
  // prevents Git/cleanup/deletion from replacing the project while
385
410
  // latexmk is running, but it deliberately does not occupy the ordinary
386
411
  // project queue for the duration of the subprocess.
387
- execute: async () => projectMutations.runCompile(id, async () => {
412
+ execute: async (signal) => projectMutations.runCompile(id, async () => {
388
413
  let snapshot = null;
389
414
  let snapshotMs = 0;
390
415
  const snapshotStartedAt = performance.now();
391
416
  try {
392
- // Refresh the cheap generation after waiting for any queued source
393
- // operation. This makes the no-op check safe when a Git/HTTP write
394
- // completed after admission but before this compile got a worker.
395
- const refreshed = await projectMutations.runSerialized(id, () => {
417
+ throwIfCompileCancelled(signal);
418
+ // Revalidate settings after queued source operations. Do not use the
419
+ // in-memory collaboration revision to skip before a snapshot: it is
420
+ // not a durable content version and can collide after a room restart
421
+ // or reconnect.
422
+ await projectMutations.runSerialized(id, () => {
423
+ throwIfCompileCancelled(signal);
396
424
  const currentProject = accessibleProject(db, id, user);
397
425
  if (!currentProject || !canEdit(currentProject)) {
398
426
  throw new Error("Project access changed while waiting for a source snapshot");
@@ -404,38 +432,9 @@ export function registerCompileRoutes(app, context) {
404
432
  throw mainDocumentChangedError();
405
433
  project = currentProject;
406
434
  mainFile = currentMainFile;
407
- return {
408
- generation: compileRequestGeneration(currentProject, collaboration.currentRevision(id), collaboration.currentGeneration(id), config.extraArgs)
409
- };
410
435
  });
411
- const currentGeneration = refreshed.generation;
412
- const publishedBeforeSnapshot = publishedCompileArtifacts(config, id, mainFile, mainFile === project.main_file);
413
- const publishedRunBeforeSnapshot = publishedBeforeSnapshot ? db.prepare(`SELECT id, status, log, finished_at
414
- FROM compile_runs WHERE id = ? AND project_id = ?`).get(publishedBeforeSnapshot.runId, id) : undefined;
415
- const latestRunBeforeSnapshot = db.prepare(`SELECT id, status FROM compile_runs
416
- WHERE project_id = ? AND main_file = ? AND id <> ? ORDER BY created_at DESC LIMIT 1`).get(id, mainFile, runId);
417
- const activeRunBeforeSnapshot = db.prepare(`SELECT 1 AS active FROM compile_runs
418
- WHERE project_id = ? AND main_file = ? AND id <> ? AND status IN ('queued', 'running') LIMIT 1`).get(id, mainFile, runId);
419
- if (!activeRunBeforeSnapshot && publishedBeforeSnapshot?.generation === currentGeneration
420
- && publishedRunBeforeSnapshot?.status === "succeeded"
421
- && latestRunBeforeSnapshot?.id === publishedRunBeforeSnapshot.id
422
- && hasCompileCache(config, id, mainFile)) {
423
- db.prepare("DELETE FROM compile_runs WHERE id = ? AND status = 'queued'").run(runId);
424
- phase = "succeeded";
425
- broadcast();
426
- return {
427
- runId: publishedBeforeSnapshot.runId,
428
- ok: true,
429
- skipped: true,
430
- log: publishedRunBeforeSnapshot.log ?? "",
431
- diagnostics: parseCompileDiagnostics(publishedRunBeforeSnapshot.log ?? "", "succeeded"),
432
- pdfPath: null,
433
- synctexPath: publishedBeforeSnapshot.synctex,
434
- revision: publishedBeforeSnapshot.revision,
435
- snapshotMs: 0
436
- };
437
- }
438
436
  const captured = await projectMutations.runSerialized(id, async () => {
437
+ throwIfCompileCancelled(signal);
439
438
  const currentProject = accessibleProject(db, id, user);
440
439
  if (!currentProject || !canEdit(currentProject)) {
441
440
  throw new Error("Project access changed while waiting for a source snapshot");
@@ -469,6 +468,7 @@ export function registerCompileRoutes(app, context) {
469
468
  extraArgs: config.extraArgs,
470
469
  generation: generationKey
471
470
  });
471
+ throwIfCompileCancelled(signal);
472
472
  }
473
473
  catch (error) {
474
474
  captureError = error;
@@ -508,6 +508,7 @@ export function registerCompileRoutes(app, context) {
508
508
  throw new CompileSnapshotBusyError();
509
509
  }, { flush: false });
510
510
  snapshot = captured;
511
+ throwIfCompileCancelled(signal);
511
512
  snapshotMs = performance.now() - snapshotStartedAt;
512
513
  metrics.record("compile.snapshot", snapshotMs);
513
514
  const published = publishedCompileArtifacts(config, id, mainFile, mainFile === project.main_file);
@@ -526,7 +527,9 @@ export function registerCompileRoutes(app, context) {
526
527
  snapshot = null;
527
528
  db.prepare("DELETE FROM compile_runs WHERE id = ? AND status = 'queued'").run(runId);
528
529
  phase = "succeeded";
529
- broadcast();
530
+ // The probe row was deleted, so broadcast the retained run that
531
+ // clients can actually resolve from SQLite and the manifest.
532
+ broadcast(published.runId);
530
533
  return {
531
534
  runId: published.runId,
532
535
  ok: true,
@@ -545,15 +548,17 @@ export function registerCompileRoutes(app, context) {
545
548
  broadcast();
546
549
  let compiled;
547
550
  try {
548
- compiled = await compileProject(config, snapshot, mainFile, project.engine, project.latexmkrc);
551
+ compiled = await compileProject(config, snapshot, mainFile, project.engine, project.latexmkrc, { signal });
549
552
  refreshSnapshotStale();
550
553
  if (compiled.ok && compiled.pdfPath) {
554
+ throwIfCompileCancelled(signal);
551
555
  const publishStartedAt = performance.now();
552
556
  // Publishing is short and atomic, but still goes through the
553
557
  // ordinary project queue so it cannot overlap a source-tree
554
558
  // archive/read or another output mutation. The long latexmk
555
559
  // process above remains outside that queue.
556
560
  await projectMutations.runSerialized(id, () => {
561
+ throwIfCompileCancelled(signal);
557
562
  if (!db.prepare("SELECT 1 FROM projects WHERE id = ?").get(id)) {
558
563
  throw new Error("Project was deleted before compile artifacts could be published.");
559
564
  }
@@ -576,12 +581,19 @@ export function registerCompileRoutes(app, context) {
576
581
  snapshot = null;
577
582
  compiled = {
578
583
  ok: false,
584
+ ...(error instanceof CompileCancelledError ? { cancelled: true } : {}),
579
585
  log: error instanceof Error ? error.message : String(error),
580
586
  diagnostics: parseCompileDiagnostics(error instanceof Error ? error.message : String(error), "failed"),
581
587
  pdfPath: null,
582
588
  synctexPath: null
583
589
  };
584
590
  }
591
+ // A killed latexmk can leave an incomplete dependency database in
592
+ // the incremental cache. Keep the last published PDF, but make the
593
+ // next requested compile a clean rebuild instead of trusting that
594
+ // partial state.
595
+ if (compiled.cancelled)
596
+ cleanCompileCache(config, id, mainFile);
585
597
  phase = compiled.ok ? "succeeded" : "failed";
586
598
  db.prepare("UPDATE compile_runs SET status = ?, log = ?, finished_at = ? WHERE id = ?")
587
599
  .run(phase, compiled.log, now(), runId);
@@ -617,6 +629,7 @@ export function registerCompileRoutes(app, context) {
617
629
  broadcast();
618
630
  return {
619
631
  ok: false,
632
+ ...(error instanceof CompileCancelledError ? { cancelled: true } : {}),
620
633
  log,
621
634
  diagnostics: parseCompileDiagnostics(log, "failed"),
622
635
  pdfPath: null,
@@ -660,7 +673,7 @@ export function registerCompileRoutes(app, context) {
660
673
  `total;dur=${timingDuration(requestMs)}`
661
674
  ].filter(Boolean).join(", "));
662
675
  return {
663
- mainFile, runId: result.runId, ok: result.ok, skipped: result.skipped === true, log: result.log, diagnostics: result.diagnostics,
676
+ mainFile, runId: result.runId, ok: result.ok, cancelled: result.cancelled === true, skipped: result.skipped === true, log: result.log, diagnostics: result.diagnostics,
664
677
  pdfUrl: result.ok ? compilePdfUrl(id, mainFile, result.runId) : null,
665
678
  pdfCompiledAt: result.ok ? completed?.finished_at ?? null : null,
666
679
  ...pdfMetadata,
@@ -212,6 +212,14 @@ export function registerProjectFileRoutes(app, context) {
212
212
  return apiError(reply, 404, "PATH_NOT_FOUND", { path: source });
213
213
  if (destination === source)
214
214
  return { ok: true, path: source };
215
+ // Moving the configured root to (for example) main.tex.bak used to
216
+ // silently store that non-TeX path as main_file. The next compilation
217
+ // then failed long after the rename had appeared to succeed. Keep the
218
+ // current root a TeX file; users can first select another root document
219
+ // in project settings when they genuinely want to retire this one.
220
+ if (source === project.main_file && !/\.tex$/i.test(destination)) {
221
+ return apiError(reply, 400, "MAIN_DOCUMENT_INVALID");
222
+ }
215
223
  const initialSourceStat = fs.statSync(sourceAbsolute);
216
224
  if (initialSourceStat.isDirectory() && (destinationDirectory === source || destinationDirectory.startsWith(`${source}/`))) {
217
225
  return apiError(reply, 400, "MOVE_INTO_SELF", { path: source });
@@ -229,6 +237,9 @@ export function registerProjectFileRoutes(app, context) {
229
237
  const validateMove = () => {
230
238
  currentProject = requireEditableProject(db, id, user);
231
239
  assertNoSourceSymlinks(config, id);
240
+ if (source === currentProject.main_file && !/\.tex$/i.test(destination)) {
241
+ throw httpError(400, "MAIN_DOCUMENT_INVALID");
242
+ }
232
243
  if (!fs.existsSync(sourceAbsolute)) {
233
244
  throw httpError(404, "PATH_NOT_FOUND", { path: source });
234
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "texlite",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "description": "A lightweight local-first collaborative LaTeX workspace",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- import{u as A,r,j as e}from"./react-BoEjKzFZ.js";import{j as B,a as R,M as F,o as $,L as I,p as J,n as K,F as V,q as G}from"./index-zIjCeZFK.js";const L=B("Replace",[["path",{d:"M14 4a2 2 0 0 1 2-2",key:"1w2hp7"}],["path",{d:"M16 10a2 2 0 0 1-2-2",key:"shjach"}],["path",{d:"M20 2a2 2 0 0 1 2 2",key:"188mtx"}],["path",{d:"M22 8a2 2 0 0 1-2 2",key:"ddf4tu"}],["path",{d:"m3 7 3 3 3-3",key:"x25e72"}],["path",{d:"M6 10V5a3 3 0 0 1 3-3h1",key:"3y3t5z"}],["rect",{x:"2",y:"14",width:"8",height:"8",rx:"2",key:"4rksxw"}]]);function Z({open:i,files:u,onOpenChange:l,onOpenFile:p}){const{t:a}=A(),[n,m]=r.useState(""),[d,o]=r.useState(0),f=r.useRef(null),h=r.useMemo(()=>u.filter(t=>t.type==="file").map(t=>({entry:t,score:H(t.path,n)})).filter(t=>t.score>=0).sort((t,c)=>c.score-t.score||t.entry.path.localeCompare(c.entry.path)).slice(0,100),[u,n]);r.useEffect(()=>{i&&(m(""),o(0),window.setTimeout(()=>f.current?.focus(),0))},[i]),r.useEffect(()=>o(t=>Math.min(t,Math.max(0,h.length-1))),[h.length]);const x=t=>{p(t),l(!1)};return e.jsx(F,{open:i,wide:!0,title:a("navigation.quickOpen"),description:a("navigation.quickOpenDescription"),onOpenChange:l,children:e.jsxs("div",{className:"quick-open-dialog",children:[e.jsxs("label",{children:[e.jsx($,{size:16}),e.jsx("input",{ref:f,value:n,placeholder:a("navigation.filePlaceholder"),onChange:t=>{m(t.target.value),o(0)},onKeyDown:t=>{t.key==="ArrowDown"&&(t.preventDefault(),o(c=>Math.min(h.length-1,c+1))),t.key==="ArrowUp"&&(t.preventDefault(),o(c=>Math.max(0,c-1))),t.key==="Enter"&&h[d]&&(t.preventDefault(),x(h[d].entry.path))}})]}),e.jsxs("div",{className:"quick-open-results",children:[h.map(({entry:t},c)=>e.jsxs("button",{className:c===d?"active":"",onMouseEnter:()=>o(c),onClick:()=>x(t.path),children:[e.jsx(V,{size:14}),e.jsx("span",{children:t.path}),c===d&&e.jsx(G,{size:13})]},t.path)),h.length===0&&e.jsx("p",{className:"muted padded",children:a("navigation.noFiles")})]})]})})}function _({open:i,project:u,onOpenChange:l,onJump:p}){const{t:a}=A(),[n,m]=r.useState(""),[d,o]=r.useState(""),[f,h]=r.useState(!1),[x,t]=r.useState(!1),[c,w]=r.useState([]),[v,C]=r.useState(0),[P,D]=r.useState(!1),[b,S]=r.useState(!1),[W,N]=r.useState(!1),[q,M]=r.useState(""),[z,k]=r.useState(""),[O,Q]=r.useState(0),y=r.useRef(null);r.useEffect(()=>{if(!i){y.current?.abort();return}if(M(""),k(""),!n.trim()){w([]),C(0),D(!1);return}const s=window.setTimeout(()=>{y.current?.abort();const j=new AbortController;y.current=j,S(!0);const E=new URLSearchParams({q:n});f&&E.set("caseSensitive","1"),x&&E.set("wholeWord","1"),R(`/api/projects/${u.id}/search?${E}`,{signal:j.signal}).then(g=>{w(g.matches),C(g.total),D(g.truncated)}).catch(g=>{g instanceof DOMException&&g.name==="AbortError"||k(T(g))}).finally(()=>{y.current===j&&(y.current=null,S(!1))})},250);return()=>window.clearTimeout(s)},[i,u.id,n,f,x,O]);const U=async()=>{N(!1),S(!0),k(""),M("");try{const s=await R(`/api/projects/${u.id}/search/replace`,{method:"POST",body:JSON.stringify({query:n,replacement:d,caseSensitive:f,wholeWord:x})});M(a("navigation.replaced",{count:s.replacements,files:s.files.length})),w([]),C(0),Q(j=>j+1)}catch(s){k(T(s))}finally{S(!1)}};return e.jsxs(e.Fragment,{children:[e.jsx(F,{open:i,extraWide:!0,title:a("navigation.projectSearch"),description:a("navigation.projectSearchDescription"),onOpenChange:l,footer:e.jsx("button",{onClick:()=>l(!1),children:a("common.close")}),children:e.jsxs("div",{className:"project-search-dialog",children:[z&&e.jsx("p",{className:"error",children:z}),q&&e.jsx("p",{className:"success",children:q}),e.jsxs("div",{className:"project-search-form",children:[e.jsxs("label",{className:"project-search-query",children:[e.jsx($,{size:16}),e.jsx("input",{autoFocus:!0,value:n,placeholder:a("navigation.searchPlaceholder"),onChange:s=>m(s.target.value)})]}),u.permission!=="read"&&e.jsxs("label",{className:"project-search-query",children:[e.jsx(L,{size:16}),e.jsx("input",{value:d,placeholder:a("navigation.replacePlaceholder"),onChange:s=>o(s.target.value)})]}),e.jsxs("div",{className:"project-search-options",children:[e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:f,onChange:s=>h(s.target.checked)}),a("editor.search.matchCase")]}),e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:x,onChange:s=>t(s.target.checked)}),a("editor.search.wholeWord")]}),u.permission!=="read"&&e.jsxs("button",{className:"danger-text",disabled:!n.trim()||v===0||b,onClick:()=>N(!0),children:[e.jsx(L,{size:13}),a("navigation.replaceAll",{count:v})]})]})]}),e.jsxs("div",{className:"project-search-summary",children:[e.jsx("span",{children:b?e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"spin",size:13}),a("common.loading")]}):a("navigation.matchSummary",{count:v})}),P&&e.jsx("small",{children:a("navigation.truncated",{count:c.length})})]}),e.jsxs("div",{className:"project-search-results",children:[c.map((s,j)=>e.jsxs("button",{onClick:()=>{p(s.path,s.line,s.column),l(!1)},children:[e.jsx(J,{size:14}),e.jsxs("span",{children:[e.jsxs("strong",{children:[s.path,e.jsxs("small",{children:[":",s.line,":",s.column]})]}),e.jsxs("code",{children:[s.preview.slice(0,s.matchStart),e.jsx("mark",{children:s.preview.slice(s.matchStart,s.matchEnd)}),s.preview.slice(s.matchEnd)]})]})]},`${s.path}-${s.line}-${s.column}-${j}`)),!b&&n.trim()&&c.length===0&&e.jsx("p",{className:"muted padded",children:a("editor.search.noMatches")})]})]})}),e.jsx(K,{open:W,title:a("navigation.replaceConfirmTitle"),description:a("navigation.replaceConfirmDescription",{count:v}),confirmLabel:a("navigation.replaceAll",{count:v}),danger:!0,onCancel:()=>N(!1),onConfirm:()=>{U()}})]})}function H(i,u){const l=i.toLocaleLowerCase(),p=u.trim().toLocaleLowerCase();if(!p)return 1;const a=l.indexOf(p);if(a>=0)return 1e4-a-l.length;let n=0,m=0;for(const d of p){const o=l.indexOf(d,n);if(o<0)return-1;m+=o===n?5:1,n=o+1}return m-l.length/100}function T(i){return i instanceof Error?i.message:String(i)}export{_ as ProjectSearchDialog,Z as QuickOpenDialog};
@@ -1 +0,0 @@
1
- :root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;color:#202421;background:#f3f4f1;font-synthesis:none}*{box-sizing:border-box}html,body,#root{margin:0;min-height:100%}button,input,select,textarea{font:inherit}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.45}.muted{color:#737a75}.error{color:#b3261e;font-size:14px}.dialog-error{margin:0;padding:8px 10px;border:1px solid #e9b6b0;border-radius:6px;background:#fff3f1}.field-hint{color:#778179;font-size:11px;font-weight:400}.primary,.compile{border:0;border-radius:8px;background:#176b44;color:#fff;padding:10px 18px;font-weight:650}.icon-button{display:inline-flex;align-items:center;gap:6px}.ghost{border:0;background:transparent;color:inherit}.page{min-height:100vh;display:flex;flex-direction:column}.login-page{min-height:100vh;display:grid;grid-template-rows:1fr auto;place-items:center;padding-top:44px;background:radial-gradient(circle at 50% 0,#d8e8dd,#f5f5f1 45%)}.login-card{width:min(390px,calc(100vw - 32px));padding:38px;display:flex;flex-direction:column;gap:16px;background:#ffffffeb;border:1px solid #dfe4df;border-radius:16px;box-shadow:0 24px 70px #1d31241f}.login-card h1{text-align:center;margin:0;letter-spacing:-.04em}.login-card>p{text-align:center;margin:-8px 0 8px}.login-card label,.settings label{display:flex;flex-direction:column;gap:7px;font-size:13px;font-weight:650}.login-card input,.settings input,.settings select,.settings textarea{width:100%;border:1px solid #cbd2cc;border-radius:8px;padding:10px 11px;background:#fff;outline:none}.login-card input:focus,.settings input:focus{border-color:#176b44;box-shadow:0 0 0 3px #176b4420}.site-logo{width:40px;height:40px;flex:none;display:inline-flex;align-items:center;justify-content:center}.site-logo img{display:block;width:100%;height:100%}.site-logo.compact{width:34px;height:34px;margin:0 16px 0 10px}.site-logo.auth-logo{width:76px;height:76px;margin:0 auto 2px;filter:drop-shadow(0 10px 18px #1e2a4a25)}.brand-link{display:inline-flex;align-items:center;color:inherit;text-decoration:none}.brand-link:hover .site-title{color:#d9f0df}.compact-brand-link{flex:none}.site-title{margin-right:11px;font-size:20px;font-weight:800;letter-spacing:-.04em}.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.support{color:#737a75;text-align:center}.topbar,.editor-topbar{height:62px;display:flex;align-items:center;padding:0 26px;background:#123c2a;color:#fff}.top-actions{margin-left:auto;display:flex;align-items:center;gap:18px;font-size:14px}.top-actions .ghost{display:inline-flex;align-items:center;gap:5px;border:1px solid transparent;border-radius:6px;padding:6px 8px;background:transparent;color:inherit;transition:background .15s ease,border-color .15s ease,box-shadow .15s ease,color .15s ease,transform .08s ease}.top-actions .ghost:hover,.top-actions .ghost:focus-visible{border-color:#ffffff20;background:#ffffff16;color:#d9f0df;box-shadow:0 4px 12px #061c1130;outline:none}.top-actions .ghost:active{transform:translateY(1px);box-shadow:0 1px 4px #061c1126}.top-actions .ghost.top-return-action,.top-actions .ghost.top-return-action:hover,.top-actions .ghost.top-return-action:focus-visible,.top-actions .ghost.top-return-action:active{transform:none;box-shadow:none}.top-user-identity{min-width:0;display:flex;flex-direction:column;line-height:1.15}.top-user-identity strong{overflow:hidden;max-width:180px;font-size:13px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.top-user-identity small{overflow:hidden;max-width:180px;margin-top:3px;color:#b9d0c2;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.language-switcher{position:fixed;top:18px;right:20px;z-index:5;display:flex;align-items:center;gap:6px;color:#536059;font-size:12px}.language-switcher select{border:1px solid #c9d0ca;border-radius:6px;padding:5px 7px;background:#fff;color:#26342b}.language-switcher.compact{position:static;color:inherit}.language-switcher.compact select{border-color:#ffffff35;background:#ffffff10;color:inherit}.language-switcher.compact option{color:#202421}.dashboard{width:100%;max-width:1180px;flex:1;margin:0 auto;padding:52px 34px}.citation-library-page-shell{padding-top:34px}.citation-library-page{display:flex;flex-direction:column;gap:18px}.citation-library-page-header{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}.citation-library-page-header>div{min-width:0}.citation-library-page-header h1{display:flex;align-items:center;gap:9px;margin:0;color:#202421;font-size:30px;letter-spacing:-.04em}.citation-library-page-header h1 svg{flex:none;color:#315b43}.citation-library-page-header p{max-width:720px;margin:8px 0 0;color:#737a75;font-size:12px;line-height:1.5}.citation-library-page-header>button{display:inline-flex;align-items:center;gap:5px;flex:none;border:1px solid #bfc8c1;border-radius:8px;padding:9px 12px;background:#fff;color:#52685a;font-size:11px}.citation-library-page-header>button:hover{border-color:#8eaa98;background:#edf4ef;color:#176b44}.citation-library-page .citation-library-dialog{padding:18px;border:1px solid #dfe4df;border-radius:12px;background:#fff;box-shadow:0 8px 26px #25352a0f}.citation-library-page .citation-entry-list{max-height:none}.citation-library-pagination{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:6px;color:#66736b;font-size:10px}.citation-library-pagination button{display:inline-flex;align-items:center;gap:4px;border:1px solid #cbd5ce;border-radius:6px;padding:6px 9px;background:#fff;color:#52685a;font-size:10px}.citation-library-pagination button:hover:not(:disabled){border-color:#8eaa98;background:#edf4ef;color:#176b44}.site-footer{width:100%;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:7px 16px;padding:18px 24px;border-top:1px solid #dfe3df;background:#eef0ed;color:#737b75;font-size:11px;text-align:center}.site-footer a{color:#176b44;text-decoration:none}.site-footer a:hover{text-decoration:underline}.login-page>.site-footer{align-self:end;background:#ffffff50}.section-title{display:flex;justify-content:space-between;align-items:end;margin-bottom:28px}.section-title h1{display:flex;align-items:center;gap:9px;margin:0;font-size:30px;letter-spacing:-.04em}.section-title h1 svg{flex:none;color:#315b43}.section-title p{margin:7px 0 0}.section-actions{display:flex;gap:9px}.section-actions>button{display:inline-flex;align-items:center;gap:6px;border:1px solid #bfc8c1;border-radius:8px;background:#fff;padding:10px 16px}.section-actions>.primary{border-color:#176b44;background:#176b44;color:#fff}.project-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin-bottom:18px;padding:10px;background:#e9ece8;border-radius:10px}.project-toolbar>input{width:220px;border:1px solid #cbd2cc;border-radius:7px;padding:8px 10px;background:#fff}.project-scope{display:flex;flex:none;gap:2px}.project-scope button{display:flex;align-items:center;gap:5px;flex:none;border:1px solid transparent;border-radius:7px;padding:7px 9px;background:transparent;color:#536059;font-size:12px}.project-scope button.active{border-color:#b8c4ba;background:#fff;color:#174b33}.tag-filters{min-width:0;flex:1;display:flex;gap:6px;overflow-x:auto}.tag-filters button,.view-toggle button{display:flex;align-items:center;gap:5px;flex:none;border:1px solid transparent;border-radius:7px;padding:7px 9px;background:transparent;color:#536059;font-size:12px}.tag-filters button.active,.view-toggle button.active{border-color:#b8c4ba;background:#fff;color:#174b33}.project-sort{flex:none;display:flex;align-items:center;gap:5px;color:#536059;font-size:11px}.project-sort>span{white-space:nowrap}.project-sort select{max-width:150px;border:1px solid #c4ccc6;border-radius:7px;padding:7px 25px 7px 8px;background:#fff;color:#34433a;font-size:12px}.view-toggle{display:flex;gap:2px}.project-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:16px}.project-card{position:relative;min-height:250px;display:flex;flex-direction:column;text-align:left;background:#fff;border:1px solid #dfe2de;border-radius:12px;overflow:hidden;transition:.15s ease}.project-card:hover{border-color:#8bae9a;transform:translateY(-2px);box-shadow:0 10px 30px #25352a10}.project-card-open{all:unset;box-sizing:border-box;min-width:0;flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:20px 20px 14px;cursor:pointer}.project-card-open:focus-visible{outline:3px solid #176b4455;outline-offset:-3px}.project-card strong{font-size:17px}.project-card-main{min-width:0;display:flex;flex-direction:column;gap:7px}.project-tags,.settings-tags{display:flex;flex-wrap:wrap;gap:5px}.owner-badge{max-width:100%;overflow:hidden;padding:6px 9px;border-radius:7px;background:#e2f0e7;color:#176b44;font-size:11px;font-weight:750;text-overflow:ellipsis;white-space:nowrap}.project-grid:not(.list-view) .owned-project .owner-badge{max-width:calc(100% - 94px)}.project-transfer-action{position:absolute;z-index:2;top:17px;right:16px;display:inline-flex;align-items:center;gap:4px;border:1px solid #cbd7cf;border-radius:6px;padding:5px 7px;background:#f7faf8;color:#315c43;font-size:10px}.project-transfer-action:hover{border-color:#8caf99;background:#e8f1eb;color:#176b44}.project-meta{width:100%;display:grid;grid-template-columns:1fr;gap:8px;margin:auto 0 0}.project-meta div{min-width:0}.project-meta dt{display:flex;align-items:center;gap:4px;color:#8a918c;font-size:10px;text-transform:uppercase}.project-meta dt svg{flex:none;color:#6f8e7a}.project-meta dd{overflow:hidden;margin:2px 0 0;color:#555e58;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.project-grid:not(.list-view) .project-meta dd{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.project-modified-by{color:#68716b}.project-card-actions{display:flex;flex-wrap:wrap;gap:5px;padding:9px 12px;border-top:1px solid #eceeeb;background:#fafbf9}.project-card-actions button,.project-card-actions a{display:inline-flex;align-items:center;gap:5px;border:0;border-radius:5px;padding:5px 7px;background:transparent;color:#4f5b53;font-size:11px;text-decoration:none}.project-card-actions button:hover,.project-card-actions a:hover{background:#e8eeea;color:#176b44}.project-card-actions .danger-text{margin-left:auto;color:#b3261e}.project-grid:not(.list-view) .project-card-actions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}.project-grid:not(.list-view) .project-card-actions button,.project-grid:not(.list-view) .project-card-actions a{width:100%;min-width:0;justify-content:flex-start;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.project-grid:not(.list-view) .project-card-actions .danger-text{margin-left:0}.project-grid.list-view{display:flex;flex-direction:column;gap:7px}.project-grid.list-view .project-card{min-height:88px;flex-direction:row;align-items:stretch}.project-grid.list-view .project-card-open{display:grid;grid-template-columns:minmax(90px,140px) minmax(170px,1fr) minmax(390px,2fr);align-items:center;gap:14px;padding:12px 15px}.project-grid.list-view .project-card-main{min-width:170px}.project-grid.list-view .project-meta{grid-template-columns:minmax(145px,.75fr) minmax(0,1.25fr);gap:8px 12px;margin:0}.project-grid.list-view .project-meta>div:last-child dd{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.project-grid.list-view .project-card-actions{width:190px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-content:center;gap:4px;border-top:0;border-left:1px solid #eceeeb}.project-grid.list-view .project-card-actions button,.project-grid.list-view .project-card-actions a{width:100%;justify-content:flex-start}.project-grid.list-view .project-card-actions .danger-text{margin-left:0}.project-comments-badge{display:inline-flex;align-items:center;gap:3px;width:fit-content;border-radius:999px;padding:1px 6px;font-size:10px;font-weight:650;line-height:1.4}.project-comments-badge.unresolved{background:#fde8e7;color:#b3261e;border:1px solid #f8c8c5}.tag{display:inline-flex;align-items:center;gap:4px;width:fit-content;border-radius:999px;padding:2px 7px;background:#eef0ee;color:#4a524c;font-size:10px;font-weight:650}.tag-dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:currentColor}.tag-red{--tag-color: #e04b45}.tag-orange{--tag-color: #ef9135}.tag-yellow{--tag-color: #dbb62f}.tag-green{--tag-color: #49a563}.tag-blue{--tag-color: #4c83db}.tag-purple{--tag-color: #9566ce}.tag-gray{--tag-color: #929994}.tag-dot[class*=tag-]{color:var(--tag-color)}.tag[class*=tag-]{border:1px solid color-mix(in srgb,var(--tag-color) 35%,transparent);background:color-mix(in srgb,var(--tag-color) 12%,white)}.empty,.center-card{padding:50px;color:#737a75;text-align:center}.project-empty{grid-column:1 / -1;width:100%;min-height:320px;display:flex;align-items:center;justify-content:center;flex-direction:column;box-sizing:border-box;padding:64px 24px;border:1px dashed #cbd7ce;border-radius:14px;background:linear-gradient(145deg,#fbfcfa,#f2f7f3);text-align:center}.project-empty-icon{width:58px;height:58px;display:grid;place-items:center;margin-bottom:18px;border-radius:18px;background:#dfeee4;color:#176b44}.project-empty h2{margin:0;color:#203f2e;font-size:clamp(27px,3vw,38px);line-height:1.15;letter-spacing:-.035em}.project-empty p{max-width:520px;margin:13px 0 0;color:#6e7b72;font-size:15px;line-height:1.6}.project-pagination{display:flex;align-items:center;justify-content:center;gap:12px;margin:22px 0 4px;color:#66726a;font-size:12px}.project-pagination button{display:inline-flex;align-items:center;gap:5px;border:1px solid #cbd4ce;border-radius:7px;padding:7px 10px;background:#fff;color:#405248;font-size:12px}.project-pagination button:hover:not(:disabled){border-color:#8bae9a;background:#f2f7f3;color:#176b44}.table-card{overflow:hidden;background:#fff;border:1px solid #dfe2de;border-radius:12px}table{width:100%;border-collapse:collapse}th,td{padding:14px 18px;border-bottom:1px solid #eceeeb;text-align:left;font-size:14px}th{background:#f8f9f7;color:#667069;font-size:12px;text-transform:uppercase}td small{display:block;color:#7d837f;margin-top:3px}td button{margin-right:8px;border:1px solid #cdd2ce;background:#fff;border-radius:5px;padding:5px 9px}.danger-text{color:#b3261e}.workspace{height:100vh;display:flex;flex-direction:column;overflow:hidden}.editor-topbar{height:56px;padding:0 14px;flex:none}.back{color:#fff;border:0;background:#ffffff10;width:32px;height:32px;display:grid;place-items:center;border-radius:6px}.project-heading{display:flex;flex-direction:column;min-width:0;margin-right:auto}.project-heading small{color:#b9d0c2;font-size:11px;margin-top:2px}.vim-status-badge{display:inline-flex;align-items:center;gap:5px;margin-right:8px;border:1px solid #7fd39e80;border-radius:999px;padding:5px 9px;background:#1d6b4638;color:#d7ffe3;font-size:10px;font-weight:750;letter-spacing:.04em;white-space:nowrap}.vim-status-badge svg{color:#9df0b5}.collaboration-presence{min-width:0;display:flex;align-items:center;gap:7px;padding-left:8px}.collaboration-status-dot{width:7px;height:7px;flex:none;border-radius:50%;background:#efb84b;box-shadow:0 0 0 2px #efb84b2e}.collaboration-connected .collaboration-status-dot{background:#69d391;box-shadow:0 0 0 2px #69d3912e}.collaboration-disconnected .collaboration-status-dot{background:#e07167;box-shadow:0 0 0 2px #e071672e}.collaboration-avatars{display:flex;align-items:center;padding-left:8px}.collaboration-avatar{--session-color: #1677c8;position:relative;width:28px;height:28px;display:grid;place-items:center;margin-left:-8px;border:2px solid #214d35;border-radius:50%;background:var(--session-color);color:#fff;font-size:11px;font-weight:750;cursor:default;box-shadow:0 1px 4px #061c1145}.collaboration-avatar.editing:after{content:"";position:absolute;right:-2px;bottom:-2px;width:7px;height:7px;border:2px solid #214d35;border-radius:50%;background:#8ff0af}.collaboration-avatar.local{outline:1px solid #ffffff8a;outline-offset:-4px}.collaboration-avatar-overflow{appearance:none;padding:0;border-color:#72877b;background:#f4f7f5;color:#284536;font-family:inherit;font-size:10px;cursor:pointer}.collaboration-avatar-overflow:hover,.collaboration-avatar-overflow:focus-visible{background:#dfe9e3;outline:2px solid #9bc6aa;outline-offset:1px}.collaboration-avatar-tooltip{position:absolute;z-index:80;top:calc(100% + 9px);right:-8px;width:max-content;max-width:280px;display:none;gap:2px;padding:9px 11px;border:1px solid #d7ded9;border-radius:7px;background:#fff;color:#20352a;font-size:12px;font-weight:400;line-height:1.35;text-align:left;box-shadow:0 8px 24px #061c1130}.collaboration-avatar-tooltip:before{content:"";position:absolute;top:-5px;right:15px;width:8px;height:8px;transform:rotate(45deg);border-left:1px solid #d7ded9;border-top:1px solid #d7ded9;background:#fff}.collaboration-avatar-tooltip strong,.collaboration-avatar-tooltip span,.collaboration-avatar-tooltip small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.collaboration-avatar-tooltip strong{font-size:13px}.collaboration-avatar-tooltip span{color:#526158}.collaboration-avatar-tooltip small{margin-top:3px;color:#77837b;font-size:11px}.collaboration-avatar:hover .collaboration-avatar-tooltip,.collaboration-avatar:focus-visible .collaboration-avatar-tooltip{display:block}.collaboration-recovery{min-width:0;display:inline-flex;align-items:center;gap:7px;margin:0 8px;border:1px solid #e0716780;border-radius:999px;padding:4px 6px 4px 9px;background:#6f2b2b66;color:#ffe0dd;font-size:10px;white-space:nowrap}.collaboration-recovery button{border:1px solid #ffffff55;border-radius:999px;padding:3px 7px;background:#ffffff18;color:inherit;font-size:10px}.collaboration-recovery button:hover{background:#ffffff2c}.compile-status-strip{min-height:31px;display:flex;align-items:center;justify-content:center;gap:7px;padding:6px 14px;background:#fff6dc;color:#72530d;border-bottom:1px solid #e8cd7d;font-size:11px}.compile-status-strip.failed{background:#fff0ee;color:#9a3028;border-bottom-color:#e8aaa4}.client-tool-recoveries{flex:none;display:flex;flex-direction:column}.client-tool-recovery{min-height:34px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;padding:6px 14px;border-bottom:1px solid #e4bf78;background:#fff8e8;color:#6f4d10;font-size:11px}.client-tool-recovery>svg{flex:none;color:#b97817}.client-tool-recovery>span{min-width:0;flex:0 1 auto;line-height:1.35}.client-tool-recovery>span strong{margin-right:3px}.client-tool-recovery-actions{flex:none;display:inline-flex;align-items:center;gap:5px}.client-tool-recovery-actions button{border:1px solid #d5a553;border-radius:5px;padding:4px 8px;background:#fff;color:#6f4d10;font:inherit;cursor:pointer}.client-tool-recovery-actions button:hover:not(:disabled){border-color:#a86b0f;background:#fff1cd}.client-tool-recovery-actions button:disabled{cursor:not-allowed;opacity:.5}.formatter-diagnostics details{min-width:110px;max-width:min(760px,80vw)}.formatter-diagnostics summary{cursor:pointer;color:#8f5b0d;font-weight:650}.formatter-diagnostics details[open]{flex-basis:100%;order:3}.formatter-diagnostics pre{max-height:150px;margin:7px auto 2px;overflow:auto;border:1px solid #e4c88f;border-radius:5px;padding:8px 10px;background:#fffdf7;color:#57451f;font:11px/1.45 SFMono-Regular,Consolas,monospace;white-space:pre-wrap}.formatter-diagnostics-dismiss{width:25px;height:25px;display:grid;place-items:center;flex:none;border:1px solid transparent;border-radius:5px;padding:0;background:transparent;color:#8f5b0d;cursor:pointer}.formatter-diagnostics-dismiss:hover{border-color:#d5a553;background:#fff1cd}.editor-actions{display:flex;align-items:center;gap:8px}.editor-actions button{padding:8px 10px;display:inline-flex;align-items:center;gap:6px;border-radius:6px;border:1px solid #ffffff28;color:#fff;background:#ffffff0d;font-size:12px;white-space:nowrap}.editor-actions .compile{background:#f3b943;border-color:#f3b943;color:#193023;font-weight:700}.editor-actions button.active{background:#d9eadf;color:#164c33}.format-action,.comments-action,.version-action{min-width:112px;display:flex;flex-direction:column;align-self:center;gap:2px}.format-action-label,.comments-action-label,.version-action-label{height:12px;display:flex;align-items:center;justify-content:center;gap:4px;padding:0 5px;color:#b9d0c2;font-size:9px;font-weight:750;letter-spacing:.08em;line-height:1;text-transform:uppercase}.format-action-options,.comments-action-options,.version-action-options{height:27px;display:grid;grid-template-columns:1fr 1fr;overflow:hidden;border:1px solid #ffffff35;border-radius:6px;background:#ffffff0d}.editor-actions .format-action button,.editor-actions .comments-action button,.editor-actions .version-action button{min-width:0;height:25px;justify-content:center;border:0;border-radius:0;padding:0 7px;font-size:11px}.editor-actions .format-action button+button,.editor-actions .comments-action button+button,.editor-actions .version-action button+button{border-left:1px solid #ffffff35}.editor-actions .format-action-file{background:#2f7a58;color:#fff}.editor-actions .format-action-selected{background:#326b91;color:#fff}.editor-actions .format-action-file:hover:not(:disabled){background:#3a946c}.editor-actions .format-action-selected:hover:not(:disabled){background:#3d82ae}.editor-actions .comments-action-add{background:#2f7a58;color:#fff}.editor-actions .comments-action-all{background:#5b648e;color:#fff}.editor-actions .comments-action-add:hover:not(:disabled){background:#3a946c}.editor-actions .comments-action-all:hover:not(:disabled){background:#6e79a8}.editor-actions .comments-action-all.active{border-color:transparent;background:#6e79a8;color:#fff}.editor-actions .version-action-history{background:#5b648e;color:#fff}.editor-actions .version-action-git{background:#765493;color:#fff}.editor-actions .version-action-history:hover:not(:disabled){background:#6e79a8}.editor-actions .version-action-git:hover:not(:disabled){background:#8a65ad}.editor-actions .format-action button:disabled,.editor-actions .comments-action button:disabled,.editor-actions .version-action button:disabled{cursor:not-allowed;opacity:.45}.layout-menu{position:relative}.editor-actions .layout-trigger{min-width:138px;justify-content:flex-start;padding-block:5px}.layout-trigger>span{min-width:0;display:flex;flex:1;flex-direction:column;align-items:flex-start;line-height:1.15}.layout-trigger>span small{color:#b9d0c2;font-size:9px;font-weight:500;letter-spacing:.025em;text-transform:uppercase}.layout-trigger.active>span small{color:#52715f}.layout-popover{position:absolute;z-index:100;top:calc(100% + 8px);right:0;width:290px;padding:7px;border:1px solid #d4dcd6;border-radius:9px;background:#fff;color:#25362c;box-shadow:0 14px 38px #061c1138}.layout-popover-title{padding:6px 8px 8px;color:#768178;font-size:10px;font-weight:700;letter-spacing:.055em;text-transform:uppercase}.editor-actions .layout-option{width:100%;min-height:52px;display:grid;grid-template-columns:25px minmax(0,1fr) 18px;gap:9px;padding:8px 9px;border:0;color:#25362c;background:transparent;text-align:left}.editor-actions .layout-option:hover,.editor-actions .layout-option.selected{background:#edf5ef;color:#185d3d}.layout-option>span{min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:2px}.layout-option strong{font-size:12px}.layout-option small{color:#748078;font-size:10px;line-height:1.35;white-space:normal}.toast{position:fixed;z-index:10;top:66px;left:50%;transform:translate(-50%);background:#8f271f;color:#fff;padding:9px 16px;border-radius:7px;font-size:13px;box-shadow:0 8px 30px #0003}.toast.success{background:#1d6b46}.work-grid{min-height:0;flex:1;background:#fff}.resize-handle{position:relative;width:6px;flex:0 0 6px;display:grid;place-items:center;background:#e4e7e4;color:#98a09a;outline:none;transition:background .12s ease}.resize-handle:hover,.resize-handle[data-resize-handle-active]{background:#89ad98;color:#fff}.resize-handle svg{pointer-events:none}.sync-resize-handle{z-index:20!important;overflow:visible}.sync-direction-buttons{position:absolute;z-index:21;top:50%;left:50%;display:flex;flex-direction:row;gap:2px;padding:3px;transform:translate(-50%,-50%);border:1px solid #aebdb3;border-radius:7px;background:#fff;box-shadow:0 4px 16px #15251b38}.sync-direction-buttons button{width:27px;height:27px;display:grid;place-items:center;border:0;border-radius:4px;padding:0;background:transparent;color:#214d35;font-size:17px;font-weight:750;line-height:1}.sync-direction-buttons button:hover:not(:disabled){background:#deebe2;color:#176b44}.sync-direction-buttons button:disabled{cursor:not-allowed;opacity:.35}.sync-resize-handle .resize-grip{opacity:0}.cm-ySelectionInfo{opacity:1!important;padding:2px 5px!important;border-radius:4px 4px 4px 0;font-family:Inter,ui-sans-serif,system-ui,sans-serif!important;font-size:10px!important;transform:translateY(-2px);box-shadow:0 2px 5px #0002}.left-panel,.context-panel,.source-panel,.preview-panel{min-width:0;min-height:0;border-right:1px solid #dfe2de}.left-panel,.source-panel,.preview-panel,.context-panel{height:100%}.left-panel{display:flex;flex-direction:column;overflow:hidden}.files-panel{position:relative;min-height:180px;flex:3;overflow:auto;border-bottom:1px solid #dfe2de}.files-panel.drop-active{outline:2px solid #2c9564;outline-offset:-2px}.file-drop-overlay{position:absolute;z-index:8;inset:42px 0 0;min-height:130px;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:6px;padding:16px;background:#e8f4edee;color:#185d3c;text-align:center;pointer-events:none;backdrop-filter:blur(2px)}.file-drop-overlay strong{font-size:13px}.file-drop-overlay span{max-width:90%;overflow:hidden;color:#5e7668;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.outline-panel{min-height:150px;flex:2;overflow:auto}.panel-title{height:42px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;border-bottom:1px solid #e6e8e5;color:#647069;text-transform:uppercase;font-size:11px;font-weight:700}.panel-title>span{min-width:0;display:flex;align-items:center;gap:6px}.panel-title button{width:28px;height:28px;display:grid;place-items:center;border:0;border-radius:5px;background:transparent;color:#5d6961}.panel-title button:hover{background:#e8eeea;color:#176b44}.file-tools{flex:none;display:flex;align-items:center;gap:4px;margin-left:8px}.file-tools button{box-sizing:border-box}.file-list{padding:6px 7px 10px}.file-entry{min-width:0;height:calc(1em + 18px);min-height:30px;display:flex;align-items:center;border-radius:5px;color:#4f5952}.file-entry:hover{background:#f0f3f0}.file-entry.active,.file-entry.selected{background:#e2efe7;color:#15583a;font-weight:650}.file-entry-main{min-width:0;height:100%;flex:1;overflow:hidden;display:flex;align-items:center;gap:5px;border:0;padding:0 4px;background:transparent;color:inherit;text-align:left;font-size:inherit}.file-entry-main span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-entry-main svg{flex:none;color:#28724e}.file-entry.root-document .file-entry-main>svg{color:#2d6f9f}.file-entry.compile-target{background:#e9f2ec;box-shadow:inset 2px 0 #28724e}.file-entry-main small{flex:none;padding:1px 4px;border-radius:999px;background:#d9eadf;color:#1d5b3e;font-size:8px;line-height:1.35}.folder-entry .file-entry-main svg:first-child{color:#78837b}.folder-entry .file-entry-main svg:nth-child(2){color:#d49b2d}.root-entry{padding-left:5px}.root-entry .file-entry-main svg{color:#d49b2d}.file-entry-action{width:26px;height:26px;flex:none;display:none;place-items:center;border:0;border-radius:4px;background:transparent;color:#657069}.file-entry:hover .file-entry-action,.file-entry:focus-within .file-entry-action{display:grid}.file-entry-action:hover{background:#dfe7e1;color:#176b44}.resource-download{display:inline-flex;align-items:center;gap:6px;text-decoration:none}.resource-preview-message{min-height:180px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:#536158;text-align:center}.resource-preview-message strong{color:#263d2e;font-size:15px}.resource-preview-message span{max-width:440px;color:#748078;font-size:12px}.resource-image-wrap{display:flex;max-height:min(620px,65vh);align-items:center;justify-content:center;overflow:auto;padding:8px;background:#e9ecea;border-radius:7px}.resource-image{display:block;max-width:100%;max-height:min(590px,62vh);object-fit:contain}.resource-pdf{width:100%;height:min(650px,68vh);border:1px solid #d9dfda;border-radius:6px;background:#69706c}.resource-text{max-height:min(650px,68vh);overflow:auto;margin:0;padding:14px;border:1px solid #d9dfda;border-radius:6px;background:#f7f9f7;color:#26352c;font:12px/1.55 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.source-panel{position:relative;overflow:hidden;display:flex;flex-direction:column;height:100%;min-height:0}.editor-tabs-bar{flex:none;min-height:35px;background:#eaefe9;border-bottom:1px solid #d4ded7;display:flex;align-items:stretch;padding:4px 6px 0;overflow:hidden}.editor-tabs-scroll{display:flex;align-items:stretch;gap:3px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.editor-tabs-scroll::-webkit-scrollbar{display:none}.editor-tab-item{display:inline-flex;align-items:center;max-width:220px;border:1px solid #ccd6ce;border-bottom:0;border-radius:6px 6px 0 0;background:#dce4de;color:#55665c}.editor-tab-item:hover{background:#e6eee8;color:#1e3628}.editor-tab-item.active{background:#fff;border-color:#cad7ce;box-shadow:0 -1px 3px #0000000a}.editor-tab{display:inline-flex;align-items:center;gap:5px;min-width:0;flex:1 1 auto;padding:4px 7px 4px 10px;border:0;border-radius:6px 0 0;background:transparent;color:inherit;font:inherit;font-size:12px;text-align:left;cursor:pointer;user-select:none;white-space:nowrap}.editor-tab:hover{color:#1e3628}.editor-tab.active{color:#184f36;font-weight:600}.editor-tab:focus-visible{position:relative;z-index:1;outline:2px solid #4c9a6d;outline-offset:-2px}.editor-tab-icon{display:inline-flex;align-items:center;color:#697a70}.editor-tab.active .editor-tab-icon{color:#184f36}.editor-tab-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.editor-tab-badge{font-size:9px;padding:1px 4px;border-radius:4px;background:#e3eee6;color:#1a6442;font-weight:600;flex-shrink:0}.editor-tab-close{display:inline-flex;align-items:center;justify-content:center;width:22px;height:24px;border:0;border-radius:0 5px 0 0;background:transparent;color:#76887e;padding:0;cursor:pointer;flex-shrink:0}.editor-tab-close:hover{background:#cbd7cf;color:#153123}.editor-tab-item.active .editor-tab-close:hover{background:#e3ece5;color:#184f36}.editor-tab-close:focus-visible{position:relative;z-index:1;outline:2px solid #4c9a6d;outline-offset:-2px}.editor-content-container{position:relative;flex:1 1 auto;min-height:0;height:100%;overflow:hidden}.editor-centered-notice{position:absolute;z-index:8;top:50%;left:50%;max-width:calc(100% - 32px);transform:translate(-50%,-50%);pointer-events:none;border:1px solid #69a780;border-radius:8px;padding:9px 15px;background:#1d6b46ed;color:#fff;font:600 12px/1.4 inherit;text-align:center;box-shadow:0 8px 26px #071d1238}.editor-shell{height:100%;min-height:0;display:flex;flex-direction:column}.editor-shell .editor-host{height:auto;min-height:0;flex:1 1 auto}.editor-host,.cm-editor{height:100%;min-height:0}.editor-host .cm-editor{font-family:inherit;font-size:inherit;line-height:inherit}.editor-host .cm-editor{font-variant-ligatures:contextual;font-feature-settings:"liga" 1,"calt" 1}.editor-host .cm-scroller{min-height:0;height:auto;flex:1 1 auto;overflow:auto;font-family:inherit;line-height:inherit}.editor-host .cm-panels{flex:none}.editor-host .cm-vim-panel{min-height:25px;display:flex;align-items:center;box-sizing:border-box;width:100%;border-top:1px solid #cbd8ce;padding:3px 10px;background:#f1f6f2;color:#31523e;font:11px/1.3 SFMono-Regular,Consolas,monospace}.vim-editor-status{min-height:25px;flex:0 0 25px;display:flex;align-items:center;box-sizing:border-box;border-top:1px solid #cbd8ce;padding:3px 10px;background:#f1f6f2;color:#31523e;font:11px/1.3 SFMono-Regular,Consolas,monospace}.editor-host .cm-content,.editor-host .cm-gutters{font-family:inherit;font-size:inherit}.cm-editor.cm-focused{outline:none}.editor-host .cm-spell-error-active{border-radius:2px;background:#f6d66f;box-shadow:0 0 0 1px #c99324;color:#3f3010;text-decoration:underline wavy #9b6715 1.5px;text-decoration-skip-ink:none}.editor-host .cm-panel.cm-search{padding:8px 38px 8px 10px;border-top:1px solid #ccd5cf;background:#f7f9f7;color:#35443a;box-shadow:0 -3px 10px #1f382710;font-family:Inter,ui-sans-serif,system-ui,sans-serif;font-size:12px;line-height:1.4}.editor-host .cm-panel.cm-search .cm-textfield{min-width:170px;height:29px;margin:2px 6px 2px 0;border:1px solid #bcc8c0;border-radius:5px;padding:4px 8px;background:#fff;color:#202b24;outline:none;font-family:inherit;font-size:12px}.editor-host .cm-panel.cm-search .cm-textfield:focus{border-color:#3d8a60;box-shadow:0 0 0 2px #3d8a6025}.editor-host .cm-panel.cm-search .cm-button{height:29px;margin:2px 5px 2px 0;border:1px solid #bdc8c0;border-radius:5px;padding:3px 9px;background:#fff;background-image:none;color:#31513d;font-family:inherit;font-size:12px;text-transform:none}.editor-host .cm-panel.cm-search .cm-button:hover{border-color:#7c9f89;background:#e9f1ec}.editor-host .cm-panel.cm-search label{display:inline-flex;align-items:center;gap:3px;margin:3px 9px 3px 0;color:#59665d;font-family:inherit;font-size:12px}.editor-host .cm-panel.cm-search input[type=checkbox]{accent-color:#176b44}.editor-host .cm-panel.cm-search [name=close]{top:8px;right:10px;width:25px;height:25px;border-radius:5px;color:#647069;font-size:19px;line-height:1}.editor-host .cm-panel.cm-search [name=close]:hover{background:#e3e9e5;color:#244d36}.editor-host .cm-search-count{display:inline-flex;align-items:center;min-height:29px;margin:2px 5px 2px 4px;color:#506057;font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap}.editor-host .cm-searchMatch{background:#f5d76e99;outline:1px solid #d9a91c88}.editor-host .cm-searchMatch.cm-searchMatch-selected{background:#f0a94a99;outline-color:#cc7720}.editor-host .cm-spell-error{text-decoration:underline wavy #c53b32 1.5px;text-decoration-skip-ink:none;text-decoration-thickness:1.5px}.editor-host .cm-grammar-warning{text-decoration:underline wavy #d19a26 1.5px;text-decoration-skip-ink:none;text-decoration-thickness:1.5px}.spell-suggestions-menu{position:fixed;z-index:1200;display:flex;min-width:190px;max-width:250px;flex-direction:column;gap:3px;padding:7px;border:1px solid #b9c8bd;border-radius:7px;background:#fff;box-shadow:0 10px 28px #1930222e;color:#26352c;font-size:12px}.spell-suggestions-title{padding:3px 6px 5px;color:#607067;font-size:10px;font-weight:700;letter-spacing:.02em;text-transform:uppercase}.spell-suggestions-message{padding:3px 6px 6px;border-bottom:1px solid #e2e8e3;color:#58685e;font-size:11px;line-height:1.4}.spell-suggestions-menu button{min-height:29px;border:1px solid transparent;border-radius:5px;padding:4px 8px;background:transparent;color:#214f37;font:inherit;text-align:left;cursor:pointer}.spell-suggestions-menu button:hover:not(:disabled),.spell-suggestions-menu button:focus-visible:not(:disabled){border-color:#a9c9b3;background:#edf6ef;outline:none}.spell-suggestions-menu button:disabled{color:#78847d;cursor:not-allowed;opacity:.7}.spell-suggestions-empty,.spell-suggestions-readonly{display:block;padding:4px 6px;color:#78847d;font-size:10px;line-height:1.35}.spell-suggestions-readonly{border-top:1px solid #e2e8e3;margin-top:3px;padding-top:7px}.cm-source-comment{background:#ffe49b99;border-bottom:2px solid #d68b00;cursor:text}.cm-source-comment-resolved{background:#dce5de99;border-bottom-color:#829087}.cm-comment-pin{color:#d68b00;font-size:9px;padding:0 2px;cursor:pointer}.preview-panel{display:flex;flex-direction:column;background:#6f7471}.preview-tabs{min-height:48px;flex:none;display:flex;align-items:stretch;padding:5px 6px 0;background:#4d544f}.preview-tab-list{min-width:0;flex:1;display:grid;grid-template-columns:minmax(0,1.8fr) minmax(120px,1fr);gap:3px}.preview-tabs button{min-width:0;display:flex;align-items:center;justify-content:center;gap:5px;border:0;border-radius:6px 6px 0 0;background:transparent;color:#d7dcd8;font-size:11px}.preview-tabs button.active{background:#f3f4f1;color:#184f36;font-weight:700}.preview-tabs button span{min-width:17px;padding:1px 4px;border-radius:999px;background:#ffffff20;font-size:9px}.preview-tabs button.active span{background:#dfe8e2}.preview-tabs .pdf-tab{justify-content:flex-start;padding:0 12px;font-size:12px}.preview-tabs button .pdf-tab-label{min-width:0;overflow:hidden;padding:0;border-radius:0;background:transparent;display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:12px;line-height:1;text-overflow:ellipsis;white-space:nowrap}.preview-tabs button.active .pdf-tab-label{background:transparent}.preview-tabs .pdf-tab small{max-width:100%;overflow:hidden;color:#bcc4bf;font-size:8px;font-weight:400;line-height:1;text-overflow:ellipsis;white-space:nowrap}.preview-tabs .pdf-tab.active small{color:#65756c}.pdf-download-top{flex:none;display:inline-flex;align-items:center;gap:5px;margin-left:4px;padding:0 11px;border:0;border-radius:6px 6px 0 0;color:#d7dcd8;font-size:10px;text-decoration:none;white-space:nowrap}.pdf-download-top:hover{background:#ffffff1b;color:#fff}.preview-subtabs{height:36px;flex:none;display:flex;align-items:center;gap:3px;padding:4px 7px;border-bottom:1px solid #cfd6d1;background:#e4e9e5}.preview-subtabs button{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 10px;border:0;border-radius:5px;background:transparent;color:#58665d;font-size:10px}.preview-subtabs button:hover{background:#d8e3db;color:#205c40}.preview-subtabs button.active{background:#fff;color:#184f36;font-weight:700;box-shadow:0 1px 3px #26312b22}.preview-subtabs button span{min-width:16px;padding:1px 4px;border-radius:999px;background:#d5ded7;font-size:9px;text-align:center}.preview-subtabs button.active span{background:#dfe8e2}.preview-content{min-height:0;flex:1}.preview-pdf{overflow:hidden}.pdf-viewer{position:relative;width:100%;height:100%;min-height:0;display:flex;flex-direction:column}.pdf-toolbar{height:36px;flex:none;display:flex;align-items:center;justify-content:flex-end;gap:3px;padding:4px 8px;border-bottom:1px solid #343a36;background:#414843;color:#e4e8e5;font:11px/1 Inter,ui-sans-serif,system-ui,sans-serif}.pdf-toolbar button{height:27px;min-width:27px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid #ffffff24;border-radius:5px;padding:0 6px;background:#ffffff0b;color:inherit}.pdf-toolbar button:hover:not(:disabled){border-color:#ffffff48;background:#ffffff1b}.pdf-toolbar button:disabled{opacity:.3}.pdf-zoom-value{min-width:42px;text-align:center;font-variant-numeric:tabular-nums}.pdf-toolbar .pdf-fit-width{margin-left:3px;padding:0 8px}.pdf-compiling-overlay{position:absolute;z-index:4;inset:36px 0 0;display:flex;align-items:flex-start;justify-content:center;gap:8px;padding-top:24px;background:#26312bb8;color:#fff;font-size:13px;pointer-events:none}.pdf-compiling-overlay span{padding:3px 8px;border-radius:5px;background:#17231cdd}.pdf-loading-state{width:100%;height:100%;min-height:220px;display:grid;place-items:center;align-content:center;gap:10px;background:#6f7471;color:#eef2ef;font-size:12px}.pdf-document{position:relative;width:100%;min-width:0;min-height:0;flex:1;overflow-x:scroll;overflow-y:auto;overscroll-behavior:contain;scrollbar-color:#aeb8b1 #4f5652;scrollbar-width:auto;scrollbar-gutter:stable;padding:14px 14px 20px;background:#6f7471}.pdf-document::-webkit-scrollbar{width:12px;height:12px}.pdf-document::-webkit-scrollbar-track{background:#4f5652}.pdf-document::-webkit-scrollbar-thumb{min-width:38px;border:2px solid #4f5652;border-radius:999px;background:#aeb8b1}.pdf-document::-webkit-scrollbar-thumb:hover{background:#d5dcd7}.pdf-document::-webkit-scrollbar-corner{background:#4f5652}.pdf-pages{min-width:100%}.pdf-loading{min-height:220px;display:grid;place-items:center;align-content:center;gap:10px;color:#eef2ef;font-size:12px}.pdf-page{position:relative;flex:none;max-width:none;overflow:hidden;margin:0 auto 16px;background:#fff;box-shadow:0 3px 14px #0004}.pdf-page.loading{background:#f7f8f7}.pdf-page canvas{display:block;width:100%!important;max-width:100%;height:auto!important}.pdf-annotation-layer{position:absolute;inset:0;z-index:3;pointer-events:none}.pdf-annotation-link{position:absolute;display:block;pointer-events:auto;border-radius:2px;background:transparent;cursor:pointer}.pdf-annotation-link:hover{background:#3f9b6426;box-shadow:inset 0 0 0 1px #3f9b6440}.pdf-page figcaption{position:absolute;right:7px;bottom:5px;padding:2px 5px;border-radius:4px;background:#26312bb5;color:#fff;font-size:9px;pointer-events:none}.pdf-sync-marker{position:absolute;z-index:2;width:14px;height:14px;border:3px solid #ef9c24;border-radius:50%;transform:translate(-50%,-50%);background:#ffe0a580;box-shadow:0 0 0 4px #ef9c2435;pointer-events:none;animation:sync-pulse 1.2s ease-out}@keyframes sync-pulse{0%{box-shadow:0 0 0 14px #ef9c2460}to{box-shadow:0 0 0 4px #ef9c2435}}.preview-empty{height:100%;display:grid;place-content:center;gap:8px;color:#e7e9e7;text-align:center}.preview-empty span{font-size:12px;color:#c2c7c4}.preview-log,.preview-warnings,.preview-errors{overflow:auto;background:#202522}.preview-clean{overflow:auto;background:#f4f6f4}.preview-artifacts{overflow:hidden;background:#f4f6f4}.artifact-browser{width:100%;height:100%;min-height:0;display:grid;grid-template-columns:minmax(135px,38%) minmax(0,1fr)}.artifact-list{min-width:0;overflow:auto;border-right:1px solid #d9dedb;background:#fff}.artifact-row{min-width:0;display:flex;align-items:stretch;border-bottom:1px solid #edf0ee}.artifact-row.active{background:#e5f0e9}.artifact-row>button{min-width:0;flex:1;display:flex;align-items:center;gap:7px;padding:8px 6px 8px 9px;border:0;background:transparent;color:#33463b;text-align:left}.artifact-row>button:disabled{cursor:default;opacity:.7}.artifact-row>button>span{min-width:0;display:flex;flex-direction:column;gap:2px}.artifact-row strong{overflow:hidden;font-size:11px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.artifact-row small{color:#89928c;font-size:9px}.artifact-row>a{width:30px;flex:none;display:grid;place-items:center;color:#52705f}.artifact-row>a:hover{background:#dce8e0;color:#176641}.artifact-preview{min-width:0;min-height:0;display:flex;flex-direction:column;background:#202522;color:#dbe2dd}.artifact-preview>header{height:36px;flex:none;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 10px;border-bottom:1px solid #39413c;background:#303732;font-size:11px}.artifact-preview>header strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.artifact-preview>header a{flex:none;display:inline-flex;align-items:center;gap:4px;color:#c9ddd1}.artifact-preview>pre{min-height:0;flex:1;margin:0;overflow:auto;padding:13px;white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.55 SFMono-Regular,Consolas,monospace}.compile-output{min-height:100%;margin:0;padding:16px;color:#dbe2dd;white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.55 SFMono-Regular,Consolas,monospace}.compile-output.compile-warning{color:#ffdfa0;background:#2d281c}.compile-output.compile-error{color:#ffc2bd;background:#301e1d}.compile-empty{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;color:#bfc7c1;font-size:12px}.compile-empty.compile-warning{color:#e8c46d;background:#2d281c}.compile-empty.compile-error{color:#e99b94;background:#301e1d}.compile-clean-panel{max-width:820px;margin:0 auto;padding:24px;color:#30453a}.compile-clean-intro{display:flex;align-items:flex-start;gap:12px;padding:15px;border:1px solid #e3d1a7;border-radius:9px;background:#fffaf0;color:#80631f;box-shadow:0 3px 12px #5c48100d}.compile-clean-intro>div{min-width:0}.compile-clean-intro strong{display:block;font-size:14px}.compile-clean-intro p,.compile-clean-actions p{margin:5px 0 0;color:#718078;font-size:11px;line-height:1.5}.compile-clean-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:14px}.compile-clean-actions article{display:grid;grid-template-columns:34px minmax(0,1fr);gap:10px;min-width:0;padding:14px;border:1px solid #d4dfd7;border-radius:8px;background:#fff}.compile-clean-actions article.danger{border-color:#e3c9c5}.compile-clean-action-icon{display:grid;place-items:center;width:32px;height:32px;border-radius:7px;background:#e7f2ea;color:#28714a}.compile-clean-actions article.danger .compile-clean-action-icon{background:#f8e8e6;color:#a6433a}.compile-clean-actions strong{color:#2d4638;font-size:12px}.compile-clean-actions article.danger strong{color:#874039}.compile-clean-actions button{display:inline-flex;align-items:center;gap:5px;margin-top:12px;padding:6px 10px;border:1px solid #b8d1bd;border-radius:5px;background:#f0f8f1;color:#21633d;font-size:11px}.compile-clean-actions button:hover:not(:disabled){border-color:#79aa86;background:#e3f2e6}.compile-clean-actions button.danger{border-color:#e2b9b4;background:#fff4f2;color:#a23d35}.compile-clean-actions button.danger:hover:not(:disabled){border-color:#c8837a;background:#fce7e4}.compile-clean-actions button:disabled{cursor:not-allowed;opacity:.45}.compile-diagnostic-list{min-height:100%;padding:8px;background:#202522;overflow:auto}.compile-diagnostic-list.compile-warning{background:#2d281c}.compile-diagnostic-list.compile-error{background:#301e1d}.compile-diagnostic-row{display:grid;grid-template-columns:20px minmax(0,1fr);gap:7px;width:100%;padding:9px 10px;border:0;border-bottom:1px solid #ffffff12;border-radius:4px;background:transparent;color:#eef2ef;text-align:left}.compile-diagnostic-row:not(:disabled):hover{background:#ffffff10;box-shadow:inset 2px 0 #63b889}.compile-diagnostic-row:disabled{opacity:.78;cursor:default}.compile-diagnostic-row>span{min-width:0;display:grid;gap:4px}.compile-diagnostic-row strong{font-size:11px;font-weight:500;white-space:normal}.compile-diagnostic-row small{color:#aeb8b1;font:10px/1.4 SFMono-Regular,Consolas,monospace;overflow-wrap:anywhere}.compile-warning .compile-diagnostic-row>svg{color:#e8c46d}.compile-error .compile-diagnostic-row>svg{color:#e99b94}.context-panel{border-right:0;overflow:auto}.drawer-title{position:sticky;top:0;z-index:2;height:42px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;border-bottom:1px solid #e3e6e3;background:#fff;font-size:13px}.drawer-title button{width:28px;height:28px;display:grid;place-items:center;border:0;border-radius:5px;background:transparent;color:#737a75}.drawer-title button:hover{background:#edf1ee}.tabs{height:42px;display:flex;border-bottom:1px solid #e3e6e3}.tabs button{flex:1;border:0;background:#fff;color:#707872;font-size:12px}.tabs button.active{color:#176b44;border-bottom:2px solid #176b44;font-weight:700}.outline{padding:10px 8px}.outline-item{width:100%;min-width:0;display:flex;align-items:stretch;border:0;padding:6px 0;background:transparent;font-size:12px;text-align:left}.outline-item:hover,.outline-item:focus-visible{background:#edf3ef;color:#176b44;outline:none}.outline-item.current{background:#e2efe7;color:#176b44;font-weight:700}.outline-guides{flex:none;background:repeating-linear-gradient(to right,#dfe5e0 0,#dfe5e0 1px,transparent 1px,transparent 12px)}.outline small{flex:none;min-width:22px;margin-left:8px;color:#a1a7a2}.outline-title{min-width:0;overflow:hidden;color:#3f4942;text-overflow:ellipsis;white-space:nowrap}.padded{padding:14px}.comments{padding:9px}.comments article{margin-bottom:9px;padding:10px;border:1px solid #dde2de;border-radius:7px;font-size:12px;cursor:pointer;user-select:text;-webkit-user-select:text}.comments article.resolved{opacity:.55;background:#f3f5f3}.comments article.orphaned{border-color:#d8847d;background:#fff4f2}.comments header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.comments header small{color:#858b87}.comments time{flex:none;color:#8b928d;font-size:9px;white-space:nowrap}.comment-times{flex:none;display:flex;align-items:flex-end;flex-direction:column;gap:2px}.comment-times small{font-size:8px;white-space:nowrap}.comment-author{min-width:0;display:flex;flex-direction:column;gap:1px}.comment-author strong,.comment-author small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.comment-location{margin-top:5px;color:#768079;font-size:10px}.comments blockquote{margin:8px 0;padding:6px 8px;border-left:2px solid #85ad96;background:#f2f6f3;color:#657069;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.comments p{white-space:pre-wrap;user-select:text;-webkit-user-select:text;cursor:text}.comments blockquote,.comments .comment-content{user-select:text;-webkit-user-select:text;cursor:text}.comments .resolve{display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;color:#176b44;padding:0;font-size:11px}.comment-replies{display:flex;flex-direction:column;gap:7px;margin:10px 0 8px;padding-left:9px;border-left:2px solid #d6dfd9}.comment-reply{position:relative;padding:7px 8px;border-radius:6px;background:#f5f7f5}.comment-reply p{margin:7px 0 1px}.comment-actions{display:flex;align-items:center;gap:12px}.comments .reply-action{display:inline-flex;align-items:center;gap:4px;border:0;padding:0;background:transparent;color:#526c5d;font-size:11px}.comment-owner-actions{display:inline-flex;align-items:center;gap:2px;margin-left:auto}.comment-reply>.comment-owner-actions{position:absolute;right:5px;bottom:4px}.comments .comment-owner-actions button{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:0;border-radius:5px;background:transparent;color:#66716a}.comments .comment-owner-actions button:hover{background:#e2e8e3;color:#244c35}.comments .comment-owner-actions button.danger-text:hover{background:#f8e4e2;color:#a7312a}.comment-reply-form{display:flex;flex-direction:column;gap:7px;margin-top:9px}.comment-edit-form{margin:7px 0}.comment-reply-form textarea{width:100%;resize:vertical;border:1px solid #cbd2cc;border-radius:6px;padding:7px 8px;outline:none;font-size:11px}.comment-reply-form textarea:focus{border-color:#176b44;box-shadow:0 0 0 2px #176b4420}.comment-reply-form>div{display:flex;justify-content:flex-end;gap:5px}.comment-reply-form button{display:inline-flex;align-items:center;gap:4px;border:1px solid #cbd2cc;border-radius:5px;padding:5px 7px;background:#fff;font-size:10px}.comment-reply-form button.primary{border-color:#176b44;background:#176b44;color:#fff}.settings{display:flex;flex-direction:column;gap:14px}.settings>section{display:flex;flex-direction:column;gap:14px}.settings button{border:1px solid #c9d0ca;background:#fff;border-radius:6px;padding:7px 9px;font-size:12px}.settings-tabs{display:flex;gap:4px;padding:3px;border:1px solid #d7ded8;border-radius:9px;background:#f4f7f4}.settings-tab{display:inline-flex;flex:1;align-items:center;justify-content:center;gap:6px;min-height:34px;border:1px solid transparent!important;border-radius:7px!important;background:transparent!important;color:#66716a;font-weight:650}.settings-tab:hover{background:#eaf1eb!important;color:#31523e}.settings-tab.active{border-color:#c8d9cb!important;background:#fff!important;color:#176b44;box-shadow:0 1px 2px #233c2a12}.settings-tab:focus-visible{outline:2px solid #176b44;outline-offset:1px}.settings-actions{display:flex;width:100%;justify-content:flex-end;padding-top:2px}.settings-section-title{display:flex;align-items:center;gap:7px;color:#31523e;font-size:13px}.settings-description{margin:0;color:#7b837e;font-size:11px;line-height:1.45}.browser-tool-statuses{display:flex;flex-wrap:wrap;gap:7px}.browser-tool-status{min-width:116px;flex:1;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:6px;padding:8px 9px;border:1px solid #d9ded9;border-radius:7px;background:#f7f9f7;color:#6d776f;font-size:10px}.browser-tool-status strong{min-width:0;overflow:hidden;color:#344d3c;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.browser-tool-status span{font-weight:700;white-space:nowrap}.browser-tool-status.loading{border-color:#e4d7ad;background:#fffaf0;color:#9a6b18}.browser-tool-status.working{border-color:#bddbc7;background:#f0f8f2;color:#187348}.browser-tool-status.error{border-color:#e7beb9;background:#fff3f1;color:#a3342c}.tex-fmt-options-heading{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px}.tex-fmt-options-heading>span:first-child{min-width:0}.browser-tool-status.compact{min-width:0;flex:none;display:inline-flex;align-items:center;gap:4px;padding:3px 6px;border-radius:999px;font-size:10px;line-height:1;white-space:nowrap}.browser-tool-status.compact span{font-size:10px}.browser-tool-status.compact .browser-tool-reload{grid-column:auto;display:grid;place-items:center;width:18px;height:18px;min-height:18px;margin:-1px -3px -1px 0;padding:0;border:0;border-radius:50%;background:transparent;color:inherit}.browser-tool-status.compact .browser-tool-reload:hover{background:#0000000d}.browser-tool-reload{grid-column:1 / -1;display:inline-flex;align-items:center;justify-content:center;gap:5px;width:100%;min-height:26px;margin-top:2px;border:1px solid #dca9a3;border-radius:5px;background:#fff;color:#922d27;font-size:10px;font-weight:700}.browser-tool-reload:hover{border-color:#bf7770;background:#fff8f7}.settings .editor-preference{display:flex;flex-direction:column;gap:4px}.settings .editor-preference .field-hint{margin:0 9px;line-height:1.4}.settings .editor-checkbox{flex-direction:row;align-items:center;gap:7px;padding:8px 9px;border:1px solid #d9ded9;border-radius:7px;font-weight:500}.settings .editor-checkbox input{width:auto;margin:0;accent-color:#176b44}.spell-check-result{display:inline-flex;align-items:center;gap:6px;color:#66716a;font-size:11px}.spell-check-result.has-issues{color:#a3342c;font-weight:650}.spell-check-controls{display:inline-flex;align-items:center;gap:2px;margin-left:3px;color:#6f4a45;font-weight:500}.spell-check-controls button{width:24px;height:24px;display:inline-grid;place-items:center;border:1px solid #d7b8b4;border-radius:4px;padding:0;background:#fff8f7;color:#8e4a42}.spell-check-controls button:hover:not(:disabled){border-color:#b98279;background:#fce9e6}.spell-check-controls button:disabled{cursor:not-allowed;opacity:.35}.spell-check-position{min-width:34px;text-align:center;color:#825850;font-variant-numeric:tabular-nums;white-space:nowrap}.password-generator{display:flex;align-items:stretch;gap:7px}.password-generator input{min-width:0;flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.password-generator button{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:0 10px;border:1px solid #c9d0ca;border-radius:6px;background:#f6f8f6;color:#31523e;font-size:11px;white-space:nowrap}.password-generator button:hover{border-color:#8eaa98;background:#edf3ef}.settings-save{width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px}.latexmkrc-editor,.tex-fmt-options-editor{resize:vertical;font:12px/1.5 SFMono-Regular,Consolas,monospace!important}.tex-fmt-options-editor{min-height:100px}.dictionary-add{display:flex;align-items:stretch;gap:7px}.dictionary-add input{min-width:0;flex:1}.dictionary-add button{flex:none;color:#176b44}.dictionary-words{display:flex;flex-wrap:wrap;gap:6px}.dictionary-word{display:inline-flex;align-items:center;gap:3px;min-height:27px;padding:3px 5px 3px 8px;border:1px solid #d5ded7;border-radius:999px;background:#f1f6f2;color:#31523e;font-size:11px}.dictionary-word code{font:11px/1.2 SFMono-Regular,Consolas,monospace}.dictionary-word button{width:20px;height:20px;display:grid;place-items:center;padding:0;border:0;background:transparent;color:#748078}.dictionary-word button:hover{color:#a7312a}.dictionary-empty{color:#7b837e;font-size:11px}.dictionary-error{margin:-6px 0 0;font-size:11px}.share-dialog{display:flex;flex-direction:column;gap:16px}.share-owner{display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:8px;background:#edf4ef;color:#18583a}.share-owner>span{display:flex;flex-direction:column;gap:2px}.share-owner small{color:#6f7d74;font-size:10px;text-transform:uppercase}.share-add{display:grid;grid-template-columns:minmax(0,1fr) 150px auto;align-items:end;gap:9px;padding-bottom:16px;border-bottom:1px solid #e4e7e4}.share-add .icon-button{height:39px;display:inline-flex;align-items:center;gap:6px;padding:0 13px;font-size:12px}.shared-members-heading{display:flex;align-items:center;justify-content:space-between;color:#48524b;font-size:13px}.shared-members-heading span{min-width:22px;padding:2px 6px;border-radius:999px;background:#e8ece9;color:#6a746d;font-size:10px;text-align:center}.shared-members{display:flex;flex-direction:column;gap:7px}.shared-member{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:10px;border:1px solid #dfe3df;border-radius:8px}.member-identity{min-width:0;display:flex;align-items:center;gap:9px}.member-identity>span:last-child{min-width:0;display:flex;flex-direction:column}.member-identity strong,.member-identity small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member-identity small{color:#7c857e;font-size:10px}.member-avatar{width:30px;height:30px;flex:none;display:grid;place-items:center;border-radius:50%;background:#dfece4;color:#176b44;font-size:12px;font-weight:750}.member-controls{display:flex;align-items:center;gap:5px}.member-controls select{border:1px solid #cbd2cc;border-radius:6px;padding:6px 8px;background:#fff;font-size:11px}.icon-only{width:31px;height:31px;display:grid;place-items:center;border:0;border-radius:6px;background:transparent}.icon-only:hover{background:#f8e9e7}.share-empty{min-height:90px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;color:#89928c;font-size:12px}.spin{animation:spin .8s linear infinite}.dialog-overlay{position:fixed;z-index:100;inset:0;background:#101b15aa;backdrop-filter:blur(2px);animation:fade-in .12s ease-out}.dialog-content{position:fixed;z-index:101;top:50%;left:50%;width:min(460px,calc(100vw - 32px));max-height:min(760px,calc(100vh - 40px));overflow:auto;transform:translate(-50%,-50%);background:#fff;border-radius:12px;box-shadow:0 25px 80px #0004;animation:dialog-in .15s ease-out}.dialog-wide{width:min(660px,calc(100vw - 32px))}.dialog-extra-wide{width:min(900px,calc(100vw - 32px))}.dialog-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 22px 14px;border-bottom:1px solid #e5e8e5}.dialog-header h2{margin:0;font-size:19px}.dialog-header p{margin:6px 0 0;color:#737a75;font-size:12px;line-height:1.5}.dialog-close{border:0;background:transparent;color:#6d746f;font-size:22px}.dialog-body{padding:20px 22px}.dialog-body .warning{display:flex;align-items:flex-start;gap:8px;margin:0;padding:10px 11px;border:1px solid #e4cf91;border-radius:7px;background:#fff8df;color:#735a18;font-size:11px;line-height:1.5}.dialog-body .warning svg{flex:none;margin-top:1px}.system-metrics{display:grid;gap:20px}.metric-summary-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.metric-card{min-width:0;padding:14px 16px;border:1px solid #dfe4df;border-radius:10px;background:#f7f8f6;display:grid;gap:4px}.metric-card>span,.metric-card small{color:var(--muted);font-size:12px}.metric-card strong{font-size:20px;font-weight:650}.metric-section{display:grid;gap:10px}.metric-section h3{margin:0;display:flex;align-items:center;gap:7px;font-size:14px}.metric-section p{margin:0;font-size:13px}.metric-table-wrap{overflow-x:auto;border:1px solid #dfe4df;border-radius:9px}.metric-table{width:100%;border-collapse:collapse;font-size:12px;white-space:nowrap}.metric-table th,.metric-table td{padding:8px 10px;border-bottom:1px solid #e4e8e4;text-align:right}.metric-table th:first-child,.metric-table td:first-child{text-align:left}.metric-table tbody tr:last-child td{border-bottom:0}@media(max-width:640px){.metric-summary-grid{grid-template-columns:1fr}}.dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:14px 22px;border-top:1px solid #e5e8e5;background:#f8f9f7}.dialog-footer button{border:1px solid #cbd2cc;border-radius:7px;padding:8px 14px;background:#fff}.dialog-footer .primary{display:inline-flex;align-items:center;justify-content:center;gap:6px;border-color:#176b44;background:#176b44;color:#fff}.dialog-footer .danger,button.danger{border-color:#b3261e;background:#b3261e;color:#fff}.citation-library-dialog{display:flex;flex-direction:column;gap:12px}.citation-library-tabs{display:flex;gap:4px;padding:3px;border:1px solid #d7ded8;border-radius:9px;background:#f4f7f4}.citation-library-tabs button{display:inline-flex;flex:1;align-items:center;justify-content:center;gap:6px;min-height:34px;border:1px solid transparent;border-radius:7px;background:transparent;color:#66716a;font-size:12px}.citation-library-tabs button:hover{background:#eaf1eb;color:#31523e}.citation-library-tabs button.active{border-color:#c8d9cb;background:#fff;color:#176b44;box-shadow:0 1px 2px #233c2a12}.citation-library-tabs button span{min-width:18px;padding:1px 5px;border-radius:999px;background:#e7eee8;font-size:10px}.citation-library-search{display:flex;align-items:center;gap:8px;padding:0 10px;border:1px solid #ccd6ce;border-radius:7px;background:#fff;color:#68766d}.citation-library-search-row{display:flex;align-items:stretch;gap:8px}.citation-library-search-row .citation-library-search{min-width:0;flex:1}.citation-add-entry-button{display:inline-flex;align-items:center;gap:5px;flex:none;border:1px solid #176b44;border-radius:7px;padding:0 11px;background:#176b44;color:#fff;font-size:11px}.citation-add-entry-button:hover{background:#125937}.citation-library-search input{min-width:0;flex:1;border:0;padding:9px 0;outline:0;font-size:12px}.citation-library-search span{flex:none;color:#8a958d;font-size:10px}.citation-tag-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.citation-tag-filters{min-width:0;display:flex;flex:1;flex-wrap:wrap;gap:5px}.citation-tag-filters button{display:inline-flex;align-items:center;gap:5px;border:1px solid transparent;border-radius:999px;padding:5px 8px;background:#f1f4f1;color:#5f6e64;font-size:10px}.citation-tag-filters button:hover{background:#e6eee8}.citation-tag-filters button.active{border-color:#9cbea6;background:#e8f2eb;color:#176b44}.citation-tag-create{display:flex;flex:none;gap:5px}.citation-tag-create input,.citation-tag-create select{min-width:0;border:1px solid #cbd4cd;border-radius:6px;padding:6px 7px;background:#fff;font-size:10px}.citation-tag-create input{width:120px}.citation-tag-create select{width:76px}.citation-tag-create button{display:inline-flex;align-items:center;gap:4px;border:1px solid #bdc9c0;border-radius:6px;padding:6px 8px;background:#fff;color:#31523e;font-size:10px;white-space:nowrap}.citation-tag-create button:hover:not(:disabled){border-color:#8eaa98;background:#edf4ef}.citation-entry-list{display:flex;flex-direction:column;gap:8px;max-height:46vh;overflow:auto;padding:1px}.citation-entry-item{display:flex;flex-direction:column;gap:6px}.citation-entry-card{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:10px 11px;border:1px solid #dce3de;border-radius:8px;background:#fbfcfb}.citation-entry-card.already-in-file{border-color:#d7ddd8;background:#f0f2f0;filter:grayscale(.35)}.citation-entry-card.already-in-file .citation-entry-heading code,.citation-entry-card.already-in-file .citation-entry-main>strong,.citation-entry-card.already-in-file .citation-entry-main>p{color:#7c867f}.citation-entry-card.selected{position:relative;z-index:1;border-color:#70a982;background:#f0f8f2;box-shadow:0 0 0 2px #2f7a5824,0 6px 16px #244c3520}.citation-entry-card.selected .citation-entry-heading code{color:#0f633d}.citation-entry-main{min-width:0;display:flex;flex:1;flex-direction:column;gap:3px}.citation-entry-heading{display:flex;align-items:center;flex-wrap:wrap;gap:6px}.citation-entry-heading code{color:#176b44;font:650 11px/1.3 SFMono-Regular,Consolas,monospace}.citation-entry-heading>span{color:#859189;font-size:10px}.citation-entry-heading>.citation-entry-venue{max-width:22rem;overflow:hidden;border-radius:999px;padding:2px 6px;background:#edf0ff;color:#4b5ca8;font-size:9px;font-style:italic;font-synthesis:style;text-overflow:ellipsis;white-space:nowrap}.citation-entry-heading em{display:inline-flex;align-items:center;gap:3px;border-radius:999px;padding:2px 6px;background:#e8f2eb;color:#26704a;font-size:9px;font-style:normal}.citation-entry-heading em.private{background:#edf0ee;color:#69756d}.citation-entry-main>strong{overflow:hidden;color:#2b3b31;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.citation-entry-main>p{margin:0;overflow:hidden;color:#718078;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.citation-entry-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:3px}.citation-tag-pill{display:inline-flex;align-items:center;gap:4px;border:1px solid color-mix(in srgb,var(--tag-color) 35%,transparent);border-radius:999px;padding:2px 6px;background:color-mix(in srgb,var(--tag-color) 12%,white);color:#526158;font-size:9px}.citation-tag-dot{width:7px;height:7px;flex:none;display:inline-block;border-radius:50%;background:var(--tag-color)}.citation-tag-filters .citation-tag-dot{background:var(--tag-color)}.citation-entry-actions{display:flex;flex:none;flex-wrap:wrap;justify-content:flex-end;gap:5px}.citation-entry-actions button{display:inline-flex;align-items:center;gap:4px;border:1px solid #cbd5ce;border-radius:6px;padding:6px 8px;background:#fff;color:#52685a;font-size:10px;white-space:nowrap}.citation-entry-actions button:hover:not(:disabled){border-color:#8eaa98;background:#edf4ef;color:#176b44}.citation-entry-actions button.primary{border-color:#176b44;background:#176b44;color:#fff}.citation-entry-actions button.saved{border-color:#acd0b8;background:#edf7f0;color:#17623d}.citation-library-empty{min-height:150px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;color:#7b887f;text-align:center}.citation-library-empty strong{color:#526158;font-size:13px}.citation-library-empty span{max-width:360px;font-size:11px;line-height:1.45}.citation-library-notice{display:flex;align-items:center;gap:6px;margin:0;padding:8px 10px;border:1px solid #acd0b8;border-radius:7px;background:#edf7f0;color:#17623d;font-size:11px}.citation-library-notice button{display:grid;place-items:center;width:21px;height:21px;margin-left:auto;border:0;border-radius:4px;background:transparent;color:inherit}.citation-current-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.citation-current-heading>div{min-width:0;display:flex;flex-direction:column;gap:3px}.citation-current-heading strong{color:#31523e;font-size:13px}.citation-current-heading span{color:#78857c;font-size:10px}.citation-current-heading button{display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;color:#176b44;font-size:10px;white-space:nowrap}.citation-edit-panel,.citation-tag-editor{display:flex;flex-direction:column;gap:9px;padding:10px 11px;border:1px solid #cbd9ce;border-radius:8px;background:#f5f9f6}.citation-edit-header{display:flex;align-items:center;justify-content:space-between;gap:8px;color:#31523e;font-size:11px}.citation-edit-header>div{min-width:0;display:flex;flex-direction:column;gap:3px}.citation-edit-header small{color:#78857c;font-size:10px;font-weight:400;line-height:1.4}.citation-edit-header button{display:grid;place-items:center;width:22px;height:22px;border:0;border-radius:4px;background:transparent;color:#68766d}.citation-edit-header button:hover{background:#e2ece4}.citation-edit-panel textarea{width:100%;resize:vertical;border:1px solid #cbd5ce;border-radius:6px;padding:8px;outline:0;font:11px/1.5 SFMono-Regular,Consolas,monospace}.citation-edit-panel textarea:focus{border-color:#176b44;box-shadow:0 0 0 2px #176b4420}.citation-modal-form{display:flex;flex-direction:column;gap:12px}.citation-modal-form.citation-edit-panel{padding:0;border:0;background:transparent}.citation-entry-item>.citation-edit-panel,.citation-entry-item>.citation-tag-editor{margin:0 7px 0 12px;border-left:3px solid #70a982}.citation-edit-actions{display:flex;justify-content:flex-end;gap:6px}.citation-edit-actions button{display:inline-flex;align-items:center;gap:4px;border:1px solid #bdc9c0;border-radius:6px;padding:6px 9px;background:#fff;color:#52685a;font-size:10px}.citation-edit-actions button.primary{border-color:#176b44;background:#176b44;color:#fff}.citation-tag-choice-list{display:flex;flex-wrap:wrap;gap:7px}.citation-tag-choice-list label{display:inline-flex;align-items:center;gap:5px;border:1px solid #d4ded6;border-radius:999px;padding:5px 7px;background:#fff;color:#526158;font-size:10px}.citation-tag-choice-list input{width:auto;accent-color:#176b44}.form-stack{display:flex;flex-direction:column;gap:14px}.import-error{margin:0;padding:10px 12px;border:1px solid #e3b5b1;border-radius:8px;background:#fff3f2;line-height:1.45}.form-field{display:flex;flex-direction:column;gap:7px;font-size:13px;font-weight:650}.form-field input,.form-field select,.form-field textarea{width:100%;border:1px solid #cbd2cc;border-radius:8px;padding:10px 11px;background:#fff;outline:none}.form-field input:focus,.form-field select:focus,.form-field textarea:focus{border-color:#176b44;box-shadow:0 0 0 3px #176b4420}.upload-picker{position:relative;min-height:116px;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;padding:20px;border:1.5px dashed #aebbb2;border-radius:10px;background:#f6f8f6;color:#5f6b63;transition:border-color .15s ease,background .15s ease}.upload-picker:hover,.upload-picker:focus-within{border-color:#4f8a68;background:#f0f6f2}.upload-picker.has-file{border-style:solid;border-color:#83aa91;background:#edf5ef;color:#276044}.upload-picker>svg{flex:none;color:#176b44}.upload-picker-copy{min-width:0;display:flex;flex-direction:column;gap:4px}.upload-picker-copy strong,.upload-picker-copy span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.upload-picker-copy strong{color:#29382f;font-size:13px}.upload-picker-copy span{color:#758078;font-size:11px}.upload-picker>button{display:inline-flex;align-items:center;gap:6px;border:1px solid #9fb0a4;border-radius:7px;padding:8px 11px;background:#fff;color:#235c3d;font-size:12px;font-weight:650}.upload-picker>button:hover{border-color:#176b44;background:#e4efe8}.upload-picker>.upload-clear{position:absolute;top:7px;right:7px;width:26px;height:26px;display:grid;place-items:center;border:0;padding:0;background:transparent;color:#6c776f}.upload-picker>.upload-clear:hover{background:#dce9e0;color:#9d2f27}.choice-group{display:flex;flex-direction:column;gap:10px;border:1px solid #dfe3df;border-radius:8px;padding:14px}.choice-group legend{padding:0 5px;font-size:12px;color:#69716b}.choice-group label{font-size:13px}.color-picker{display:grid;grid-template-columns:repeat(2,1fr);gap:7px;border:0;padding:0}.color-picker legend{margin-bottom:8px;font-size:13px;font-weight:650}.color-picker label{display:flex;align-items:center;gap:7px;border:1px solid #dce1dd;border-radius:7px;padding:8px;font-size:12px}.color-picker label.active{border-color:#176b44;background:#edf5f0}.color-picker input{position:absolute;opacity:0;pointer-events:none}.tag-assignment-list{display:flex;flex-direction:column;gap:7px}.tag-assignment-list label,.tag-assignment-list button{display:flex;align-items:center;gap:9px;min-height:38px;border:1px solid #dce1dd;border-radius:7px;padding:8px 10px;background:#fff;color:#38423b;font-size:13px;text-align:left}.tag-assignment-list label:hover,.tag-assignment-list button:hover{border-color:#8bae9a;background:#f4f8f5}.tag-assignment-list input{width:auto;accent-color:#176b44}.checkbox-field{display:flex;align-items:center;gap:8px;font-size:13px}.checkbox-field input{width:auto}.selection-preview{max-height:130px;overflow:auto;margin:14px 0 0;padding:10px 12px;border-left:3px solid #d6a128;background:#fff8e5;white-space:pre-wrap;font:12px/1.5 SFMono-Regular,Consolas,monospace}.git-dialog{display:flex;flex-direction:column;gap:14px}.git-dialog-modal-fullscreen{top:0;left:0;width:100vw;height:100vh;max-height:100vh;transform:none;overflow:hidden;border-radius:0}.git-loading{min-height:120px;display:flex;align-items:center;justify-content:center;gap:8px;color:#6e7871;font-size:13px}.git-message{margin:0;display:flex;align-items:center;gap:7px;padding:9px 11px;border:1px solid;border-radius:7px;font-size:12px}.git-message.error{border-color:#e2b4b0;background:#fff2f1}.git-message.success{border-color:#acd0b8;background:#edf7f0;color:#17623d}.git-section{display:flex;flex-direction:column;gap:11px;padding:14px;border:1px solid #dfe4e0;border-radius:9px;background:#fbfcfb}.git-section-toggle{width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;border:0;padding:0;background:transparent;color:#607068;text-align:left}.git-section-toggle:hover{color:#176b44}.git-section-heading{min-width:0;display:flex;align-items:flex-start;gap:8px;color:#27533a}.git-section-heading>svg{flex:none;margin-top:1px}.git-section-heading>div,.git-section-heading>span{min-width:0;display:flex;flex-direction:column;gap:3px}.git-section-heading strong{font-size:13px}.git-section-heading small{max-width:650px;overflow:hidden;color:#78817b;font-size:10px;line-height:1.4;text-overflow:ellipsis;white-space:nowrap}.git-section-content{display:flex;flex-direction:column;gap:11px;padding-top:2px}.git-token-guidance{display:flex;flex-direction:column;gap:4px;padding:10px 11px;border:1px solid #c6d9cb;border-left:3px solid #28714b;border-radius:7px;background:#f0f7f2}.git-token-guidance strong{color:#225d3c;font-size:11px}.git-token-guidance span{color:#66756b;font-size:10px;line-height:1.5}.git-account,.git-repository-card{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:7px;background:#eaf3ed;color:#23563a;font-size:12px}.git-account>span{min-width:0;flex:1}.git-account button{display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;color:#a3342c;font-size:10px}.git-inline-actions,.git-action-row{display:flex;align-items:center;flex-wrap:wrap;gap:7px}.git-inline-actions{justify-content:space-between}.git-inline-actions a,.git-repository-card a{display:inline-flex;align-items:center;gap:4px;color:#176b44;font-size:11px;text-decoration:none}.git-inline-actions button,.git-action-row button,.git-primary-action{display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid #bdc9c0;border-radius:6px;padding:7px 9px;background:#fff;color:#31523e;font-size:11px}.git-action-row .git-discard-button:not(:disabled){border-color:#d9aaa5;color:#9b332b}.git-action-row .git-discard-button:not(:disabled):hover{background:#fff0ee}.git-primary-action{align-self:flex-start;border-color:#176b44;background:#176b44;color:#fff}.git-repository-card{justify-content:space-between}.git-repository-card>div{min-width:0;display:flex;flex-direction:column;gap:3px}.git-repository-card strong,.git-repository-card small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-repository-card small{color:#6e7c73;font-size:10px}.git-count{min-width:17px;padding:1px 5px;border-radius:999px;background:#d9e9df;font-size:9px}.git-diff-section{padding-bottom:0;overflow:hidden}.git-diff-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.git-diff-controls{display:flex;align-items:center;gap:7px;flex:none}.git-diff-font-controls{display:inline-flex;align-items:center;gap:2px;border:1px solid #cbd5ce;border-radius:6px;padding:2px;background:#fff;color:#52685a}.git-diff-font-button{width:25px;height:25px;display:grid;place-items:center;border:0;border-radius:4px;padding:0;background:transparent;color:inherit}.git-diff-font-button:hover:not(:disabled){background:#edf4ef;color:#176b44}.git-diff-font-value{min-width:34px;color:#52685a;font-size:10px;font-variant-numeric:tabular-nums;text-align:center}.git-diff-fullscreen{width:29px;height:29px;flex:none;display:grid;place-items:center;padding:0!important;border:1px solid #cbd5ce!important;border-radius:6px!important;background:#fff!important;color:#52685a}.git-diff-fullscreen:hover{border-color:#8eaa98!important;background:#edf4ef!important;color:#176b44}.git-diff-section.is-fullscreen,.git-diff-section:fullscreen{position:fixed;z-index:1000;inset:0;width:100vw;height:100vh;max-height:none;box-sizing:border-box;margin:0;padding:20px!important;border:0;border-radius:0;overflow:hidden;background:#fbfcfb}.git-diff-section.is-fullscreen .git-diff,.git-diff-section:fullscreen .git-diff{flex:1;min-height:0;max-height:none;margin:0}.git-diff-section.is-fullscreen .git-diff-empty,.git-diff-section:fullscreen .git-diff-empty{flex:1;min-height:0;margin:0}.git-diff{max-height:360px;margin:0 -14px;overflow:auto;padding:11px 0;background:#202522;color:#d9e1dc;font:10px/1.5 SFMono-Regular,Consolas,monospace;tab-size:4}.git-diff span{display:block;min-width:max-content;padding:0 12px;white-space:pre}.git-diff span.addition{background:#173b28;color:#bfe8cb}.git-diff span.deletion{background:#442421;color:#f1c1bc}.git-diff span.hunk{background:#283a48;color:#b8daf4}.git-diff span.header{color:#e8cf8b;font-weight:650}.git-diff-empty{margin:0 -14px;padding:28px;background:#252a27;color:#b9c0bc;font-size:12px;text-align:center}.git-history{max-height:300px;display:flex;flex-direction:column;gap:5px;overflow:auto}.git-history article{min-width:0;display:grid;grid-template-columns:66px minmax(0,1fr) auto;align-items:center;gap:8px;padding:8px;border:1px solid #e2e6e3;border-radius:6px;background:#fff}.git-history code{color:#176b44;font-size:10px}.git-history article>div{min-width:0;display:flex;flex-direction:column;gap:2px}.git-history article strong,.git-history article small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-history article strong{font-size:11px}.git-history article small{color:#7b847e;font-size:9px}.git-history article>span{display:flex;gap:3px}.git-history button{width:27px;height:27px;display:grid;place-items:center;border:0;border-radius:5px;background:transparent;color:#52685a}.git-history button:hover{background:#e8f0eb;color:#176b44}.git-force-checkout{display:flex;align-items:flex-start;gap:9px;padding:11px;border:1px solid #e4b9b5;border-radius:8px;background:#fff6f5}.git-force-checkout input{margin-top:2px;accent-color:#b3261e}.git-force-checkout span{display:flex;flex-direction:column;gap:3px}.git-force-checkout strong{color:#932c25;font-size:12px}.git-force-checkout small{color:#7d6562;font-size:10px;line-height:1.45}.quick-open-dialog>label,.project-search-query{display:flex;align-items:center;gap:8px;border:1px solid #bfcac2;border-radius:7px;padding:0 10px;background:#fff}.quick-open-dialog>label:focus-within,.project-search-query:focus-within{border-color:#418060;box-shadow:0 0 0 2px #41806020}.quick-open-dialog input,.project-search-query input{width:100%;border:0;outline:0;padding:10px 0;background:transparent}.quick-open-results{max-height:420px;overflow:auto;margin-top:8px;border:1px solid #d9e0db;border-radius:7px}.quick-open-results button{display:grid;grid-template-columns:20px minmax(0,1fr) 18px;align-items:center;gap:6px;width:100%;padding:8px 10px;border:0;border-radius:0;background:#fff;text-align:left}.quick-open-results button+button{border-top:1px solid #eef1ef}.quick-open-results button.active{background:#e4efe8;color:#195f3d}.quick-open-results span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:11px/1.4 JetBrains Mono,monospace}.project-search-dialog{display:grid;gap:9px}.project-search-form{display:grid;grid-template-columns:1fr 1fr;gap:8px}.project-search-options{grid-column:1 / -1;display:flex;align-items:center;gap:14px}.project-search-options label{display:inline-flex;align-items:center;gap:5px;color:#55645a;font-size:11px}.project-search-options label input{accent-color:#28734b}.project-search-options button{margin-left:auto;display:inline-flex;align-items:center;gap:5px}.project-search-summary{display:flex;align-items:center;justify-content:space-between;min-height:22px;color:#5e6c63;font-size:11px}.project-search-summary span{display:inline-flex;align-items:center;gap:5px}.project-search-results{max-height:480px;overflow:auto;border:1px solid #d9e0db;border-radius:7px;background:#fff}.project-search-results>button{display:grid;grid-template-columns:20px minmax(0,1fr);gap:7px;width:100%;padding:9px 10px;border:0;border-radius:0;background:#fff;text-align:left}.project-search-results>button+button{border-top:1px solid #e8ece9}.project-search-results>button:hover{background:#edf4ef}.project-search-results>button>span{min-width:0;display:grid;gap:4px}.project-search-results strong{color:#31503d;font-size:11px}.project-search-results strong small{color:#7c877f;font-weight:400}.project-search-results code{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#4e5952;font:10px/1.45 JetBrains Mono,monospace}.project-search-results mark{border-radius:2px;padding:1px;background:#f2d36e;color:#4b3b0b}.history-dialog-modal{width:min(1120px,calc(100vw - 32px))}.history-dialog{display:grid;grid-template-columns:270px minmax(0,1fr);min-height:560px;max-height:min(72vh,760px);border:1px solid #d9e0db;border-radius:8px;overflow:hidden;background:#fff}.history-loading{grid-column:1 / -1;display:flex;align-items:center;justify-content:center;gap:8px;min-height:420px;color:#68736b}.history-message{grid-column:1 / -1;margin:10px}.history-timeline{overflow:auto;border-right:1px solid #d9e0db;background:#f5f7f5}.history-stats{position:sticky;top:0;z-index:2;display:grid;gap:5px;padding:10px 12px;border-bottom:1px solid #d8dfda;background:#edf3ef;color:#33483b}.history-stats header{display:flex;align-items:center;justify-content:space-between;gap:8px}.history-stats header span{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:700}.history-stats header button{width:26px;height:26px;display:grid;place-items:center;border:0;padding:0;background:transparent;color:#9d332b}.history-stats header button:hover:not(:disabled){background:#f5deda}.history-stats strong{font-size:11px}.history-stats small{color:#68766d;font-size:9px;line-height:1.4}.history-stats progress{width:100%;height:6px;border:0;border-radius:999px;overflow:hidden;accent-color:#34845a}.history-stats.exceeded progress{accent-color:#bd483e}.history-stats .history-storage-warning{color:#9d332b}.history-timeline>button{display:grid;grid-template-columns:20px minmax(0,1fr);gap:7px;width:100%;padding:11px 12px;border:0;border-bottom:1px solid #e1e6e2;border-radius:0;background:transparent;text-align:left;color:#34443a}.history-timeline>button:hover{background:#eaf0ec}.history-timeline>button.active{background:#dfece4;box-shadow:inset 3px 0 #28734b}.history-timeline>button span{min-width:0;display:grid;gap:2px}.history-timeline>button strong,.history-timeline>button small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.history-timeline>button small{color:#68736b;font-size:10px}.history-detail{min-width:0;overflow:auto;padding:14px}.history-detail-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}.history-detail-header>div{display:grid;gap:4px}.history-detail-header small{display:flex;align-items:center;gap:4px;color:#68736b}.history-detail-actions{display:flex;align-items:center;gap:6px}.history-detail-actions button{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.history-label{display:flex;gap:8px;margin-bottom:12px}.history-label label{flex:1;display:flex;align-items:center;gap:7px;padding:0 9px;border:1px solid #cdd6cf;border-radius:6px;background:#fff}.history-label input{width:100%;border:0;padding:8px 0;outline:0}.history-files{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:start}.history-file-list{display:flex;gap:5px;overflow-x:auto;padding-bottom:5px}.history-file-list button{display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;max-width:230px}.history-file-list button span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.history-file-list button small{padding:1px 4px;border-radius:8px;background:#f2d675;color:#695414;font-size:9px}.history-file-list button.active{border-color:#418060;background:#e7f0ea}.history-file-actions{display:flex;gap:5px}.history-file-actions button{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.history-comparison{min-height:360px;margin-top:10px;border:1px solid #d8dfda;border-radius:7px;overflow:hidden;background:#fbfcfb}.history-comparison>header{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:8px 10px;border-bottom:1px solid #d8dfda;background:#f1f4f2}.history-comparison>header small{color:#68736b}.history-comparison pre{min-height:330px;max-height:430px;margin:0;overflow:auto;padding:11px;white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.5 JetBrains Mono,Source Code Pro,monospace;color:#26342b}.history-comparison pre .history-removed{background:#f8c9c9;color:#7b2525;text-decoration:line-through}.history-comparison pre .history-added{background:#ccebd5;color:#15552c}.history-comparison-empty{min-height:360px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:#78827b}@keyframes fade-in{0%{opacity:0}}@keyframes dialog-in{0%{opacity:0;transform:translate(-50%,-48%) scale(.98)}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:1100px){.project-grid.list-view .project-card-open{grid-template-columns:110px minmax(160px,1fr)}.project-grid.list-view .project-meta{grid-column:1 / -1}.editor-actions button{padding:8px}.editor-actions button svg+*{display:none}.editor-actions .format-action button,.editor-actions .comments-action button,.editor-actions .version-action button{padding:7px 6px}.editor-actions .format-action button svg+*,.editor-actions .comments-action button svg+*,.editor-actions .version-action button svg+*{display:inline}}@media(max-width:720px){.citation-library-page-shell{padding-top:24px}.citation-library-page-header{flex-direction:column}.citation-library-page-header h1{font-size:25px}.citation-library-page-header>button{align-self:flex-start}.citation-library-page .citation-library-dialog{padding:12px}.citation-library-search-row{flex-direction:column}.citation-add-entry-button{min-height:34px;justify-content:center}.citation-entry-card{flex-direction:column}.citation-entry-actions{width:100%;justify-content:flex-start}.upload-picker{grid-template-columns:auto 1fr}.upload-picker>button{grid-column:1 / -1;justify-content:center}.share-add{grid-template-columns:1fr}.shared-member{align-items:flex-start}.member-controls{flex:none}.history-dialog{grid-template-columns:1fr;max-height:none}.history-timeline{max-height:180px;border-right:0;border-bottom:1px solid #d9e0db}.history-files,.project-search-form{grid-template-columns:1fr}}