:root {
  --bg: #f3f3f5;
  --paper: #ffffff;
  --text: #1f2937;
  --text-muted: #6b7280;
  --accent: #2563eb;
  --accent-hover: #1d4ed8;
  --accent-light: #dbeafe;
  --accent-border: #93c5fd;
  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --toolbar-bg: #fafafa;
  --header-grad-start: #1e3a5f;
  --header-grad-mid: #2563eb;
  --header-grad-end: #7c3aed;
  --table-border: #cbd5e1;
  --table-header-bg: #f1f5f9;
  --selected-cell: rgba(37, 99, 235, 0.08);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  min-height: 100vh;
}

/* Word-style title bar: slim Office-blue strip with a white "W" badge and the
   document name centered ("<file> — DocxEditor", mirroring Word's
   "Document1 - Word"). Replaces the old marketing gradient banner. Keeps the
   .page-header class so existing print/responsive selectors still target it. */
.page-header {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  background: #2b579a; /* Office/Word signature blue */
  color: #fff;
  padding: 0 0.75rem;
  position: relative;
  user-select: none;
  font-family: 'Segoe UI', 'Calibri', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 0.82rem;
}

.de-titlebar-badge {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  color: #2b579a;
  font-weight: 800;
  font-size: 0.78rem;
  border-radius: 3px;
}

.de-titlebar-title {
  font-weight: 600;
  letter-spacing: 0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 70vw;
}

.de-titlebar-app { color: rgba(255, 255, 255, 0.72); font-weight: 400; }

.doc-status { color: #fff; }

/* ============================================================ RIBBON
   Word-style tabbed ribbon. Top strip = tab buttons. Below = a single
   panel container whose visible child is keyed by the active tab. Each
   panel is a horizontal row of groups; each group is a column of button
   rows with a small label at the bottom (matching Word's "Font" / "Paragraph"
   / "Styles" group labels). Existing JS hangs off button id + data-cmd —
   none of the wiring changes. */

.ribbon {
  position: sticky;
  top: 0;
  background: var(--toolbar-bg);
  border-bottom: 1px solid var(--border);
  z-index: 10;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
  font-size: 0.82rem;
}

/* ---- Tab strip ---- */
.ribbon-tabs {
  display: flex;
  align-items: stretch;
  background: #fafafa;
  border-bottom: 1px solid var(--border);
  padding: 0 0.5rem;
  gap: 0.05rem;
}

.ribbon-tab {
  background: transparent;
  border: none;
  border-bottom: 2.5px solid transparent;
  padding: 0.55rem 0.95rem 0.45rem;
  cursor: pointer;
  font-size: 0.81rem;
  font-family: inherit;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: #475569;
  white-space: nowrap;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
  position: relative;
}
.ribbon-tab:hover {
  background: rgba(0,0,0,0.04);
  color: var(--text);
}
.ribbon-tab.is-active {
  color: var(--accent);
  background: var(--toolbar-bg);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
.ribbon-tab.is-active::after {
  /* Visual continuity with the panel below — the active tab "merges" into
     the ribbon body, like Word's tab strip. */
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--toolbar-bg);
}

/* The File tab gets the Word-style colored treatment as the leftmost tab */
.ribbon-tab-file {
  background: var(--accent);
  color: white;
  font-weight: 600;
  margin-right: 0.2rem;
  padding-left: 1.1rem;
  padding-right: 1.1rem;
}
.ribbon-tab-file:hover {
  background: var(--accent-hover);
  color: white;
}
.ribbon-tab-file.is-active {
  background: var(--accent-hover);
  color: white;
  border-bottom-color: transparent;
}
.ribbon-tab-file.is-active::after { display: none; }

/* ---- Panels ---- */
.ribbon-panels {
  background: var(--toolbar-bg);
  overflow-x: auto;
  overflow-y: hidden;
}
.ribbon-panel {
  display: flex;
  align-items: stretch;
  padding: 0.4rem 0.5rem;
  gap: 0;
  min-height: 96px;
}
.ribbon-panel[hidden] {
  display: none;
}

/* ---- Groups ---- */
.ribbon-group {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: stretch;
  padding: 0.15rem 0.6rem 0.3rem;
  border-right: 1px solid var(--border);
  position: relative;
  min-width: 0;
}
.ribbon-group:last-child {
  border-right: none;
}
.ribbon-group-row {
  display: flex;
  gap: 0.2rem;
  align-items: stretch;
  min-height: 0;
}
.ribbon-group-row + .ribbon-group-row {
  margin-top: 0.25rem;
}
.ribbon-group-label {
  text-align: center;
  font-size: 0.68rem;
  font-weight: 500;
  color: #6b7280;
  letter-spacing: 0.04em;
  margin-top: 0.35rem;
  padding-top: 0.1rem;
  user-select: none;
  line-height: 1;
}
.ribbon-group-wide {
  /* Wider groups (multi-button rows) get a bit more breathing room */
  padding-left: 0.7rem;
  padding-right: 0.7rem;
}

/* ---- Buttons ---- */
.ribbon-btn {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  font-size: 0.78rem;
  line-height: 1;
  color: var(--text);
  transition: background 0.08s ease, border-color 0.08s ease, color 0.08s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  white-space: nowrap;
}
.ribbon-btn:hover {
  background: #e8e8e8;
  border-color: #d4d4d4;
}
.ribbon-btn:active {
  background: #d9d9d9;
}
.ribbon-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.ribbon-btn:disabled:hover {
  background: transparent;
  border-color: transparent;
}

/* Toggled-on state (used by JS via .is-active on bold/italic/etc.) */
.ribbon-btn.is-active {
  background: var(--accent-light);
  border-color: var(--accent-border);
  color: var(--accent);
}

/* Format Painter armed — paintbrush cursor over the editor content. */
.ProseMirror.de-format-painter-armed,
.ProseMirror.de-format-painter-armed * {
  cursor: copy;
}

/* Big buttons: icon over label, like Word's "Paste" / "Insert Table" /
   "New Comment" big buttons. ~58px tall, 60-80px wide. */
.ribbon-btn-big {
  flex-direction: column;
  padding: 0.35rem 0.6rem 0.3rem;
  min-width: 56px;
  min-height: 64px;
  gap: 0.25rem;
  font-size: 0.72rem;
  font-weight: 500;
  text-align: center;
  line-height: 1.15;
}
.ribbon-btn-big svg {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}
.ribbon-btn-big span {
  color: var(--text);
  font-size: 0.7rem;
}

/* Small buttons: icon-only or short-label, single row, ~28px tall */
.ribbon-btn-small {
  padding: 0.3rem 0.45rem;
  min-width: 28px;
  min-height: 28px;
  font-size: 0.78rem;
}
.ribbon-btn-small svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Small button with a visible text label next to the icon (e.g. "↶ Undo").
   Used when an icon-only button would be ambiguous. */
.ribbon-btn-labeled {
  padding-left: 0.55rem;
  padding-right: 0.7rem;
  gap: 0.4rem;
}
.ribbon-btn-labeled span {
  font-size: 0.78rem;
  font-weight: 500;
}

/* Medium buttons: icon-over-label like big buttons, but more compact.
   Used for clusters of related actions (table tools, etc.) where 4–6
   per row look more balanced than full-size big buttons. ~50px wide
   × 58px tall. */
.ribbon-btn-medium {
  flex-direction: column;
  padding: 0.3rem 0.45rem 0.25rem;
  min-width: 48px;
  min-height: 56px;
  gap: 0.2rem;
  font-size: 0.68rem;
  font-weight: 500;
  text-align: center;
  line-height: 1.15;
}
.ribbon-btn-medium svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.ribbon-btn-medium span {
  color: var(--text);
  font-size: 0.66rem;
}

/* "Font-face" buttons (B / I / U / S / X² / X₂) — use the actual glyph
   as the icon instead of an SVG. Slightly larger font. */
.ribbon-btn-fontface {
  font-size: 0.92rem;
  font-family: 'Times New Roman', Cambria, Georgia, serif;
  min-width: 28px;
  padding-top: 0.32rem;
  padding-bottom: 0.32rem;
}
.ribbon-btn-fontface sub,
.ribbon-btn-fontface sup {
  font-size: 0.6em;
  font-weight: 600;
  /* Explicit vertical-align overrides the browser default's subtle shift —
     at toolbar-button size (~28px) the default sub/sup offset isn't
     visually distinct enough between the two buttons. Pin them to a clear
     down/up displacement so X₂ and X² are immediately recognisable. */
  line-height: 0;
  position: relative;
}
.ribbon-btn-fontface sub {
  top: 0.4em;       /* push down */
  vertical-align: baseline;
}
.ribbon-btn-fontface sup {
  top: -0.5em;      /* push up */
  vertical-align: baseline;
}

/* Semantic small-button colors for Accept / Reject */
.ribbon-btn-success { color: #15803d; }
.ribbon-btn-success:hover { background: #dcfce7; border-color: #86efac; color: #14532d; }
.ribbon-btn-danger { color: #b91c1c; }
.ribbon-btn-danger:hover { background: #fee2e2; border-color: #fca5a5; color: #7f1d1d; }

/* ---- Selects in the ribbon (heading, view, zoom) ---- */
.ribbon-select {
  background: white;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.35rem 0.5rem;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
  color: var(--text);
  min-height: 28px;
  min-width: 120px;
}
.ribbon-select-label {
  display: inline-flex;
  align-items: center;
}
/* Font Name / Font Size selects sit side-by-side in the Font group and want
   their own widths (Word: a wide font-name combo + a narrow size combo). */
.ribbon-select-font { min-width: 130px; max-width: 150px; }
.ribbon-select-size { min-width: 56px; max-width: 64px; }

/* ---- Back-compat shims: a few existing selectors still reference
   ".toolbar ..." (e.g. context menus and panels positioned relative to
   the toolbar). Keep them resolving by aliasing .ribbon → .toolbar. */
.toolbar { /* legacy alias — kept so positioned descendants keep working */ }

#editor-wrap {
  padding: 2rem 1rem 6rem;
  display: flex;
  justify-content: center;
  position: relative; /* anchor for the loading overlay */
}

/* Editor loading overlay — shown immediately at page load (the HTML is
   static), then app.js fades it out the moment Tiptap finishes booting
   (right after `new Editor({...})`). This is the user's visual signal
   that the page is alive while the ~20 esm.sh Tiptap extension imports
   resolve in the background. */
#editor-loading-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  /* Sit above the empty editor surface but below the toolbar / modals. */
  z-index: 10;
  pointer-events: none;
  opacity: 1;
  /* Slight delay before showing so a hot-cache load (when everything is
     already in memory) doesn't briefly flash a spinner. */
  animation: de-loading-fade-in 250ms 150ms ease-out backwards;
  transition: opacity 240ms ease;
}
#editor-loading-overlay.is-hidden {
  opacity: 0;
  pointer-events: none;
}
.de-loading-spinner {
  width: 34px;
  height: 34px;
  border: 3px solid #e2e8f0;
  border-top-color: var(--accent, #6750A4);
  border-radius: 50%;
  animation: de-loading-spin 0.9s linear infinite;
}
.de-loading-label {
  font-size: 0.92rem;
  color: #64748b;
  font-weight: 500;
  letter-spacing: 0.02em;
}
@keyframes de-loading-spin {
  to { transform: rotate(360deg); }
}
@keyframes de-loading-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.page-stack {
  width: 100%;
  max-width: 8.5in;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Continuous (default-when-toggled) view: the stage is just a passthrough
   wrapper — its children flow vertically like before. The overlay layer
   stays hidden in this mode. */
.de-page-stage {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: 100%;
}

body:not(.de-view-page) #page-overlay {
  display: none;
}

#editor {
  background: var(--paper);
  width: 100%;
  min-height: 11in;
  padding: 1in;
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 6px 20px rgba(0,0,0,0.06);
}

/* Page header / footer zones — read-only display of running banners
   imported from the .docx. Visually "outside" the main editable page card
   but styled to feel like part of the page chrome. Hidden by default; the
   import handler reveals them when the imported doc actually has a
   header / footer. */
.page-header-zone,
.page-footer-zone {
  position: relative;
  width: 100%;
  background: var(--paper);
  /* Use the imported docx's pgMar values (set on :root by JS) so the
     header / footer text starts at exactly the same left edge as the
     body content above. Without the variables a hard-coded 1in indent
     would mis-align with docs that use non-1in margins (e.g. Foxit
     Master uses 0.8in left). Fallback to 1in for docs we don't have
     OOXML margins for. */
  padding: 0.6rem var(--de-margin-right, 1in) 0.6rem var(--de-margin-left, 1in);
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  font-family: 'Calibri', 'Segoe UI', sans-serif;
  font-size: 10pt;
  color: #475569;
  cursor: default;
  user-select: text;
  /* Above margin covers (z=1), gap divider (z=2), and the per-page banner
     clones (z=2). The canonical zone is what the user actually interacts
     with — it must paint on top of everything in the overlay. */
  z-index: 3;
}

.page-header-zone[hidden],
.page-footer-zone[hidden] { display: none; }

/* Ribbon dropdown — currently used by the Insert Field picker. The
   parent .ribbon-dropdown-wrap is position:relative so the menu can be
   absolutely positioned just below the button. */
.ribbon-dropdown-wrap {
  position: relative;
  display: inline-flex;
}
.ribbon-dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 50;
  min-width: 200px;
  background: white;
  border: 1px solid var(--border, #d4d4d4);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  padding: 4px 0;
  margin-top: 2px;
}
.ribbon-dropdown-menu[hidden] {
  display: none;
}
.ribbon-dropdown-menu button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 6px 12px;
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 0.82rem;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.ribbon-dropdown-menu button:hover {
  background: var(--accent-light, #ede7f6);
  color: var(--accent, #6750A4);
}
.ribbon-dropdown-menu button small {
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.72rem;
  opacity: 0.55;
  margin-left: 1em;
}

/* Override button shown on read-only H/F zones (image headers, field-code
   footers). Sits absolutely-positioned at the top-right of the zone,
   visible by default at low opacity so the user can find it. Clicking
   it confirms then converts the zone to a text-only mini editor. */
.de-hf-edit-override {
  position: absolute;
  top: 4px;
  right: 6px;
  z-index: 4; /* above the read-only content + the canonical zone z=3 */
  padding: 2px 8px;
  font-family: inherit;
  font-size: 0.7rem;
  background: var(--accent-light, #ede7f6);
  color: var(--accent, #6750A4);
  border: 1px solid var(--accent-border, #b39ddb);
  border-radius: 999px;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.12s ease, background 0.12s ease;
  user-select: none;
}
.de-hf-edit-override:hover {
  opacity: 1;
  background: var(--accent, #6750A4);
  color: white;
}

/* "✓ Done" — exits H/F text-editing mode back to the formatted (centered,
   tab-stop) read-only view. Shown only while a tab/field/image zone is being
   edited. More prominent than the Edit-text pill (full opacity, filled) so the
   way OUT of edit mode is obvious. */
.de-hf-done {
  position: absolute;
  top: 4px;
  right: 6px;
  z-index: 5;
  padding: 2px 10px;
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  background: var(--accent, #6750A4);
  color: #fff;
  border: 1px solid var(--accent, #6750A4);
  border-radius: 999px;
  cursor: pointer;
  user-select: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.de-hf-done:hover { background: #543b9a; }

/* Editable H/F: render tab paragraphs with Word-like tab distribution so
   "Edit text" mode doesn't collapse "<left>[tab]<center>[tab]" into one run.
   Scoped with :has(.hf-tab) so ONLY footer/header tab lines flex — normal
   paragraphs keep ordinary flow (avoids caret quirks in contenteditable flex).
   white-space:pre-wrap stops flexbox from trimming the spaces around the field
   pills, so "Page 1 of 14" keeps its spacing. (Perfect centering is restored
   by the 3-cell grid view on "✓ Done".) */
.page-decoration-content .ProseMirror p:has(.hf-tab) {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  white-space: pre-wrap;
}
.page-decoration-content .ProseMirror p:has(.hf-tab) .hf-tab {
  flex: 1 1 1.5em;
  min-width: 1.5em;
}

.page-decoration-label {
  position: absolute;
  top: 4px;
  right: 8px;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #cbd5e1;
  pointer-events: none;
}

.page-decoration-content {
  min-height: 1.2em;
}

/* When a header/footer carries an image (e.g. a logo banner) — let it
   fill the zone edge-to-edge without leaving the page-card padding around it. */
.page-header-zone .page-decoration-content,
.page-footer-zone .page-decoration-content {
  margin: -0.6rem -1in;
}

.page-decoration-content > p {
  padding: 0 1in;
}

.header-footer-img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* OL marker suffix overrides for imported lists. Word's <w:lvlText> can
   end in ')' or ']' or ':' (e.g. "%1)" for a) b) c)). Default CSS list
   markers use '.' so we override via ::marker for the non-period cases.
   Modern Chrome / Firefox / Safari all support `::marker { content: ... }`.
   The earlier attempt used `counter(list-item, var(--x))` which is
   inconsistently supported (Safari rejects var() inside counter() in some
   versions); explicit per-(suffix × style) rules avoid that entirely. */

/* --- paren ")" suffix --- */
#editor ol[data-list-suffix="paren"]:not([style]) > li::marker,
#editor ol[data-list-suffix="paren"][style*="decimal"]:not([style*="leading-zero"]) > li::marker {
  content: counter(list-item, decimal) ") ";
}
#editor ol[data-list-suffix="paren"][style*="lower-alpha"] > li::marker {
  content: counter(list-item, lower-alpha) ") ";
}
#editor ol[data-list-suffix="paren"][style*="upper-alpha"] > li::marker {
  content: counter(list-item, upper-alpha) ") ";
}
#editor ol[data-list-suffix="paren"][style*="lower-roman"] > li::marker {
  content: counter(list-item, lower-roman) ") ";
}
#editor ol[data-list-suffix="paren"][style*="upper-roman"] > li::marker {
  content: counter(list-item, upper-roman) ") ";
}
#editor ol[data-list-suffix="paren"][style*="decimal-leading-zero"] > li::marker {
  content: counter(list-item, decimal-leading-zero) ") ";
}

/* --- bracket "]" suffix --- */
#editor ol[data-list-suffix="bracket"]:not([style]) > li::marker,
#editor ol[data-list-suffix="bracket"][style*="decimal"]:not([style*="leading-zero"]) > li::marker {
  content: counter(list-item, decimal) "] ";
}
#editor ol[data-list-suffix="bracket"][style*="lower-alpha"] > li::marker {
  content: counter(list-item, lower-alpha) "] ";
}
#editor ol[data-list-suffix="bracket"][style*="upper-alpha"] > li::marker {
  content: counter(list-item, upper-alpha) "] ";
}
#editor ol[data-list-suffix="bracket"][style*="lower-roman"] > li::marker {
  content: counter(list-item, lower-roman) "] ";
}
#editor ol[data-list-suffix="bracket"][style*="upper-roman"] > li::marker {
  content: counter(list-item, upper-roman) "] ";
}

/* --- colon ":" suffix --- */
#editor ol[data-list-suffix="colon"]:not([style]) > li::marker,
#editor ol[data-list-suffix="colon"][style*="decimal"]:not([style*="leading-zero"]) > li::marker {
  content: counter(list-item, decimal) ": ";
}
#editor ol[data-list-suffix="colon"][style*="lower-alpha"] > li::marker {
  content: counter(list-item, lower-alpha) ": ";
}
#editor ol[data-list-suffix="colon"][style*="upper-alpha"] > li::marker {
  content: counter(list-item, upper-alpha) ": ";
}
#editor ol[data-list-suffix="colon"][style*="lower-roman"] > li::marker {
  content: counter(list-item, lower-roman) ": ";
}
#editor ol[data-list-suffix="colon"][style*="upper-roman"] > li::marker {
  content: counter(list-item, upper-roman) ": ";
}

/* Anchored layout for floating text boxes + images from OOXML wp:anchor */
.hf-anchored-container {
  position: relative;
  font-size: 9pt;
  color: white;
  overflow: hidden;
}

.hf-anchored-container p {
  margin: 0;
  line-height: 1.25;
}

.hf-anchored-container img {
  max-width: 100%;
  max-height: 100%;
}

/* Tab-stop spacers — flex-grow elements that push text to either side
   of the paragraph, approximating Word's tab-stop layout for simple
   "Label[TAB]Value" footer lines. */
.hf-anchored-container .hf-tab,
.page-header-zone .hf-tab,
.page-footer-zone .hf-tab {
  flex: 1 1 1em;
  min-width: 0.5em;
}

/* Borderless tables rendered inside header/footer zones. Word docs commonly
   use these for laying out logo + multi-column text. */
.page-header-zone table,
.page-footer-zone table {
  font-size: 9pt;
  color: inherit;
}

.page-header-zone table p,
.page-footer-zone table p {
  margin: 0;
  line-height: 1.3;
}

.page-header-zone table img,
.page-footer-zone table img {
  max-width: 100%;
  height: auto;
}

.page-decoration-content p {
  margin: 0 0 0.2em;
}

.page-decoration-content p:last-child {
  margin-bottom: 0;
}

.page-header-zone {
  border-bottom: 2px solid #e2e8f0;
}

.page-footer-zone {
  border-top: 2px solid #e2e8f0;
}

#editor .ProseMirror {
  outline: none;
  min-height: calc(11in - 2in);
  font-family: 'Calibri', 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 11pt;
  line-height: 1.5;
  color: #111827;
}

#editor h1, #editor h2, #editor h3, #editor h4 {
  font-family: 'Calibri Light', 'Calibri', 'Segoe UI', sans-serif;
  color: #1e3a5f;
  font-weight: 500;
}

/* Heading auto-number widget (display-only ProseMirror decoration rendered
   before a numbered heading's text — restores Word's style-based numbering
   mammoth drops). Inherits the heading's font/colour; not selectable/copyable. */
#editor .de-heading-number {
  user-select: none;
  -webkit-user-select: none;
  white-space: pre;
}

#editor h1 { font-size: 22pt; margin: 0.6em 0 0.4em; }
#editor h2 { font-size: 17pt; margin: 0.7em 0 0.35em; }
#editor h3 { font-size: 14pt; margin: 0.8em 0 0.3em; }
#editor h4 { font-size: 12pt; margin: 0.9em 0 0.3em; font-weight: 600; }

#editor p { margin: 0 0 0.6em; }
#editor ul, #editor ol { padding-left: 2em; margin: 0 0 0.6em; }
#editor li > p { margin: 0 0 0.2em; }
#editor li > p:last-child { margin-bottom: 0; }

#editor blockquote {
  border-left: 3px solid #cbd5e1;
  padding-left: 1em;
  color: #475569;
  margin: 0 0 0.6em;
  font-style: italic;
}

#editor hr {
  border: none;
  border-top: 1px solid #cbd5e1;
  margin: 1.5em 0;
}

#editor code {
  background: #f1f5f9;
  padding: 1px 5px;
  border-radius: 3px;
  font-family: 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
  font-size: 0.9em;
}

#editor pre {
  background: #f1f5f9;
  padding: 0.75em 1em;
  border-radius: 5px;
  overflow-x: auto;
  margin: 0 0 0.8em;
}
#editor pre code { background: none; padding: 0; }

#editor a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Tables */
#editor table {
  border-collapse: collapse;
  margin: 1em 0;
  width: 100%;
  table-layout: fixed;
  overflow: hidden;
}

#editor table td, #editor table th {
  border: 1px solid var(--table-border);
  padding: 0.45em 0.65em;
  vertical-align: top;
  min-width: 60px;
  position: relative;
}

#editor table th {
  background: var(--table-header-bg);
  font-weight: 600;
  text-align: left;
}

#editor .selectedCell {
  background: var(--selected-cell);
}

/* Custom page-break node — visually breaks the editor surface into "pages".
   The break renders as a gap that bleeds outside the page's white background,
   showing the gray editor-wrap underneath with subtle shadows on top and
   bottom to mimic the bottom of one page transitioning to the top of the next.
   Content after the break appears to "start on a new page" even though the
   editor is still one ProseMirror document. */
#editor .page-break {
  position: relative;
  /* Bleed left/right outside the 1in page padding so the gap spans full width */
  margin: 2.2em -1in;
  padding: 2.6em 0;
  background: var(--bg);   /* matches the editor-wrap gray background */
  border: none;
  text-align: center;
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #94a3b8;
  user-select: none;
}

/* Bottom edge of the "previous page" */
#editor .page-break::before {
  content: '';
  position: absolute;
  inset: 0 0 50% 0;
  background: linear-gradient(to top, rgba(0,0,0,0.07) 0%, transparent 100%);
  pointer-events: none;
}

/* Top edge of the "next page" */
#editor .page-break::after {
  content: '';
  position: absolute;
  inset: 50% 0 0 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.07) 0%, transparent 100%);
  pointer-events: none;
}

/* "Page Break" pill floats in the middle of the gap */
#editor .page-break .page-break-label {
  position: relative;
  display: inline-block;
  z-index: 1;
  background: white;
  border: 1px solid var(--border);
  padding: 0.3em 0.95em;
  border-radius: 999px;
  color: #64748b;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}

#editor .page-break.ProseMirror-selectednode .page-break-label {
  background: var(--accent-light);
  border-color: var(--accent-border);
  color: var(--accent);
}

/* The × remove button. Default-hidden so the page-break looks clean; fades
   in on hover (or when the node is selected) so removal is discoverable.
   Positioned just to the right of the centered "Page Break" pill, sitting
   in the same horizontal line. */
#editor .page-break .page-break-remove {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em;
  height: 1.6em;
  margin-left: 0.4em;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: #94a3b8;
  font-size: 1.05rem;
  line-height: 1;
  font-family: ui-sans-serif, system-ui, sans-serif;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms ease, background 120ms ease, color 120ms ease, border-color 120ms ease;
}

#editor .page-break:hover .page-break-remove,
#editor .page-break.ProseMirror-selectednode .page-break-remove,
#editor .page-break .page-break-remove:focus {
  opacity: 1;
}

#editor .page-break .page-break-remove:hover {
  background: #fee2e2;       /* light red */
  border-color: #fca5a5;     /* mid red */
  color: #b91c1c;            /* dark red */
}

#editor table p { margin: 0; }

#editor img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 0.4em auto;
  border-radius: 2px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
#editor img.ProseMirror-selectednode {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Drag handle for table column resize (when enabled) */
#editor .column-resize-handle {
  position: absolute;
  right: -2px;
  top: 0;
  bottom: -2px;
  width: 4px;
  background-color: var(--accent);
  pointer-events: none;
}

#editor .tableWrapper {
  overflow-x: auto;
  margin: 1em 0;
}

#editor.resize-cursor {
  cursor: col-resize;
}

/* Messages panel (import warnings) */
.messages[hidden] { display: none; }

.messages {
  position: fixed;
  bottom: 1.25rem;
  left: 1.25rem;
  width: 360px;
  max-width: calc(100vw - 2.5rem);
  max-height: 60vh;
  background: white;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.15);
  z-index: 50;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.messages-head {
  padding: 0.7rem 1rem;
  background: #fff7ed;
  border-bottom: 1px solid #fed7aa;
  color: #9a3412;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.85rem;
}

.messages-head button {
  background: none;
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  color: #9a3412;
  cursor: pointer;
  padding: 0;
}

#messages-list {
  list-style: none;
  margin: 0;
  padding: 0.4rem 0;
  overflow-y: auto;
  flex: 1;
  font-size: 0.82rem;
  color: var(--text-muted);
}

#messages-list li {
  padding: 0.35rem 1rem;
  border-bottom: 1px solid var(--border);
}
#messages-list li:last-child { border-bottom: none; }
#messages-list li code {
  background: #f3f4f6;
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.95em;
}

/* Context menu (right-click in a table cell) */
.context-menu {
  position: fixed;
  z-index: 200;
  background: white;
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  padding: 0.3rem 0;
  min-width: 200px;
  font-size: 0.85rem;
  user-select: none;
}

.context-menu[hidden] { display: none; }

.context-menu button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0.4rem 0.85rem;
  cursor: pointer;
  font-family: inherit;
  font-size: inherit;
  color: var(--text);
  white-space: nowrap;
}

.context-menu button:hover {
  background: var(--accent-light);
  color: var(--accent);
}

.context-menu button.danger { color: #b91c1c; }
.context-menu button.danger:hover { background: #fee2e2; color: #991b1b; }

.context-menu-sep {
  height: 1px;
  background: var(--border);
  margin: 0.3rem 0;
}

.context-menu-shading-group {
  padding: 0.3rem 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.context-menu-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-right: 0.25rem;
}

.shade-swatch {
  width: 18px !important;
  height: 18px !important;
  padding: 0 !important;
  border-radius: 4px !important;
  border: 1px solid var(--border-strong) !important;
  cursor: pointer;
}

.shade-swatch:hover {
  border-color: var(--accent) !important;
  transform: scale(1.1);
}

/* Image resize handle */
.image-resize-wrapper {
  position: relative;
  display: inline-block;
  margin: 0.4em auto;
}

.image-resize-wrapper.is-selected {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.image-resize-handle {
  position: absolute;
  right: -6px;
  bottom: -6px;
  width: 14px;
  height: 14px;
  background: var(--accent);
  border: 2px solid white;
  border-radius: 50%;
  cursor: nwse-resize;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  display: none;
}

.image-resize-wrapper.is-selected .image-resize-handle {
  display: block;
}

/* ---------- Polish-extension styling (added 2026-05-25) ---------- */

/* Placeholder: shown only on a truly-empty editor. Tiptap's Placeholder
   extension adds .is-editor-empty to the doc root; we attach a
   ::before pseudo-element with the placeholder text. */
.ProseMirror p.is-editor-empty:first-child::before {
  content: attr(data-placeholder);
  float: left;
  height: 0;
  pointer-events: none;
  color: #9ca3af;
  font-style: italic;
}

/* Focus extension: subtle left-border accent on the currently-focused node.
   Useful in long docs where it's hard to tell which paragraph the cursor
   is in. Soft accent (Material 3 purple at 20% alpha) — visible but
   doesn't compete with selection highlight. */
/* Focus accent intentionally disabled (UX feedback): the left bar +
   margin-left:-0.4em shift made the focused block visibly jump left, which is
   non-standard (Word shows no per-block focus indicator — only the caret and
   selection). The Focus extension still tags the focused node with .has-focus,
   so a subtler, NON-shifting cue can be reinstated here if ever wanted (e.g. a
   faint background, or a left bar drawn via box-shadow so it doesn't reflow). */
#editor .has-focus { /* no visual decoration */ }

/* Highlight mark — Tiptap renders this as <mark> by default. We override the
   browser default (browser-yellow tends to be a clashy #FFFF00) with a softer
   amber that matches the rest of the UI. multicolor:true means a future color
   picker could set background-color on the <mark>; this rule only applies
   when no inline style is present. */
#editor mark,
.de-bubble-menu mark,
.page-header-zone mark,
.page-footer-zone mark {
  background-color: #fef08a;
  padding: 0 2px;
  border-radius: 2px;
}

/* ---------- Bubble menu (floating inline toolbar) ----------
   Sits above the current selection; positioned by Tippy via the BubbleMenu
   extension. Buttons mirror the main toolbar's most-used inline formats. */
.de-bubble-menu {
  display: inline-flex;
  gap: 2px;
  align-items: center;
  background: #1f2937;
  color: white;
  padding: 4px;
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.18);
  z-index: 50;
}

.de-bubble-menu button {
  background: transparent;
  border: none;
  color: white;
  padding: 4px 7px;
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
  border-radius: 4px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.de-bubble-menu button:hover {
  background: rgba(255,255,255,0.12);
}

.de-bubble-menu button.is-active {
  background: rgba(255,255,255,0.22);
}

/* ---------- Status bar (word + character count) ---------- */
.de-status-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--toolbar-bg);
  border-top: 1px solid var(--border);
  padding: 0.35rem 1.2rem;
  font-size: 0.78rem;
  color: var(--text-muted);
  display: flex;
  gap: 0.6rem;
  align-items: center;
  z-index: 5;
}

.de-status-sep {
  color: var(--border-strong);
}

/* Push the editor up so it doesn't sit under the status bar */
#editor-wrap {
  padding-bottom: 4rem;
}

/* ---------- Editable header / footer zones ----------
   The zones already exist as read-only display surfaces above/below the
   editor; we now mount mini Tiptap editors INSIDE the .page-decoration-content
   container. Visual cues for editability: hover ring + a "Click to edit"
   label that fades on first edit. */
.page-header-zone,
.page-footer-zone {
  transition: box-shadow 0.15s ease;
}

.page-header-zone:hover,
.page-footer-zone:hover {
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), inset 0 0 0 1px rgba(103, 80, 164, 0.3);
}

.page-decoration-edit-hint {
  position: absolute;
  top: 4px;
  left: 8px;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #cbd5e1;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.25s ease;
}

/* Once the user starts editing, hide the hint. The .de-hf-edited class is
   toggled by JS on first content change. */
.page-header-zone.de-hf-edited .page-decoration-edit-hint,
.page-footer-zone.de-hf-edited .page-decoration-edit-hint {
  opacity: 0;
}

/* The mini-editor ProseMirror surface. Inherits a smaller, header-y font
   from the zone itself. Visible focus ring when the user clicks in.
   Restores the page padding stripped by .page-decoration-content's
   negative margin (which exists so banner images can bleed edge-to-edge). */
.page-header-zone .ProseMirror,
.page-footer-zone .ProseMirror {
  outline: none;
  min-height: 1.2em;
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  cursor: text;
  padding: 0 1in;
}

.page-header-zone .ProseMirror p,
.page-footer-zone .ProseMirror p {
  margin: 0 0 0.25em;
}
.page-header-zone .ProseMirror p:last-child,
.page-footer-zone .ProseMirror p:last-child {
  margin-bottom: 0;
}

.page-header-zone .ProseMirror-focused,
.page-footer-zone .ProseMirror-focused {
  box-shadow: inset 0 0 0 1px rgba(103, 80, 164, 0.45);
  border-radius: 2px;
}

/* "+ Add header" / "+ Add footer" affordance when the imported doc had no
   header/footer (or there isn't one yet). Plain text button with a dashed
   border so it doesn't look like a permanent UI element. */
.de-hf-add {
  display: block;
  width: 100%;
  background: transparent;
  border: 1px dashed var(--border-strong);
  border-radius: 4px;
  padding: 0.4rem 0.8rem;
  font-family: inherit;
  font-size: 0.75rem;
  color: var(--text-muted);
  cursor: pointer;
  margin: 0.5rem 1in;
  transition: all 0.15s ease;
}

.de-hf-add:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(37, 99, 235, 0.04);
}

/* Toast */
.toast {
  position: fixed;
  bottom: 1.25rem;
  right: 1.25rem;
  background: rgba(17,24,39,0.92);
  color: white;
  padding: 0.6rem 1rem;
  border-radius: 6px;
  font-size: 0.85rem;
  transform: translateY(80px);
  opacity: 0;
  transition: all 0.2s ease;
  pointer-events: none;
  z-index: 100;
  max-width: 360px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}

.toast.show {
  transform: translateY(0);
  opacity: 1;
}

.toast.error {
  background: #991b1b;
}

@media (max-width: 768px) {
  .page-header { padding: 1rem; }
  .page-header h1 { font-size: 1.25rem; }
  .page-header .tagline { font-size: 0.78rem; }
  .doc-status { display: none; }
  .ribbon-tabs { overflow-x: auto; }
  .ribbon-panels { overflow-x: auto; }
  .ribbon-panel { padding: 0.3rem; }
  .ribbon-group { padding: 0.1rem 0.4rem 0.2rem; }
  #editor {
    padding: 1.2rem;
    max-width: 100%;
    min-height: auto;
  }
}

/* =====================================================================
   PAGE VIEW (multi-page visual layout, Word-like)
   ---------------------------------------------------------------------
   The editor is a single Tiptap document. To make it *look* like Word's
   print-layout view we render the surface inside a `.de-page-container`
   and lay an overlay grid on top of the editor with one banner per page.
   The overlay is positioned absolutely inside `.de-page-stage`, so the
   editor still owns its own scrolling / text selection / cursor.
   ===================================================================== */

body.de-view-page #editor-wrap {
  background: #e5e7eb;
  padding: 1.5rem 1rem 6rem;
}

/* In page view, the existing `.page-stack` becomes the layout root. We
   keep the original element so Agent A's HF mini-editors stay mounted
   in the same DOM nodes (no teardown required when toggling views). */
body.de-view-page .page-stack {
  max-width: none;
  width: auto;
  gap: 0;
  align-items: center;
}

/* Page-view stage: positioned container so the per-page overlay can be
   absolutely placed over the editor. The CSS variables are layout knobs
   set by JS based on the imported docx's pgSz / pgMar (or sensible defaults
   for new docs). */
body.de-view-page .de-page-stage {
  display: block;
  position: relative;
  transform-origin: top center;
  transition: transform 0.15s ease;
  --de-page-width: 8.5in;
  --de-page-height: 11in;
  --de-margin-top: 1in;
  --de-margin-right: 1in;
  --de-margin-bottom: 1in;
  --de-margin-left: 1in;
  --de-header-h: 0px;
  --de-footer-h: 0px;
  --de-gap: 18px;
  width: var(--de-page-width);
}

/* The Tiptap editor in page view: still one continuous editable surface,
   but sized to a "page" width with the page's left/right margins as
   padding. Top/bottom padding leaves room for the header / footer
   banners; the overlay (below) draws on top. */
body.de-view-page #editor {
  background: var(--paper);
  width: var(--de-page-width);
  min-height: var(--de-page-height);
  /* Top/bottom padding match Word's logical page margins. The header / footer
     overlay banners (positioned absolutely, see below) sit INSIDE the top /
     bottom margin areas — they overlap the margin whitespace rather than
     adding to it, so a 1in margin + 0.5in header gives a Word-like page
     where the header floats in the top inch. For oversized banners (e.g.
     Foxit-georgia's 2in image banner that pokes down BELOW the top margin)
     we use max() so the content gets pushed down rather than crashing into
     the header. --de-header-h / --de-footer-h are measured banner heights
     (zero when no banner is present). */
  padding:
    max(var(--de-margin-top), calc(var(--de-first-header-top, 48px) + var(--de-header-h) + 0.15in))
    var(--de-margin-right)
    max(var(--de-margin-bottom), calc(var(--de-footer-h) + var(--de-footer-offset, 48px) + 0.15in))
    var(--de-margin-left);
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06);
  position: relative;
  z-index: 1;
}

body.de-view-page #editor .ProseMirror {
  min-height: 0;
}

/* In page view we hide the legacy single-pair zones at the top/bottom
   of the page-stack — the per-page overlay banners replace them. The
   first-page mini-editors stay mounted in the (now-hidden) zones so
   they remain editable when the user switches back to continuous view.
   Wait — actually we want them visible in page view too, but only the
   FIRST one on the first page. The overlay banners mirror them.
   Strategy: the .page-header-zone / .page-footer-zone stays in the DOM
   but is rendered INSIDE the overlay containers via absolute positioning
   so the mini editors keep DOM identity. See below. */

/* The overlay layer sits *over* the editor. Most of it is pointer-events:
   none, so clicks/drags fall through to the editor underneath. Only the
   header/footer banners on individual pages accept pointer events. */
.de-page-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--de-page-width);
  pointer-events: none;
  z-index: 2;
}

/* Page-boundary indicator: horizontal gap between visible pages.
   Drawn over the editor's white background, creating the illusion that
   one page ends and another starts. The gap is var(--de-gap)px tall. */
.de-page-gap {
  position: absolute;
  left: 0;
  width: 100%;
  height: var(--de-gap, 18px);
  background: #e5e7eb;
  box-shadow:
    inset 0 6px 6px -4px rgba(0,0,0,0.10),
    inset 0 -6px 6px -4px rgba(0,0,0,0.10);
  pointer-events: none;
  /* Higher z-index than the body editor but lower than canonical zones. */
  z-index: 2;
}

/* Opaque margin cover — paints the top/bottom margin strip of every page
   with the paper-white background so body content (one continuous editor
   underneath the overlays) doesn't bleed into the margin areas between
   pages. Without this, long items that span pages (e.g. a 20-item OL
   that flows from page N to page N+1) leak a slice of text just above
   the gap and just below it. z-index 1 sits ABOVE the body editor but
   BELOW the canonical H/F zones (z-index 3) and the per-page banners
   (z-index 2). */
.de-page-margin-cover {
  position: absolute;
  left: 0;
  width: 100%;
  background: var(--paper, #ffffff);
  pointer-events: none;
  z-index: 1;
}

/* Header banner repeated at the top of each page (after the first). */
.de-page-header-overlay,
.de-page-footer-overlay {
  position: absolute;
  left: 0;
  width: 100%;
  box-sizing: border-box;
  font-family: 'Calibri', 'Segoe UI', sans-serif;
  font-size: 10pt;
  color: #475569;
  overflow: hidden;
  background: var(--paper);
  pointer-events: auto;
  user-select: none;
  /* Above the margin-cover (z=1) and gap (z=2), below canonical zones (z=3). */
  z-index: 2;
  /* No own padding: the content inside (either plain paragraph or anchored
     container) supplies its own positioning. Matches the canonical zone
     which uses `padding: 0.4rem var(--de-margin-*)` only for plain
     paragraphs; anchored content bypasses via negative-margin .page-
     decoration-content trick. */
}

/* Plain-paragraph overlay content: pad to align with body text columns. */
.de-page-overlay-content:not(:has(.hf-anchored-container)):not(:has(table)) {
  padding: 0.4rem var(--de-margin-right, 1in) 0.4rem var(--de-margin-left, 1in);
}

.de-page-header-overlay { border-bottom: 1px solid #f1f5f9; }
.de-page-footer-overlay { border-top: 1px solid #f1f5f9; }

/* Read-only mirror copies of the canonical header/footer content.
   Inline elements inside should clamp; banners shouldn't grow with content
   (height = header_h / footer_h on the first page, measured at render). */
.de-page-overlay-content {
  margin: 0;
  padding: 0;
  font-size: inherit;
  color: inherit;
}

.de-page-overlay-content p {
  margin: 0 0 0.2em;
  line-height: 1.3;
}

.de-page-overlay-content img {
  max-width: 100%;
  height: auto;
}

/* When the canonical zone uses a mini Tiptap editor, its DOM includes a
   .ProseMirror wrapper with `padding: 0 1in` (from the zone's editable-
   mount rule). Cloned into the overlay container, that padding would
   double up with the overlay's own margin. Zero it out for clones. */
.de-page-overlay-content .ProseMirror {
  padding: 0 !important;
  margin: 0 !important;
  outline: none !important;
  cursor: default !important;
}

/* Read-only banner: prevent the overlay copy from looking interactive. */
.de-page-header-overlay,
.de-page-footer-overlay {
  cursor: default;
}

/* The canonical zone's content has `margin: -0.6rem -1in` to allow image
   bleed; cloned, that negative margin would push the content out past the
   overlay container. Strip it in the clone. */
.de-page-overlay-content > [class*="page-decoration-content"],
.de-page-overlay-content > .page-decoration-content {
  margin: 0 !important;
}

/* "Page N of M" pill at the bottom-right of each page overlay. */
.de-page-number {
  position: absolute;
  bottom: 4px;
  right: 12px;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #cbd5e1;
  pointer-events: none;
}

/* In page view, the editor's `.page-break` node should fill the rest of
   the current page so subsequent content visually starts a new page. The
   layout overlay handles the gap; the page-break node itself becomes a
   compact pill instead of the big striped band used in continuous view. */
body.de-view-page #editor .page-break {
  margin: 0;
  padding: 0.6em 0;
  background: transparent;
  text-align: center;
  break-before: page;
}

body.de-view-page #editor .page-break::before,
body.de-view-page #editor .page-break::after {
  display: none;
}

body.de-view-page #editor .page-break .page-break-label {
  background: #fef9c3;
  border-color: #fde68a;
  color: #92400e;
}

/* In page view we move the legacy header/footer zones inside the stage
   as the canonical (editable) first-page banners. Their existing styling
   stays — only positioning changes. */
body.de-view-page .page-header-zone,
body.de-view-page .page-footer-zone {
  position: absolute;
  left: 0;
  width: var(--de-page-width);
  margin: 0;
  border-radius: 0;
  z-index: 3;
  /* Use page margins instead of the legacy 1in fixed padding so the banner
     content lines up with the body text on the same x-axis. */
  padding: 0.4rem var(--de-margin-right) 0.4rem var(--de-margin-left);
  box-shadow: none;
  background: var(--paper);
}

/* Strip the negative-margin trick on the inner content wrapper in page
   view — banners no longer bleed past the page edge. */
body.de-view-page .page-header-zone .page-decoration-content,
body.de-view-page .page-footer-zone .page-decoration-content {
  margin: 0;
}

/* Same for the ProseMirror padding fix-up — the outer zone provides it. */
body.de-view-page .page-header-zone .ProseMirror,
body.de-view-page .page-footer-zone .ProseMirror {
  padding: 0;
}

body.de-view-page .page-header-zone {
  /* Header sits inside the top margin: top edge at `header offset` from
     page top (pgMar w:header), defaulting to 0.5in. JS sets the variable. */
  top: var(--de-first-header-top, 0);
}

body.de-view-page .page-footer-zone {
  /* Footer position is computed in JS (depends on page height + footer
     height + page index). JS sets `--de-first-footer-top` on the stage. */
  top: var(--de-first-footer-top, 0);
}

/* When a zone is hidden but the doc has no HF, take it out of layout. */
body.de-view-page .page-header-zone[hidden],
body.de-view-page .page-footer-zone[hidden] { display: none; }

/* Zoom selector visual tweak in the ribbon */
.ribbon select#zoom-select,
.ribbon select#view-select {
  min-width: 5em;
}

/* Page-number readout in the status bar */
.de-status-pages {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.78rem;
}

/* =====================================================================
   FILLABLE FIELDS — Tiptap Mention pills + side panel + suggestion popup
   ---------------------------------------------------------------------
   Contract templates use placeholders like {party_1}. Each placeholder
   renders as a styled inline "pill" so the user can identify and fill
   them at a glance. On export, the pill round-trips as the plain
   `{name}` literal in a normal Word text run (no custom OOXML node).
   ===================================================================== */
.de-field-pill {
  display: inline-block;
  padding: 0 0.4em;
  margin: 0 1px;
  border-radius: 4px;
  background: #ede7f6;       /* light purple */
  border: 1px solid #b39ddb; /* darker purple */
  color: #4527a0;            /* deep purple text */
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.92em;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  line-height: 1.4;
}
.de-field-pill:hover {
  background: #d1c4e9;
}
.de-field-pill.de-field-filled {
  background: #e8f5e9;       /* light green */
  border-color: #81c784;
  color: #1b5e20;
  font-family: inherit;      /* filled values look like normal text */
  font-size: 1em;
}
.de-field-pill.de-field-filled:hover {
  background: #c8e6c9;
}

/* Suggestion popup that appears when the user types `{`. Plain absolute-
   positioned <div> — no tippy.js dep beyond what BubbleMenu pulls in. */
.de-field-suggestion {
  position: absolute;
  z-index: 1000;
  background: white;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  min-width: 220px;
  max-width: 320px;
  max-height: 260px;
  overflow-y: auto;
  display: none;
}
.de-field-suggestion ul {
  list-style: none;
  margin: 0;
  padding: 4px 0;
}
.de-field-suggestion-item {
  padding: 5px 12px;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.85rem;
  color: #1f2937;
  cursor: pointer;
}
.de-field-suggestion-item:hover,
.de-field-suggestion-item.is-selected {
  background: #ede7f6;
  color: #4527a0;
}
.de-field-suggestion-empty {
  padding: 8px 12px;
  font-size: 0.78rem;
  color: var(--text-muted, #6b7280);
  font-style: italic;
}

/* ---------- Inline pill-click editor ---------- */
.de-field-inline-edit {
  position: absolute;
  z-index: 1001;
  background: white;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  padding: 10px 12px;
  min-width: 260px;
}
.de-field-inline-edit[hidden] {
  display: none;
}
.de-field-inline-label {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted, #6b7280);
  margin-bottom: 6px;
}
.de-field-inline-label span {
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  color: #4527a0;
  font-weight: 600;
}
.de-field-inline-edit input[type="text"] {
  width: 100%;
  padding: 5px 8px;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 4px;
  font-size: 0.9rem;
  font-family: inherit;
  box-sizing: border-box;
}
.de-field-inline-edit input[type="text"]:focus {
  outline: none;
  border-color: #7e57c2;
  box-shadow: 0 0 0 2px rgba(126, 87, 194, 0.2);
}
.de-field-inline-actions {
  margin-top: 8px;
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}
.de-field-inline-apply,
.de-field-inline-clear {
  border: 1px solid var(--border, #d1d5db);
  background: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
}
.de-field-inline-apply {
  background: #4527a0;
  border-color: #4527a0;
  color: white;
}
.de-field-inline-apply:hover { background: #311b92; border-color: #311b92; }
.de-field-inline-clear:hover { background: #f3f4f6; }

/* ---------- Fields side panel ---------- */
.de-fields-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  background: white;
  border-left: 1px solid var(--border, #d1d5db);
  box-shadow: -4px 0 18px rgba(0,0,0,0.06);
  z-index: 60;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Override the `display:flex` rule above when [hidden] is set — without this,
   the panel stays visible even when JS sets aside.hidden=true. */
.de-fields-panel[hidden] {
  display: none;
}
.de-fields-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-fields-panel-head strong {
  font-size: 0.95rem;
  color: #1f2937;
}
#fields-panel-close {
  background: transparent;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-muted, #6b7280);
  padding: 0 4px;
}
#fields-panel-close:hover { color: #1f2937; }
.de-fields-panel-actions {
  padding: 10px 16px;
  display: flex;
  gap: 8px;
  border-bottom: 1px solid var(--border, #d1d5db);
  flex-wrap: wrap;
}
.de-fields-panel-actions button,
.de-fields-import-label {
  border: 1px solid var(--border, #d1d5db);
  background: white;
  padding: 5px 12px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
  color: #1f2937;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.de-fields-panel-actions button:hover,
.de-fields-import-label:hover { background: #f3f4f6; }
.de-fields-panel-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
#fields-apply-all {
  background: #4527a0;
  color: white;
  border-color: #4527a0;
}
#fields-apply-all:hover:not(:disabled) { background: #311b92; }
.de-fields-panel-empty {
  padding: 20px 16px;
  font-size: 0.83rem;
  color: var(--text-muted, #6b7280);
  text-align: center;
}
.de-fields-panel-empty code {
  background: #ede7f6;
  border: 1px solid #b39ddb;
  border-radius: 3px;
  padding: 1px 5px;
  color: #4527a0;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
}
.de-fields-panel-list {
  list-style: none;
  margin: 0;
  padding: 8px 0;
  overflow-y: auto;
  flex: 1;
}
.de-fields-panel-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "id count"
    "input apply"
    "input clear";
  grid-template-rows: auto auto;
  gap: 4px 6px;
  padding: 10px 16px;
  border-bottom: 1px solid #f3f4f6;
  align-items: center;
}
/* Tighter layout: id on top row, input + apply + clear all on second row */
.de-fields-panel-row {
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "id    id    count"
    "input apply clear";
}
.de-fields-panel-id {
  grid-area: id;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.82rem;
  color: #4527a0;
  font-weight: 500;
  overflow-wrap: anywhere;
}
.de-fields-panel-count {
  grid-area: count;
  font-size: 0.7rem;
  color: var(--text-muted, #6b7280);
  background: #f3f4f6;
  padding: 1px 5px;
  border-radius: 3px;
}
.de-fields-panel-input {
  grid-area: input;
  width: 100%;
  padding: 4px 8px;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 4px;
  font-size: 0.85rem;
  font-family: inherit;
  box-sizing: border-box;
}
.de-fields-panel-input:focus {
  outline: none;
  border-color: #7e57c2;
  box-shadow: 0 0 0 2px rgba(126, 87, 194, 0.2);
}
.de-fields-panel-apply {
  grid-area: apply;
  border: 1px solid #4527a0;
  background: #4527a0;
  color: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 0.75rem;
  font-family: inherit;
  cursor: pointer;
}
.de-fields-panel-apply:hover { background: #311b92; border-color: #311b92; }
.de-fields-panel-clear {
  grid-area: clear;
  border: 1px solid var(--border, #d1d5db);
  background: white;
  color: var(--text-muted, #6b7280);
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}
.de-fields-panel-clear:hover { background: #f3f4f6; color: #1f2937; }

/* When the panel is open, push the status-bar's right edge inward so the
   word-count text doesn't sit under the panel. The page-stage stays centred
   in the remaining width. */
body.de-fields-panel-open .de-status-bar {
  right: 360px;
}

/* =====================================================================
   TRACK CHANGES + COMMENTS
   ---------------------------------------------------------------------
   Visual styling matching Word's review markup. Insertions render in
   green with an underline; deletions in red with a strikethrough.
   Comment ranges get a soft yellow highlight that becomes more prominent
   when the row in the Comments panel is clicked.
   ===================================================================== */
.de-track-ins {
  color: #0d7a3b;
  text-decoration: underline;
  text-decoration-color: #0d7a3b;
}
.de-track-ins[data-author]::after,
.de-track-del[data-author]::after {
  /* Tooltip-style attribute hint via title="" — actual title is set in JS;
     this is just a no-op rule reserved for future polish. */
}
.de-track-del {
  color: #c62828;
  text-decoration: line-through;
  text-decoration-color: #c62828;
}
.de-comment-marked {
  background-color: #fff8c5;
  border-bottom: 2px solid #d4a72c;
  padding-bottom: 1px;
  cursor: pointer;
}
.de-comment-marked.is-focused {
  background-color: #ffe78a;
  outline: 2px solid #d4a72c;
  outline-offset: 0;
}

/* Tracked formatting change — dotted orange underline + a CSS-tooltip
   on hover that names the author. Distinct visual from .de-track-ins/del
   so a single run can carry BOTH (e.g. an inserted run that also has a
   formatting change). */
.de-format-change {
  border-bottom: 2px dotted #ff9800;
  position: relative;
}
.de-format-change:hover::after {
  content: attr(data-author) " changed formatting";
  position: absolute;
  bottom: 100%;
  left: 0;
  background: #333;
  color: white;
  padding: 0.3em 0.6em;
  font-size: 0.75rem;
  white-space: nowrap;
  border-radius: 3px;
  z-index: 100;
  pointer-events: none;
}

/* Toolbar Track Changes toggle active state */
#toggle-track-changes.is-active {
  background: #dcfce7;
  border-color: #15803d;
  color: #15803d;
}
#review-toolbar-group button {
  font-size: 0.78rem;
}
.de-status-review {
  margin-left: 0.5rem;
  color: #6b7280;
  font-size: 0.78rem;
}

/* ---------- Comments side panel ----------
   Same shape as the Fields side panel but with a per-row avatar + body
   layout instead of an input + apply button. */
.de-comments-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  background: white;
  border-left: 1px solid var(--border, #d1d5db);
  box-shadow: -4px 0 18px rgba(0,0,0,0.06);
  z-index: 60;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.de-comments-panel[hidden] {
  display: none;
}
.de-comments-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-comments-panel-head strong {
  font-size: 0.95rem;
  color: #1f2937;
}
#comments-panel-close {
  background: transparent;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-muted, #6b7280);
  padding: 0 4px;
}
#comments-panel-close:hover { color: #1f2937; }
.de-comments-panel-meta {
  padding: 10px 16px;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-comments-reviewer-label {
  display: flex;
  flex-direction: column;
  font-size: 0.78rem;
  color: var(--text-muted, #6b7280);
  gap: 4px;
}
.de-comments-reviewer-label input {
  padding: 4px 8px;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 4px;
  font-size: 0.85rem;
  font-family: inherit;
}
.de-comments-panel-empty {
  padding: 20px 16px;
  font-size: 0.83rem;
  color: var(--text-muted, #6b7280);
  text-align: center;
}
.de-comments-panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}
.de-comments-panel-row {
  padding: 12px 16px;
  border-bottom: 1px solid #f3f4f6;
  cursor: pointer;
}
.de-comments-panel-row:hover {
  background: #fafbff;
}
.de-comments-row-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.de-comments-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #4527a0;
  color: white;
  font-size: 0.75rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.de-comments-meta {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.de-comments-author {
  font-size: 0.83rem;
  font-weight: 500;
  color: #1f2937;
}
.de-comments-date {
  font-size: 0.7rem;
  color: var(--text-muted, #6b7280);
}
.de-comments-body {
  font-size: 0.83rem;
  color: #374151;
  white-space: pre-wrap;
  word-break: break-word;
  margin-left: 42px;
  margin-bottom: 6px;
}
.de-comments-actions {
  display: flex;
  gap: 6px;
  margin-left: 42px;
}
.de-comments-actions button {
  border: 1px solid var(--border, #d1d5db);
  background: white;
  padding: 3px 8px;
  border-radius: 3px;
  font-size: 0.72rem;
  font-family: inherit;
  cursor: pointer;
  color: var(--text-muted, #6b7280);
}
.de-comments-actions button:hover {
  background: #f3f4f6;
  color: #1f2937;
}

/* ---------- Reply threads + Resolve workflow ---------- */
/* Reply rows render indented from the parent's left edge so the thread is
   visually grouped. No border between replies — only the parent gets a
   bottom border via .de-comments-panel-row. */
.de-comments-replies {
  margin-left: 1.5em;
  margin-top: 4px;
  margin-bottom: 4px;
  border-left: 2px solid #e5e7eb;
  padding-left: 8px;
}
.de-comments-reply {
  padding: 6px 0;
}
.de-comments-reply + .de-comments-reply {
  border-top: 1px dashed #f1f5f9;
  margin-top: 2px;
}
.de-comments-reply .de-comments-row-head {
  margin-bottom: 4px;
}
.de-comments-reply .de-comments-body {
  margin-left: 30px; /* smaller avatar = smaller indent */
  font-size: 0.78rem;
}
.de-comments-avatar-sm {
  width: 22px;
  height: 22px;
  font-size: 0.62rem;
  background: #6b7280;
}

/* Reply composer (textarea + Submit/Cancel) — appears between the parent's
   body and its actions row when "Reply" is clicked. */
.de-comments-reply-composer {
  margin-left: 42px;
  margin-bottom: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.de-comments-reply-composer textarea {
  width: 100%;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.83rem;
  padding: 6px 8px;
  resize: vertical;
  min-height: 44px;
}
.de-comments-reply-composer textarea:focus {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 2px rgba(37,99,235,0.15);
}
.de-comments-reply-composer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}
.de-comments-reply-composer-actions button {
  border: 1px solid var(--border, #d1d5db);
  background: white;
  padding: 3px 10px;
  border-radius: 3px;
  font-size: 0.75rem;
  font-family: inherit;
  cursor: pointer;
  color: var(--text-muted, #6b7280);
}
.de-comments-reply-composer-actions button:hover {
  background: #f3f4f6;
  color: #1f2937;
}
.de-comments-reply-submit {
  background: #2563eb !important;
  color: white !important;
  border-color: #2563eb !important;
}
.de-comments-reply-submit:hover {
  background: #1d4ed8 !important;
  border-color: #1d4ed8 !important;
}

/* Resolved comments: faded, with body strikethrough. Stay clickable so the
   user can unresolve. */
.de-comments-panel-row.is-resolved {
  opacity: 0.5;
}
.de-comments-panel-row.is-resolved .de-comments-body {
  text-decoration: line-through;
  color: #6b7280;
}

/* Disclosure at the bottom of the panel grouping all resolved comments. */
.de-comments-resolved-section {
  border-top: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-comments-resolved-section summary {
  padding: 10px 16px;
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted, #6b7280);
  user-select: none;
  list-style: none;
}
.de-comments-resolved-section summary::-webkit-details-marker { display: none; }
.de-comments-resolved-section summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 6px;
  transition: transform 120ms;
}
.de-comments-resolved-section[open] summary::before {
  transform: rotate(90deg);
}
.de-comments-resolved-section summary:hover {
  background: #f3f4f6;
}
.de-comments-resolved-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

body.de-comments-panel-open .de-status-bar {
  right: 360px;
}
/* When both panels are open at once, stack them — comments on the inside,
   fields on the outside — by giving fields a slightly higher z-index and
   shifting the comments panel left of where the fields panel sits. For
   v1 we just prevent the two from overlapping by closing one before
   opening the other (handled in JS, not needed in CSS). */

/* =====================================================================
   FOOTNOTES + ENDNOTES
   ---------------------------------------------------------------------
   Subtle blue superscript pills inside the editor. Hover gives them a
   light highlight to confirm they're interactive. The side panel that
   lists every footnote uses the same shape as the Comments panel.
   ===================================================================== */
.de-footnote-ref,
.de-endnote-ref {
  font-size: 75%;
  line-height: 0;
  vertical-align: super;
  color: #2563eb;
  cursor: pointer;
  font-weight: 600;
  padding: 0 1px;
  border-radius: 2px;
  transition: background-color 120ms;
  /* Tiptap inserts a contenteditable=false wrapper around atom nodes; ensure
     the user can still click without entering edit mode mid-pill. */
  user-select: none;
}
.de-footnote-ref:hover,
.de-endnote-ref:hover {
  background-color: #dbeafe;
}
.de-endnote-ref { color: #7c3aed; }
.de-endnote-ref:hover { background-color: #ede9fe; }
.de-footnote-ref.is-focused,
.de-endnote-ref.is-focused {
  background-color: #fde68a;
  outline: 1px solid #d4a72c;
}

/* ---------- Page-bottom footnote band ---------- */
/* Footnotes appear at the bottom of the page they're referenced from, like
   Word's print layout. The band sits inside the page's margins (uses the
   same CSS variables as the editor) and is non-interactive (pointer-events
   disabled) so clicks fall through to the body content. The side panel
   stays the canonical editor for footnote text — page-bottom is a visual
   mirror. */
.de-page-footnote-band {
  position: absolute;
  left: var(--de-margin-left);
  right: var(--de-margin-right);
  font-size: 0.78rem;
  line-height: 1.4;
  color: #475569;
  pointer-events: none;
}
.de-page-footnote-band::before {
  content: '';
  display: block;
  width: 30%;
  border-top: 1px solid #cbd5e1;
  margin-bottom: 0.3em;
}
.de-page-footnote-band .de-page-footnote-row {
  margin: 0;
}
.de-page-footnote-band .de-page-footnote-num {
  font-weight: 600;
  margin-right: 0.3em;
  color: #2563eb;
}

/* ---------- Footnotes / Endnotes side panel ---------- */
.de-footnotes-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  background: white;
  border-left: 1px solid var(--border, #d1d5db);
  box-shadow: -4px 0 18px rgba(0,0,0,0.06);
  z-index: 60;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.de-footnotes-panel[hidden] { display: none; }
.de-footnotes-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-footnotes-panel-head strong {
  font-size: 0.95rem;
  color: #1f2937;
}
#footnotes-panel-close {
  background: transparent;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-muted, #6b7280);
  padding: 0 4px;
}
#footnotes-panel-close:hover { color: #1f2937; }
.de-footnotes-panel-tabs {
  display: flex;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-footnotes-panel-tabs button {
  flex: 1;
  background: transparent;
  border: none;
  padding: 8px 12px;
  font-size: 0.82rem;
  color: var(--text-muted, #6b7280);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  font-family: inherit;
}
.de-footnotes-panel-tabs button.is-active {
  color: #1f2937;
  border-bottom-color: #2563eb;
  font-weight: 500;
}
.de-footnotes-panel-actions {
  display: flex;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border, #d1d5db);
  background: #fafafa;
}
.de-footnotes-panel-actions button {
  background: white;
  border: 1px solid var(--border, #d1d5db);
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 0.78rem;
  cursor: pointer;
  font-family: inherit;
  color: #1f2937;
}
.de-footnotes-panel-actions button:hover { background: #f3f4f6; }
.de-footnotes-panel-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.de-footnotes-panel-empty {
  padding: 20px 16px;
  font-size: 0.83rem;
  color: var(--text-muted, #6b7280);
  text-align: center;
}
.de-footnotes-panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}
.de-footnote-row {
  padding: 10px 16px;
  border-bottom: 1px solid #f3f4f6;
  display: flex;
  gap: 8px;
  cursor: pointer;
}
.de-footnote-row:hover { background: #fafbff; }
.de-footnote-row.is-focused { background: #fffbeb; }
.de-footnote-num {
  flex-shrink: 0;
  font-size: 0.78rem;
  font-weight: 600;
  color: #2563eb;
  min-width: 28px;
}
.de-footnote-row[data-kind="endnote"] .de-footnote-num { color: #7c3aed; }
.de-footnote-body {
  flex: 1;
  min-width: 0;
  font-size: 0.83rem;
  color: #374151;
  border: 1px solid transparent;
  border-radius: 3px;
  padding: 2px 4px;
  outline: none;
  white-space: pre-wrap;
  word-break: break-word;
}
.de-footnote-body:hover {
  border-color: #e5e7eb;
}
.de-footnote-body:focus {
  border-color: #2563eb;
  background: white;
}
.de-footnote-remove {
  flex-shrink: 0;
  background: transparent;
  border: none;
  color: #9ca3af;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
}
.de-footnote-remove:hover { color: #dc2626; }
body.de-footnotes-panel-open .de-status-bar {
  right: 360px;
}

/* Toolbar footnotes button active state */
#toggle-footnotes-panel.is-active {
  background: #dbeafe;
  border-color: #2563eb;
  color: #2563eb;
}

/* =====================================================================
   MAIL MERGE MODAL
   ---------------------------------------------------------------------
   Three-step wizard for generating N documents from a CSV/JSON/XLSX
   data source against the current template's `{field}` placeholders.
   Triggered by the "Mail Merge" toolbar button. Styles use the de-mm-*
   prefix to stay clear of the other side-panel styles.
   ===================================================================== */
.de-mm-modal[hidden] { display: none; }
.de-mm-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
}
.de-mm-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(2px);
}
.de-mm-dialog {
  position: relative;
  background: white;
  border-radius: 10px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.35), 0 6px 18px rgba(0,0,0,0.18);
  width: 720px;
  max-width: calc(100vw - 2rem);
  max-height: calc(100vh - 2rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.de-mm-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--border);
  background: #fafafa;
}
.de-mm-head strong {
  font-size: 1rem;
  color: #1f2937;
}
.de-mm-step-indicator {
  flex: 1;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.de-mm-close {
  background: transparent;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 0.3rem;
}
.de-mm-close:hover { color: #1f2937; }
.de-mm-step {
  flex: 1;
  overflow-y: auto;
  padding: 1rem 1.2rem 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.de-mm-step[hidden] { display: none; }
.de-mm-tabs {
  display: flex;
  gap: 0.4rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.25rem;
}
.de-mm-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.5rem 0.85rem;
  font-size: 0.85rem;
  font-family: inherit;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  margin-bottom: -1px;
}
.de-mm-tab:hover { color: #1f2937; }
.de-mm-tab.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.de-mm-tab-pane[hidden] { display: none; }
.de-mm-tab-pane {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.de-mm-label {
  font-size: 0.8rem;
  font-weight: 500;
  color: #374151;
}
.de-mm-textarea {
  width: 100%;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.82rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  resize: vertical;
  box-sizing: border-box;
  background: #fafafa;
  color: #1f2937;
}
.de-mm-textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: white;
  box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
.de-mm-file-input {
  font-size: 0.85rem;
  padding: 0.3rem 0;
}
.de-mm-action {
  align-self: flex-start;
  background: white;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.4rem 0.85rem;
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
  color: #1f2937;
}
.de-mm-action:hover { background: #f1f5f9; border-color: var(--border-strong); }
.de-mm-options {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.de-mm-checkbox {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.8rem;
  color: #374151;
  cursor: pointer;
  line-height: 1.35;
}
.de-mm-checkbox input { margin-top: 2px; }
.de-mm-hint {
  margin: 0;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.de-mm-hint code {
  background: #f3f4f6;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  font-size: 0.75rem;
}
.de-mm-error {
  background: #fee2e2;
  border: 1px solid #fca5a5;
  color: #991b1b;
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  font-size: 0.8rem;
}
.de-mm-warning {
  background: #fef3c7;
  border: 1px solid #fcd34d;
  color: #92400e;
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  font-size: 0.8rem;
}
.de-mm-preview {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fafafa;
  padding: 0.6rem;
}
.de-mm-preview-summary {
  font-size: 0.8rem;
  color: #374151;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: center;
}
.de-mm-preview-summary strong { color: #1f2937; }
.de-mm-preview-table-wrap {
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: white;
}
.de-mm-preview-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.78rem;
  width: 100%;
}
.de-mm-preview-table thead th {
  position: sticky;
  top: 0;
  background: #f1f5f9;
  border-bottom: 1px solid var(--border-strong);
  padding: 0.45rem 0.55rem;
  text-align: left;
  font-weight: 600;
  color: #1f2937;
  white-space: nowrap;
  z-index: 1;
}
.de-mm-preview-table tbody td {
  padding: 0.4rem 0.55rem;
  border-bottom: 1px solid #f3f4f6;
  vertical-align: top;
  color: #374151;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.de-mm-preview-table tbody tr:last-child td { border-bottom: none; }
.de-mm-col-marker {
  display: inline-block;
  margin-right: 4px;
  font-weight: 700;
}
.de-mm-col-match { color: #047857; }
.de-mm-col-nomatch { color: #b45309; }
.de-mm-col-header-row {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.de-mm-insert-field {
  background: transparent;
  border: 1px solid #c4b5fd;
  border-radius: 3px;
  color: #4527a0;
  font-size: 0.68rem;
  padding: 1px 6px;
  cursor: pointer;
  margin-left: 4px;
  font-family: inherit;
}
.de-mm-insert-field:hover { background: #ede9fe; }
.de-mm-output-mode {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.6rem 0.8rem 0.7rem;
  margin: 0;
}
.de-mm-output-mode legend {
  font-size: 0.78rem;
  font-weight: 600;
  color: #374151;
  padding: 0 0.4rem;
}
.de-mm-radio {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.82rem;
  color: #374151;
  padding: 0.25rem 0;
  cursor: pointer;
  line-height: 1.4;
}
.de-mm-radio input { margin-top: 3px; }
.de-mm-name-label { margin-top: 0.3rem; }
.de-mm-text-input {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  font-size: 0.85rem;
  font-family: ui-monospace, 'SF Mono', Consolas, monospace;
  box-sizing: border-box;
}
.de-mm-text-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
.de-mm-confirm {
  background: #f1f5f9;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.7rem 0.85rem;
  font-size: 0.82rem;
  color: #374151;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.de-mm-confirm strong { color: #1f2937; }
.de-mm-confirm .de-mm-field-list {
  margin: 0.25rem 0 0;
  padding-left: 1.1rem;
  font-size: 0.78rem;
  color: var(--text-muted);
  max-height: 110px;
  overflow-y: auto;
}
.de-mm-progress {
  background: #f8fafc;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.7rem 0.85rem;
}
.de-mm-progress-label {
  font-size: 0.82rem;
  color: #374151;
  margin-bottom: 0.4rem;
}
.de-mm-progress-bar {
  height: 8px;
  background: #e2e8f0;
  border-radius: 4px;
  overflow: hidden;
}
.de-mm-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #7c3aed);
  width: 0%;
  transition: width 0.15s linear;
}
.de-mm-result {
  background: #ecfdf5;
  border: 1px solid #6ee7b7;
  border-radius: 6px;
  padding: 0.75rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.de-mm-result-msg {
  font-size: 0.85rem;
  color: #065f46;
}
.de-mm-result-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.de-mm-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.8rem 1.2rem;
  border-top: 1px solid var(--border);
  background: #fafafa;
  margin-top: 0.75rem;
}
.de-mm-footer[hidden] { display: none; }
.de-mm-primary,
.de-mm-secondary {
  background: white;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.45rem 1rem;
  font-size: 0.83rem;
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
  color: #1f2937;
}
.de-mm-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
.de-mm-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
.de-mm-primary:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.de-mm-secondary:hover { background: #f1f5f9; border-color: var(--border-strong); }

/* =====================================================================
   PRINT
   ---------------------------------------------------------------------
   When the user prints, we want real page breaks at every PageBreak node
   and the standard Word-style 1in margins. The overlay layers are
   non-essential (printed-out paginators just need the body content), so
   we hide them.
   ===================================================================== */
@media print {
  .toolbar,
  .page-header,
  .de-status-bar,
  .de-page-overlay,
  #messages,
  #table-context-menu,
  .de-bubble-menu,
  .de-fields-panel,
  .de-comments-panel,
  .de-footnotes-panel,
  .de-field-suggestion,
  .de-field-inline-edit,
  .de-mm-modal {
    display: none !important;
  }
  /* Fields panel-open offsets must reset for print too. */
  body.de-fields-panel-open .de-status-bar,
  body.de-comments-panel-open .de-status-bar,
  body.de-footnotes-panel-open .de-status-bar {
    right: 0;
  }
  body {
    background: white;
  }
  #editor-wrap {
    padding: 0;
  }
  .de-page-stage {
    transform: none !important;
    width: auto;
  }
  #editor {
    box-shadow: none;
    border-radius: 0;
    width: auto;
    padding: 0.5in 1in;
  }
  .page-header-zone,
  .page-footer-zone {
    position: static;
    box-shadow: none;
    border-radius: 0;
    width: auto;
  }
  #editor .page-break {
    page-break-before: always;
    break-before: page;
    height: 0;
    padding: 0;
    margin: 0;
    border: none;
  }
  #editor .page-break .page-break-label { display: none; }
}

/* ============================================================ FIND & REPLACE */
.de-frbar {
  position: fixed;
  top: calc(var(--toolbar-h, 150px));
  right: 24px;
  z-index: 60;
  background: white;
  border: 1px solid var(--border, #d4d4d4);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.16);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 320px;
}
.de-frbar[hidden] { display: none; }
.de-frbar-row { display: flex; align-items: center; gap: 4px; }
.de-frbar-input {
  flex: 1 1 auto; min-width: 0;
  padding: 5px 8px; font: inherit; font-size: 0.85rem;
  border: 1px solid var(--border, #d4d4d4); border-radius: 5px;
}
.de-frbar-input:focus { outline: 2px solid var(--accent, #6750A4); outline-offset: -1px; }
.de-frbar-count { font-size: 0.72rem; color: #6b7280; min-width: 38px; text-align: center; white-space: nowrap; }
.de-frbar-btn {
  flex: 0 0 auto; padding: 4px 7px; font: inherit; font-size: 0.8rem;
  background: #f3f4f6; border: 1px solid var(--border, #d4d4d4); border-radius: 5px;
  cursor: pointer; color: var(--text); line-height: 1;
}
.de-frbar-btn:hover { background: var(--accent-light, #ede7f6); border-color: var(--accent-border, #b39ddb); color: var(--accent, #6750A4); }
.de-frbar-text { padding: 4px 10px; }
.de-frbar-close { margin-left: 2px; }
.de-frbar-toggle {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 0.78rem; color: #6b7280; cursor: pointer; user-select: none;
  padding: 0 4px; border: 1px solid transparent; border-radius: 5px;
}
.de-frbar-toggle input { margin: 0; }
/* Decoration class for highlighted matches in the editor. */
.de-find-match { background: #fde68a; border-radius: 2px; }
.de-find-match-current { background: #fb923c; }

@media print { .de-frbar { display: none !important; } }
