:root {
  /* Light theme (default) */
  --bg: #f6f7fb;
  --bg-soft: #ffffff;
  --panel: #ffffff;
  --panel-light: #ffffff;
  --text: #1a1d2e;
  --text-dim: #666d85;
  --accent: #7c5cff;
  --accent2: #0ea5b8;
  --accent-grad: linear-gradient(135deg, #7c5cff 0%, #22b8cf 100%);
  --success: #17a878;
  --danger: #e0405f;
  --radius: 14px;
  --shadow: 0 8px 28px rgba(30, 34, 60, 0.08);
  --body-bg-grad: radial-gradient(ellipse at top left, #ece9ff 0%, var(--bg) 60%);
  /* Subtle brand-tinted glass instead of plain white -- same ~85% opacity/
     blur as before (so contrast & readability are unchanged), just the base
     color is nudged from neutral white toward a faint --accent (#7c5cff)
     wash, so the header reads as "on-brand" without competing with the
     accent-gradient buttons/active-states used everywhere else on the page. */
  --topbar-bg: rgba(230, 225, 255, 0.85);
  --border-soft: rgba(20, 20, 40, 0.08);
  --border-strong: rgba(20, 20, 40, 0.18);
  --brand-ace: #4b2fc2;
}

[data-theme="dark"] {
  --bg: #0f1220;
  --bg-soft: #161a2e;
  --panel: #1c2138;
  --panel-light: #ffffff;
  --text: #e8eaf6;
  --text-dim: #a4a9c7;
  --accent: #7c5cff;
  --accent2: #22d3ee;
  --accent-grad: linear-gradient(135deg, #7c5cff 0%, #22d3ee 100%);
  --success: #2dd4a7;
  --danger: #ff5c7a;
  --shadow: 0 12px 32px rgba(10, 12, 30, 0.35);
  --body-bg-grad: radial-gradient(ellipse at top left, #1a1f3a 0%, var(--bg) 60%);
  /* Same subtle brand-tinted-glass idea for dark mode -- same ~85% opacity
     as before, base color nudged from neutral dark-navy toward a faint
     --accent (#7c5cff) wash instead of a flat dark-gray/black bar. */
  --topbar-bg: rgba(30, 22, 58, 0.85);
  --border-soft: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.2);
  --brand-ace: #b9a6ff;
}

body, .topbar, .theme-toggle-btn { transition: background 0.2s, color 0.2s, border-color 0.2s; }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, "Inter", sans-serif;
  background: var(--body-bg-grad);
  color: var(--text);
  min-height: 100vh;
}
a { color: inherit; text-decoration: none; }

.topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 14px 40px;
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--topbar-bg);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-soft);
  flex-wrap: nowrap;
}
.brand { flex: 0 0 auto; }
.theme-toggle-btn { flex: 0 0 auto; }
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
}
.brand .logo-mark {
  width: 34px; height: 34px;
  border-radius: 10px;
  background: var(--accent-grad);
  display: flex; align-items: center; justify-content: center;
  font-weight: 900;
  color: #ffffff;
  box-shadow: 0 4px 14px rgba(124,92,255,0.5);
}
.brand .accent { background: var(--accent-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.brand .brand-ace { color: var(--brand-ace); font-weight: 800; }

.nav-links { display: flex; gap: 18px; font-size: 1rem; font-weight: 700; color: var(--text); flex: 0 1 auto; overflow: visible; white-space: nowrap; align-items: center; }
.nav-links a { padding: 6px 12px; border-radius: 999px; transition: background 0.15s, color 0.15s; }
.nav-links a:hover { color: var(--accent); }
.nav-links a.active, .nav-item-dropdown.active > a {
  color: var(--accent); background: rgba(124,92,255,0.14); font-weight: 800;
}

.nav-item-dropdown { position: relative; }
.nav-item-icon { margin-right: 5px; font-size: 0.95em; }

/* ---------------- RESULT PREVIEW MODAL (universal post-processing popup) ---------------- */
.preview-modal-overlay {
  position: fixed; inset: 0; background: rgba(15,17,26,0.55); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; z-index: 500; padding: 20px;
}
.preview-modal-box {
  background: var(--panel); border-radius: var(--radius); box-shadow: 0 24px 60px rgba(0,0,0,0.35);
  width: min(920px, 96vw); height: min(88vh, 900px); display: flex; flex-direction: column; overflow: hidden;
}
.preview-modal-header {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 18px;
  border-bottom: 1px solid var(--border-soft); flex: 0 0 auto;
}
.preview-modal-title { font-weight: 700; color: var(--text); font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 80%; }
.preview-modal-close {
  background: none; border: none; font-size: 1.4rem; line-height: 1; cursor: pointer; color: var(--text-dim);
  padding: 2px 8px; border-radius: 6px;
}
.preview-modal-close:hover { background: rgba(124,92,255,0.12); color: var(--text); }
.preview-modal-body {
  flex: 1 1 auto; overflow: auto; padding: 16px; display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start;
  min-height: 220px; background: var(--bg);
}
.preview-modal-frame { width: 100%; flex: 1 1 auto; min-height: 320px; border: 1px solid var(--border-soft); border-radius: 8px; background: #fff; }
.preview-modal-hint { flex: 0 0 auto; font-size: 0.82rem; color: var(--text-dim); text-align: center; margin-top: 10px; }
.preview-modal-frame-text { background: #fff; }
.preview-modal-img { flex: 1 1 auto; max-width: 100%; max-height: 100%; object-fit: contain; margin: 0 auto; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.15); }
.preview-modal-nopreview {
  text-align: center; color: var(--text-dim); font-size: 0.95rem; line-height: 1.6; padding: 30px;
}
.preview-modal-nopreview br { content: ""; display: block; margin-bottom: 8px; }
.preview-modal-footer {
  display: flex; gap: 10px; justify-content: flex-end; padding: 14px 18px;
  border-top: 1px solid var(--border-soft); flex: 0 0 auto;
}
.nav-item-dropdown > a::after {
  content: " ▾"; font-size: 0.95em; font-weight: 900; opacity: 0.85; color: var(--text);
  margin-left: 2px;
}
body.is-home-page .nav-item-dropdown > a::after { content: ""; margin-left: 0; }
.nav-item-dropdown > a:hover::after, .nav-item-dropdown.open > a::after { opacity: 1; color: var(--accent); }
.nav-item-dropdown.open > a { color: var(--text); }

.nav-dropdown-panel {
  position: absolute; top: calc(100% + 14px); left: 50%; transform: translateX(-50%);
  background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
  box-shadow: 0 16px 40px rgba(0,0,0,0.25);
  padding: 20px 24px; min-width: 420px; max-width: min(700px, 92vw);
  max-height: 78vh; overflow-y: auto; overflow-x: hidden;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.15s, visibility 0.15s;
  z-index: 60;
}
.nav-item-dropdown.open .nav-dropdown-panel { opacity: 1; visibility: visible; pointer-events: auto; }
.nav-dropdown-panel::before {
  content: ""; position: absolute; top: -7px; left: var(--arrow-left, 50%);
  transform: translateX(var(--arrow-tx, -50%)) rotate(45deg);
  width: 14px; height: 14px; background: var(--panel); border-left: 1px solid var(--border-soft); border-top: 1px solid var(--border-soft);
}
/* Hybrid horizontal+vertical layout: categories flow left-to-right and wrap
   onto a new row once they run out of room, instead of forcing one wide
   nowrap row (which was overflowing the viewport) or one tall column. */
.dd-grid { display: flex; gap: 22px; flex-wrap: wrap; }
.dd-col { display: flex; flex-direction: column; gap: 2px; flex: 0 1 190px; min-width: 170px; }
/* Lay each category's tools out in 2 columns instead of one tall stack --
   uses the mega-menu's horizontal space instead of forcing vertical scrolling
   (mirrors iLovePDF's 2-column-per-category layout). */
.dd-items { display: grid; grid-template-columns: repeat(2, minmax(110px, 1fr)); gap: 0 8px; align-content: start; }
.dd-more { grid-column: 1 / -1; }
.dd-col-header {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 6px; white-space: normal;
}
.dd-col-header:hover { color: var(--accent); }
.dd-tool {
  display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-radius: 6px;
  font-size: 0.85rem; color: var(--text); white-space: normal;
}
.dd-tool:hover { background: rgba(124,92,255,0.1); color: var(--accent); }
.dd-tool-icon { font-size: 1rem; }
.dd-more { font-size: 0.78rem; color: var(--accent2); padding: 4px; white-space: normal; }
@media (max-width: 900px) {
  .nav-dropdown-panel {
    position: fixed !important; left: 12px !important; right: 12px !important; top: 60px !important;
    transform: none !important; width: auto; max-width: none; min-width: 0;
  }
  .nav-dropdown-panel::before { display: none; }
}

.topbar-auth { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.btn-ghost-small, .btn-primary-small {
  padding: 9px 16px; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  cursor: pointer; white-space: nowrap; min-height: 38px; line-height: 1;
}
.btn-ghost-small {
  background: transparent; color: var(--text); border: 1px solid var(--border-strong);
}
.btn-ghost-small:hover { background: rgba(124,92,255,0.08); }
.btn-primary-small {
  background: var(--accent-grad); color: #fff; border: none;
}
.btn-primary-small:hover { opacity: 0.92; }
@media (max-width: 480px) {
  .btn-ghost-small, .btn-primary-small { padding: 8px 12px; font-size: 0.8rem; }
}

.topbar-search { margin-left: auto; flex: 1 1 200px; max-width: 280px; min-width: 130px; }
.topbar-search input {
  width: 100%; padding: 8px 16px; border-radius: 999px; border: 1px solid var(--border-soft);
  background: var(--panel); color: var(--text); font-size: 0.85rem; outline: none;
}
.topbar-search input:focus { border-color: var(--accent); }
@media (max-width: 900px) {
  /* overflow must stay visible here: the dot-menu panel and the nav mega
     panels are absolutely positioned *below* the header box, so a clipping
     ancestor rendered them into nothing and made the ⠿ button look dead on
     every mobile page. Nothing overflows sideways instead, because the brand
     shrinks, the (0px-wide, unreachable) nav strip is hidden, and a focused
     search box overlays the row rather than widening it. */
  .topbar {
    gap: 8px; padding: 10px 12px; flex-wrap: nowrap; overflow: visible;
  }
  .brand { font-size: 1.02rem; gap: 7px; }
  .brand .logo-mark { width: 28px; height: 28px; font-size: 0.95rem; }
  /* The doc groups move to the dot-menu (see .site-menu-docnav, injected by
     site-menu.js) and to the home page's own doc chips. */
  .nav-links { display: none; }
  #signup-btn { display: none; }
  /* Mobile header order (user-spec): [three-line tools menu] [logo]
     [search bar, grows] ... [site dot-menu at the far right edge]. The
     buttons get their places from `order`, so the same rules hold on
     every page that shares this header (SPA, static, generated). */
  #tools-menu-btn { order: -2; }
  .brand { order: -1; }
  .site-menu-wrap { order: 1; }
  .topbar-search {
    order: 0; flex: 1 1 auto; margin-left: 0; width: auto; max-width: none;
    /* Can shrink to just the magnifier icon on the narrowest phones --
       otherwise the fixed row (menu + logo + dot-menu) overflows at 320px.
       Focusing still expands it to the full-width overlay below. */
    min-width: 40px; overflow: hidden;
  }
  .topbar-search:focus-within {
    position: absolute; left: 10px; right: 10px; top: 50%; transform: translateY(-50%);
    width: auto; max-width: none; z-index: 70;
  }
  .topbar-search input {
    background-color: var(--panel);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>");
    background-repeat: no-repeat; background-position: 10px center;
    padding-left: 32px; text-overflow: ellipsis;
  }
  .topbar-auth { order: 4; }
}

.control-bar {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  flex-wrap: wrap; padding: 18px 20px 8px; max-width: 1200px; margin: 0 auto;
}
.doc-tabs {
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
}
.doc-tabs button {
  padding: 9px 22px; border-radius: 12px; border: 1px solid var(--border-soft);
  background: var(--panel); color: var(--text-dim); cursor: pointer; font-size: 0.95rem; font-weight: 600;
  transition: all 0.15s;
}
.doc-tabs button.active, .doc-tabs button:hover {
  background: var(--accent-grad); color: #0f1220; border-color: transparent;
  box-shadow: 0 4px 16px rgba(139,92,246,0.35);
}

.category-tabs {
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
  padding: 10px 20px 10px; max-width: 1200px; margin: 0 auto;
}
.category-tabs button, .doc-tabs-mobile button {
  padding: 8px 18px; border-radius: 999px; border: 1px solid var(--border-soft);
  background: transparent; color: var(--text-dim); cursor: pointer; font-size: 0.88rem;
  transition: all 0.15s;
}
.category-tabs button.active, .category-tabs button:hover,
.doc-tabs-mobile button.active, .doc-tabs-mobile button:hover {
  background: var(--accent-grad); color: #0f1220; border-color: transparent; font-weight: 600;
}

/* Home-page doc-group chips. Desktop reaches these through the top nav, which
   is hidden on mobile, so they are the phone's primary way into PDF /
   Markdown / Image -- and they take the place of the sub-category chips,
   which are the less useful filter on a small screen. */
.doc-tabs-mobile { display: none; }
@media (max-width: 900px) {
  .category-tabs { display: none; }
  .doc-tabs-mobile {
    display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;
    padding: 8px 12px 4px; max-width: 100%; margin: 0 auto;
  }
  .doc-tabs-mobile button { padding: 8px 14px; font-size: 0.85rem; min-height: 40px; }
}

.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 18px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px 40px 80px;
}
.tool-card {
  background: var(--panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 22px;
  cursor: pointer;
  transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
  display: flex; flex-direction: column; gap: 10px;
}
.tool-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
  border-color: rgba(124,92,255,0.4);
}
.tool-card .icon {
  width: 46px; height: 46px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.4rem; background: rgba(124,92,255,0.14); color: var(--accent2);
}
.tool-card h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.tool-card p { margin: 0; font-size: 0.85rem; color: var(--text-dim); line-height: 1.4; }
.tool-card .badge {
  align-self: flex-start; font-size: 0.65rem; padding: 2px 8px; border-radius: 6px;
  background: rgba(45,212,167,0.15); color: var(--success); font-weight: 700; letter-spacing: 0.03em;
}

.page-wrap { max-width: 900px; margin: 0 auto; padding: 40px 24px 100px; }
.page-wrap-wide { max-width: 1400px; }
/* Editor-type tools (Edit PDF, Sign, Redact, Edit PDF Text): the header is
   hidden by JS once a file is loaded, so this trims the padding/heading gap
   that would otherwise leave a lot of unused space above the toolbar, and
   widens the usable canvas area instead of capping it like a content page. */
.page-wrap-editor { padding: 16px 12px 40px; }
.md-sticky-toolbar {
  position: sticky; top: 0; z-index: 20; background: var(--bg);
  padding: 12px 0 10px; margin: 0 0 10px; border-bottom: 1px solid var(--border-soft);
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.action-bar-top { margin-top: 0; justify-content: flex-end; }
.tool-header { text-align: center; margin-bottom: 30px; }
.tool-header h2 { font-size: 1.9rem; margin: 0 0 8px; }
.tool-header p { color: var(--text-dim); }

.dropzone {
  border: 2px dashed rgba(124,92,255,0.35);
  border-radius: var(--radius);
  background: var(--panel);
  padding: 50px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.dropzone.dragover { border-color: var(--accent2); background: rgba(124,92,255,0.08); }
.dropzone .dz-icon { font-size: 2.6rem; margin-bottom: 10px; }
.dropzone .dz-main { font-weight: 700; font-size: 1.05rem; margin-bottom: 4px; }
.dropzone .dz-sub { color: var(--text-dim); font-size: 0.85rem; }
.dropzone button.browse-btn {
  margin-top: 16px; padding: 10px 26px; border-radius: 999px; border: none;
  background: var(--accent-grad); color: #0f1220; font-weight: 700; cursor: pointer;
}

.file-list { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.file-item {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--panel); border-radius: 10px; padding: 10px 16px; font-size: 0.9rem;
}
.file-item .fname { display: flex; align-items: center; gap: 10px; }
.file-item button { background: none; border: none; color: var(--danger); cursor: pointer; font-size: 1rem; }

.options-panel {
  margin-top: 24px; background: var(--panel); border-radius: var(--radius); padding: 22px;
  display: flex; flex-direction: column; gap: 16px;
}
.field-row { display: flex; flex-direction: column; gap: 6px; }
.multiselect-lang { padding: 6px; min-height: 120px; }
.multiselect-lang option { padding: 4px 6px; border-radius: 4px; }
.multiselect-lang option:checked { background: var(--accent-grad); color: #0f1220; }
.field-row label { font-size: 0.85rem; color: var(--text-dim); font-weight: 600; }
.field-row input[type=text], .field-row input[type=number], .field-row input[type=password],
.field-row select, .field-row textarea {
  padding: 10px 14px; border-radius: 8px; border: 1px solid var(--border-soft);
  background: var(--bg-soft); color: var(--text); font-size: 0.9rem;
}
.field-row textarea { font-family: monospace; min-height: 140px; }
.radio-group { display: flex; gap: 14px; flex-wrap: wrap; }
.radio-group label { display: flex; align-items: center; gap: 6px; font-size: 0.88rem; color: var(--text-dim); font-weight: 500; }

.action-bar { display: flex; justify-content: center; margin-top: 30px; }
.btn-primary {
  padding: 14px 40px; border-radius: 999px; border: none; font-size: 1.05rem; font-weight: 700;
  background: var(--accent-grad); color: #0f1220; cursor: pointer;
  box-shadow: 0 8px 24px rgba(124,92,255,0.35);
  transition: transform 0.15s;
}
.btn-primary:hover { transform: translateY(-2px); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn-save { background: var(--success) !important; color: #fff !important; }
.btn-secondary {
  padding: 10px 22px; border-radius: 999px; border: 1px solid var(--border-strong);
  background: transparent; color: var(--text); cursor: pointer; font-weight: 600;
}

.status-box { text-align: center; margin-top: 24px; color: var(--text-dim); }
.status-extra { margin-top: 10px; font-size: 0.85em; color: var(--accent); animation: fadeIn 0.3s ease-in; }

/* Long-wait panel (app.js startLongWaitNotice): rotating caption, an
   indeterminate bar, and an elapsed clock. Indeterminate on purpose -- the
   synchronous path has no real percentage to report. */
.long-wait { max-width: 340px; margin-left: auto; margin-right: auto; }
.long-wait-caption { min-height: 2.4em; line-height: 1.4; }
.long-wait-bar {
  position: relative; height: 6px; border-radius: 3px; margin: 10px 0 6px;
  background: var(--border-soft, #e2e2e2); overflow: hidden;
}
.long-wait-bar span {
  position: absolute; top: 0; left: 0; height: 100%; width: 40%; border-radius: 3px;
  background: var(--accent, #7c5cff); animation: longWaitSlide 1.6s ease-in-out infinite;
}
@keyframes longWaitSlide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
.long-wait-time { font-size: 0.92em; color: var(--text-dim); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
  .long-wait-bar span { animation: none; width: 100%; opacity: 0.5; }
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.spinner {
  width: 40px; height: 40px; border-radius: 50%; margin: 0 auto 12px;
  border: 4px solid rgba(124,92,255,0.2); border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.result-box {
  text-align: center; background: var(--panel); border-radius: var(--radius);
  padding: 40px; margin-top: 24px;
}
.result-box .check {
  width: 60px; height: 60px; border-radius: 50%; margin: 0 auto 16px;
  background: rgba(45,212,167,0.15); color: var(--success);
  display: flex; align-items: center; justify-content: center; font-size: 1.8rem;
}
.result-box h3 { margin: 0 0 8px; }
.result-box p { color: var(--text-dim); margin: 0 0 20px; }
.error-box {
  text-align: center; background: rgba(255,92,122,0.1); border: 1px solid rgba(255,92,122,0.3);
  border-radius: var(--radius); padding: 24px; margin-top: 24px; color: #ffb3c1;
}

.top-error-toast {
  position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 9500; /* below the 9999 ad/reward modals, above everything else */
  max-width: min(680px, calc(100vw - 24px));
  background: #fff0f2; border: 1px solid rgba(200,30,60,0.4);
  color: #7a0e24; border-radius: var(--radius);
  padding: 14px 40px 14px 16px; box-shadow: 0 8px 28px rgba(0,0,0,0.2);
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  animation: top-error-toast-in 0.18s ease-out;
}
[data-theme="dark"] .top-error-toast {
  background: #3a1620; border-color: rgba(255,92,122,0.55); color: #ffe1e7;
}
.top-error-toast-body { flex: 1 1 auto; font-size: 0.92rem; line-height: 1.5; }
.top-error-toast-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.top-error-toast-close {
  position: absolute; top: 6px; right: 10px; background: none; border: none;
  color: inherit; font-size: 1.3rem; line-height: 1; cursor: pointer; opacity: 0.8;
}
.top-error-toast-close:hover { opacity: 1; }
@keyframes top-error-toast-in {
  from { opacity: 0; transform: translate(-50%, -12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

footer { text-align: center; padding: 30px; color: var(--text-dim); font-size: 0.8rem; border-top: 1px solid var(--border-soft); }
/* 0.8rem bare links computed to a ~19px tap target; WCAG 2.5.8 wants >=24px. */
footer a { display: inline-block; padding: 6px 4px; min-height: 24px; }

/* Editor page (edit/sign/redact) */
.editor-layout { display: flex; gap: 16px; max-width: 1600px; margin: 8px auto 0; padding: 0 12px; }
.editor-toolbar {
  width: 220px; background: var(--panel); border-radius: var(--radius); padding: 0;
  position: sticky; top: 78px; max-height: calc(100vh - 90px); overflow-y: auto; overflow-x: hidden;
}
/* Frozen action row -- Undo / Delete / Save are the three actions used most
   often and needed at any scroll position, so they are the sticky first
   child inside the single scrolling container above (standard
   sticky-header-in-scroll-area pattern -- avoids the fit-content/flex-grow
   sizing ambiguity that broke this layout previously). */
/* A 220px sidebar cannot fit 3 legible text-labeled buttons ("Undo",
   "Delete", "Save") side by side at any reasonable font size -- an earlier
   flex:1 + text-overflow:ellipsis attempt only hid the overflow by chopping
   labels down to unreadable "U..." / "D..." / "S...", which is worse than
   the scrollbar it replaced. Fixed properly with a 2-row grid instead:
   Undo + Delete share row 1 (each gets ~half the sidebar, plenty for their
   short labels), and Save/Apply -- the primary, most-used action -- gets
   its own full-width row 2, both for legibility and because it deserves
   the visual emphasis of a full-width primary button anyway. */
.editor-actionbar {
  display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto auto;
  gap: 6px; padding: 10px 8px 8px; margin: 0;
  position: sticky; top: 0; z-index: 5; background: var(--panel);
  border-bottom: 1px solid var(--border-soft);
  overflow: hidden; /* extra safety net -- never let this row create a scrollbar */
}
.editor-actionbar button {
  min-width: 0; padding: 7px 4px; font-size: 0.8rem; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Save/Apply is always the 3rd button in DOM order (#finish-btn /
   #save-text-edits-btn) -- span both grid columns so it takes the full
   width of row 2. */
.editor-actionbar button:nth-child(3) { grid-column: 1 / -1; font-size: 0.85rem; padding: 8px 4px; }
.editor-actionbar button:disabled { opacity: 0.4; cursor: not-allowed; }
.editor-toolbar-scroll {
  display: flex; flex-direction: column; gap: 6px; padding: 8px 12px 12px;
}
.editor-toolbar-scroll strong { flex: 0 0 auto; }
.editor-toolbar-scroll hr { margin: 2px 0; }
/* Must reset padding/max-width/margin here too -- the generic .tool-grid rule above (for the main tools-listing page) sets a large padding: 20px 40px 80px that this narrower selector doesn't otherwise override, since it only wins on grid-template-columns/gap via specificity. Without this reset, that leaked 80px bottom padding shows up as a large blank gap under the last row of drawing-tool buttons in the editor sidebar. */
.editor-toolbar .tool-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 0; max-width: none; margin: 0; }
.editor-toolbar .tool-grid button { padding: 8px 6px; font-size: 0.8rem; text-align: center; }
.editor-toolbar button {
  padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border-soft);
  background: var(--bg-soft); color: var(--text); cursor: pointer; text-align: left; font-size: 0.85rem;
}
.eyedropper-btn {
  padding: 4px 8px; border-radius: 6px; border: 1px solid var(--border-soft);
  background: var(--bg-soft); cursor: pointer; font-size: 0.85rem; line-height: 1;
}
.eyedropper-btn:hover { background: var(--accent-grad); }
.color-row-inline { display: flex; align-items: center; gap: 6px; }
.editor-toolbar button.active { background: var(--accent-grad); color: #0f1220; font-weight: 700; border-color: transparent; }
.editor-canvas-wrap { flex: 1; overflow: auto; max-height: 82vh; background: var(--bg-soft); border-radius: var(--radius); padding: 20px; }
/* Contextual per-item delete affordance -- floats at the top-right corner of
   whichever item is currently selected so users can delete right where
   their attention already is, without looking back at the sidebar. This was
   chosen over a full "layers panel" for now: most documents here only have
   a handful of overlay items at a time (text boxes/shapes/signatures), so a
   dedicated list-tracking pane would add UI weight without a matching
   day-to-day benefit -- the sidebar's frozen Delete button + this floating
   badge already cover both "eyes on canvas" and "eyes on sidebar" workflows.
   Worth revisiting only if usage grows toward dozens of items per document. */
.selection-delete-badge {
  position: absolute; z-index: 20; width: 20px; height: 20px; border-radius: 50%;
  background: var(--danger); color: #fff; border: 2px solid var(--panel);
  font-size: 11px; line-height: 1; cursor: pointer; display: flex; align-items: center;
  justify-content: center; padding: 0; box-shadow: 0 2px 6px rgba(0,0,0,0.25);
}
.selection-delete-badge:hover { filter: brightness(1.15); }
/* max-width: 100% (added) lets the canvas shrink to fit viewports narrower
   than the 700px logical width app.js renders it at, instead of only being
   reachable via the horizontal scrollbar .editor-canvas-wrap already provides
   -- pageScale() in app.js reads the actual rendered box size at interaction
   time, so drawing/dragging stays accurate at any width this clamps it to. */
.pdf-page-canvas { position: relative; margin: 0 auto 20px; max-width: 100%; box-shadow: 0 4px 20px rgba(0,0,0,0.4); }
.pdf-page-canvas img { display: block; width: 100%; }
.overlay-item {
  position: absolute; cursor: move; user-select: none; border: 1px dashed transparent;
}
.overlay-item:hover { border-color: var(--accent2); }
.overlay-item.text-item { color: #000; font-family: Helvetica, Arial, sans-serif; white-space: pre; }
.overlay-item.rect-item { background: rgba(255,92,122,0.55); }

.sig-pad-wrap { background: var(--panel); border-radius: var(--radius); padding: 20px; margin-top: 20px; text-align: center; }
.sig-pad-wrap canvas { background: #fff; border-radius: 8px; touch-action: none; }

.diff-view { background: var(--panel); border-radius: var(--radius); padding: 20px; font-family: monospace; font-size: 0.85rem; max-height: 70vh; overflow: auto; }
.diff-line { padding: 2px 8px; white-space: pre-wrap; }
.diff-line.added { background: rgba(45,212,167,0.15); color: #7de8cb; }
.diff-line.removed { background: rgba(255,92,122,0.15); color: #ffb3c1; }
.diff-line.same { color: var(--text-dim); }

.compare-upload-row { display: flex; gap: 20px; }
.compare-upload-row .dropzone { flex: 1; padding: 30px 14px; }

/* --- Editor: text-box create/edit + selection states --- */
.overlay-item.selected { outline: 2px solid var(--accent2); outline-offset: 1px; }
.overlay-item.text-item {
  min-width: 20px; min-height: 1em; padding: 2px; line-height: 1.15;
  outline: none; border: 1px dashed rgba(120,140,255,0.5); background: transparent;
}
.overlay-item.text-item.has-bg { border-style: solid; }
.overlay-item.text-item:empty::before { content: attr(data-placeholder); color: #888; }
.overlay-item.text-item.editing { cursor: text; border-color: var(--accent2); background: rgba(124,92,255,0.08); }
.editor-toolbar .hint-box { font-size: 0.78rem; color: var(--text-dim); line-height: 1.4; background: var(--border-soft); padding: 8px 10px; border-radius: 8px; }
/* Tool caveats used to be a permanently-visible orange warning box shown to
   EVERY user immediately on page load, before they had even chosen a file --
   loud, alarming, and in the way for the (large) majority of documents that
   never hit the edge case being warned about. Now a quiet, collapsed
   disclosure: the info is one click away for anyone who wants it (e.g.
   after a conversion looks off), but doesn't shout a warning at everyone
   up front. */
.tool-caveat {
  font-size: 0.82rem; line-height: 1.45; color: var(--text-dim);
  margin-top: 10px; border-radius: 8px;
}
.tool-caveat summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px;
  color: var(--text-dim); font-size: 0.8rem; padding: 4px 0;
}
.tool-caveat summary::before { content: "\2139\FE0F"; flex: 0 0 auto; }
.tool-caveat summary::-webkit-details-marker { display: none; }
.tool-caveat[open] summary::before { content: "\26A0\FE0F"; }
.tool-caveat-body {
  display: flex; align-items: flex-start; gap: 8px; margin-top: 6px;
  background: rgba(255, 176, 32, 0.1); border: 1px solid rgba(255, 176, 32, 0.35);
  border-radius: 8px; padding: 10px 12px;
}
.editor-toolbar button.danger { background: rgba(255,92,122,0.15); border-color: rgba(255,92,122,0.4); }

/* --- Direct text-editing tool (Edit PDF Text) --- */
.text-span-edit {
  position: absolute; white-space: pre-wrap; word-break: break-word;
  background: #fff; border: 1px dashed transparent; padding: 0; margin: 0;
  cursor: text; box-decoration-break: clone; outline: none; line-height: 1.05;
}
.text-span-edit:hover { border-color: rgba(120,140,255,0.6); }
.text-span-edit.dirty { background: #fff8e1; border-color: #e0a800; }
.text-span-edit:focus { border-color: var(--accent2); background: #fffef2; }
.text-span-edit.text-span-selected {
  border-color: var(--accent, #7c5cff); border-style: solid;
  box-shadow: 0 0 0 2px rgba(124,92,255,0.25);
}

/* --- Markdown Editor --- */
.md-editor-wrap {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin-top: 10px; min-height: 640px;
}
#md-editor-src {
  width: 100%; min-height: 640px; resize: vertical;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-soft); border-radius: 10px;
  padding: 14px; font-family: "Courier New", monospace; font-size: 0.92rem; line-height: 1.5;
}
.md-preview {
  background: #fff; color: #1a1a1a; border-radius: 10px; padding: 20px 24px;
  overflow-y: auto; min-height: 640px; line-height: 1.5;
}
.md-preview h1, .md-preview h2, .md-preview h3 { margin-top: 0.6em; margin-bottom: 0.3em; }
.md-preview p { margin: 0.5em 0; }
.md-preview code { background: #f0f0f0; padding: 1px 4px; border-radius: 3px; font-family: monospace; }
.md-preview pre code { display: block; padding: 10px; overflow-x: auto; }
.md-preview blockquote { border-left: 3px solid #ccc; margin: 0.5em 0; padding-left: 12px; color: #555; }
.md-preview ul { padding-left: 1.4em; }
@media (max-width: 800px) {
  .md-editor-wrap { grid-template-columns: 1fr; }
}

/* --- Markdown toolbar (upload .md into editor) --- */
.md-toolbar { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.md-upload-btn { cursor: pointer; display: inline-block; }

/* --- Rich markdown preview: tables, images, task lists, code --- */
.md-preview table { border-collapse: collapse; width: 100%; margin: 0.8em 0; }
.md-preview th, .md-preview td { border: 1px solid #d0d0d0; padding: 6px 10px; text-align: left; }
.md-preview thead th { background: #f2f2f5; font-weight: 600; }
.md-preview tbody tr:nth-child(even) { background: #fafafa; }
.md-preview img { max-width: 100%; height: auto; border-radius: 6px; margin: 0.4em 0; display: block; }
.md-preview hr { border: none; border-top: 1px solid #ddd; margin: 1.2em 0; }
.md-preview del { color: #999; }
.md-preview li.task-item { list-style: none; margin-left: -1.4em; }
.md-preview li.task-item input { margin-right: 6px; }
.md-preview a { color: #5b4fd6; text-decoration: none; }
.md-preview a:hover { text-decoration: underline; }
.md-preview ol { padding-left: 1.4em; }

/* Front-matter metadata table + tag chips (YAML --- block at document top) */
/* Trust note under a tool header for flows that stay in the browser. */
.tool-privacy-note {
  font-size: 0.82rem; color: var(--text-dim); margin-top: 8px;
  max-width: 720px; margin-left: auto; margin-right: auto;
}

.md-preview .frontmatter-table { font-size: 0.9em; margin: 0 0 1.1em; }
.md-preview .frontmatter-table th { text-align: right; white-space: nowrap; width: 1%; vertical-align: top; background: #f7f7fa; color: var(--text-dim, #555); font-weight: 600; }
.md-preview .fm-chip { display: inline-block; padding: 1px 9px; margin: 1px 4px 1px 0; border: 1px solid #d7dcff; border-radius: 10px; background: #f3f5ff; color: #4552c9; font-size: 0.85em; white-space: nowrap; }

/* Syntax highlighting tokens (fenced code blocks) */
.md-preview .tok-keyword { color: #d6336c; font-weight: 600; }
.md-preview .tok-string { color: #2b8a3e; }
.md-preview .tok-number { color: #1c7ed6; }
.md-preview .tok-comment { color: #868e96; font-style: italic; }

/* Footnotes */
.md-preview .footnotes { margin-top: 1.4em; font-size: 0.92em; color: var(--text-dim, #666); }
.md-preview .footnotes hr { margin-bottom: 0.6em; }
.md-preview .footnote-ref a { text-decoration: none; }
.md-preview .footnote-backref { margin-left: 4px; text-decoration: none; }

/* Definition lists */
.md-preview dl { margin: 0.6em 0; }
.md-preview dt { font-weight: 600; }
.md-preview dd { margin: 0 0 0.5em 1.6em; color: #444; }

/* Basic math rendering (Unicode-based, not full LaTeX/KaTeX) */
.md-preview .math-inline, .md-preview .math-display {
  font-family: "Cambria Math", Cambria, "Times New Roman", serif; font-style: italic;
}
.md-preview .math-display {
  display: block; text-align: center; margin: 0.8em 0; font-size: 1.15em; font-style: normal;
}
.md-preview .frac { display: inline-flex; flex-direction: column; vertical-align: middle; text-align: center; margin: 0 2px; font-style: normal; }
.md-preview .frac-num { border-bottom: 1px solid currentColor; padding: 0 4px; line-height: 1.3; }
.md-preview .frac-den { padding: 0 4px; line-height: 1.3; }

/* Markdown Syntax Guide panel (Editor + Viewer tools) */
.syntax-guide-panel {
  margin: 14px 0; border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
}
.syntax-guide-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; border-bottom: 1px solid var(--border-soft);
}
.syntax-guide-body {
  margin: 0; padding: 16px; max-height: 420px; overflow-y: auto;
  font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 0.82rem;
  line-height: 1.5; white-space: pre-wrap; color: var(--text);
}

.mermaid-block { margin: 1em 0; text-align: center; overflow-x: auto; }
.mermaid-block svg { max-width: 100%; }
.mermaid-fallback { text-align: left; background: #f6f6f8; padding: 10px; border-radius: 6px; }

/* Standalone Markdown Viewer: wider reading column, printable */
.md-preview-standalone {
  max-width: 860px; margin: 20px auto; padding: 36px 48px;
  box-shadow: 0 2px 20px rgba(0,0,0,0.08);
}
@media print {
  .tool-header, .dropzone, .file-list, .action-bar, .category-tabs, .doc-tabs, .control-bar, .topbar { display: none !important; }
  .md-preview-standalone { box-shadow: none; margin: 0; padding: 0; }
}


/* ---------------- Theme toggle button ---------------- */
.theme-toggle-btn {
  border: 1px solid var(--border-soft);
  background: var(--bg-soft);
  color: var(--text);
  border-radius: 50%;
  width: 40px; height: 40px;
  font-size: 1.1rem;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.theme-toggle-btn:hover { border-color: var(--accent); }

/* ---------------- Dot-menu (top-right site menu) ---------------- */
.site-menu-wrap { position: static; flex: 0 0 auto; }
.site-menu-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 200;
  min-width: 220px; background: var(--panel); border: 1px solid var(--border-soft);
  border-radius: var(--radius); box-shadow: var(--shadow, 0 8px 24px rgba(0,0,0,0.25));
  padding: 8px; display: flex; flex-direction: column; gap: 2px;
}
.site-menu-panel[hidden] { display: none; }
.site-menu-panel a, .site-menu-linklike {
  display: block; width: 100%; text-align: left; padding: 9px 12px; border-radius: 8px;
  color: var(--text); text-decoration: none; font-size: 0.9rem; font-weight: 600;
  border: none; background: none; cursor: pointer; font-family: inherit;
}
.site-menu-panel a:hover, .site-menu-linklike:hover { background: var(--bg-soft); color: var(--accent); }
.site-menu-panel hr { border: none; border-top: 1px solid var(--border-soft); margin: 6px 4px; }
.site-menu-lang {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 9px 12px; font-size: 0.9rem; font-weight: 600; color: var(--text);
}
.site-menu-lang select {
  flex: 1 1 auto; max-width: 130px; padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--border-strong); background: var(--bg-soft); color: var(--text);
  font-size: 0.82rem;
}
.site-menu-docnav { display: none; flex-direction: column; gap: 2px; }
.site-menu-mobile-only { display: none; flex-direction: column; gap: 2px; }
@media (max-width: 900px) {
  .site-menu-panel {
    left: 10px; right: 10px; min-width: 0;
    max-height: calc(100vh - 78px); max-height: calc(100dvh - 78px); overflow-y: auto;
  }
  .site-menu-docnav, .site-menu-mobile-only { display: flex; }
}

/* The static pages (pricing comparison, about's tool table) carry tables
   wider than a phone; they were pushing the whole document sideways, so they
   scroll inside their own box instead. */
@media (max-width: 900px) {
  .legal-wrap table { display: block; width: 100%; overflow-x: auto; }
}

/* ---------------- All-tools sheet (mobile only) ---------------- */
/* Injected by site-menu.js. Hidden on desktop, where the top nav's mega-menus
   already do this job. */
#tools-menu-btn { display: none; }
.tools-sheet-overlay {
  position: fixed; inset: 0; z-index: 400; background: rgba(15,17,26,0.55);
  display: flex; align-items: flex-end; justify-content: center;
}
.tools-sheet-overlay[hidden] { display: none; }
.tools-sheet {
  background: var(--panel); width: 100%; display: flex; flex-direction: column;
  height: 88vh; height: 88dvh; border-radius: 16px 16px 0 0;
  border-top: 1px solid var(--border-soft); box-shadow: 0 -12px 40px rgba(0,0,0,0.35);
}
.tools-sheet-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--border-soft); flex: 0 0 auto;
  font-size: 1rem; color: var(--text);
}
.tools-sheet-body { flex: 1 1 auto; overflow-y: auto; padding: 12px 14px 28px; }
.ts-group-title {
  font-size: 0.95rem; font-weight: 800; color: var(--text); margin: 14px 0 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border-soft);
}
.ts-group-title:first-child { margin-top: 0; }
.ts-empty { color: var(--text-dim); font-size: 0.9rem; padding: 12px 4px; }
/* One category per row, its tools in two columns -- the desktop mega-menu's
   190px columns would leave ~85px per tool name on a phone. */
.tools-sheet .dd-grid { display: block; }
.tools-sheet .dd-col { flex: 1 1 100%; min-width: 0; margin-bottom: 10px; }
.tools-sheet .dd-items { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 10px; }
.tools-sheet .dd-tool { padding: 10px 6px; min-height: 44px; font-size: 0.86rem; }
.tools-sheet .dd-col-header { font-size: 0.78rem; }
.tools-sheet .dd-more { padding: 10px 6px; min-height: 44px; }
body.sheet-open { overflow: hidden; }
@media (max-width: 900px) {
  #tools-menu-btn { display: flex; }
  /* Folded into the ⠿ menu (site-menu.js injects forwarding rows) so four
     controls fit a 320px header without clipping. */
  #theme-toggle, .topbar-auth { display: none; }
}
@media (max-width: 640px) {
  .site-menu-panel { min-width: 0; }
}

/* ---------------- PDF Reader ---------------- */
.reader-toolbar {
  display: flex; align-items: center; justify-content: center; gap: 20px;
  padding: 12px; margin-bottom: 14px;
}
.reader-page {
  display: flex; justify-content: center;
  background: var(--bg-soft); border-radius: var(--radius); padding: 20px;
  box-shadow: var(--shadow);
}
.reader-page img { max-width: 100%; border-radius: 6px; box-shadow: 0 4px 18px rgba(0,0,0,0.15); }

/* --- Image Editor Studio (Basic Image Editor) --- */
.ie-layout {
  display: grid; grid-template-columns: 1fr 320px; gap: 24px; margin-top: 10px; align-items: start;
}
.ie-canvas-wrap { display: flex; flex-direction: column; align-items: center; }
.ie-image-frame {
  position: relative; max-width: 100%; display: inline-block;
  background: repeating-conic-gradient(#2a2a34 0% 25%, #232329 0% 50%) 50% / 20px 20px;
  border-radius: 10px; overflow: hidden; border: 1px solid var(--border-soft);
}
.ie-image-frame img {
  display: block; max-width: 100%; max-height: 560px; transition: filter 0.05s linear; user-select: none;
}
.ie-crop-box {
  position: absolute; border: 2px dashed #fff; background: rgba(124,92,255,0.18);
  pointer-events: none; box-shadow: 0 0 0 9999px rgba(0,0,0,0.35);
}
.ie-hint { color: var(--text-dim); font-size: 0.82rem; margin-top: 10px; text-align: center; }
.ie-controls {
  background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 18px; display: flex; flex-direction: column; gap: 8px;
}
.ie-controls h4 { margin: 10px 0 2px; font-size: 0.85rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }
.ie-controls h4:first-child { margin-top: 0; }
.ie-btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.ie-btn-row button { flex: 1 1 auto; font-size: 0.82rem; padding: 8px 10px; }
#ie-crop-toggle.active { background: var(--accent-grad); color: #0f1220; border-color: transparent; }
.ie-preview-img { max-width: 100%; max-height: 480px; border-radius: 10px; margin: 12px 0; }
@media (max-width: 900px) {
  .ie-layout { grid-template-columns: 1fr; }
}


/* ---------------- ACCOUNT MANAGER (login/signup/pro-upgrade modal) ---------------- */
.account-modal-box { width: min(420px, 92vw); height: auto; max-height: 90vh; }
.account-modal-body { padding: 20px; overflow-y: auto; }
.account-panel { display: flex; flex-direction: column; gap: 14px; }
.account-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border-soft); }
.account-tab {
  flex: 1; padding: 10px; border: none; background: none; cursor: pointer;
  font-weight: 700; color: var(--text-dim); border-bottom: 2px solid transparent;
}
.account-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.account-form { display: flex; flex-direction: column; gap: 12px; }
.account-form label { display: flex; flex-direction: column; gap: 6px; font-size: 0.85rem; color: var(--text-dim); font-weight: 600; }
.account-form input {
  padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border-strong);
  background: var(--bg-soft); color: var(--text); font-size: 0.95rem;
}
.account-error { color: var(--danger); font-size: 0.85rem; }
.account-hint { font-size: 0.8rem; color: var(--text-dim); margin: 0; }
.account-loggedin { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.account-email { font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-badge { padding: 4px 10px; border-radius: 999px; font-size: 0.75rem; font-weight: 800; }
.account-badge-free { background: var(--border-soft); color: var(--text-dim); }
.account-badge-pro { background: var(--accent-grad); color: #0f1220; }
.account-upgrade-btn { text-align: center; text-decoration: none; display: block; }
.account-upgrade-plans { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
/* Recurring-charge disclosure, deliberately directly under its own button
   rather than in a footnote -- the negative margin pulls it against the
   button it describes so the pairing is unambiguous. */
.account-upgrade-renew {
  margin: -4px 0 4px; font-size: 0.75rem; line-height: 1.35;
  color: var(--text-dim); text-align: center;
}
.account-upgrade-btn-yearly {
  text-align: center; text-decoration: none; display: block;
  white-space: normal; height: auto; min-height: 38px; line-height: 1.3;
  padding: 8px 14px;
}
.account-dev-toggle {
  margin-top: 4px; padding: 6px 10px; border-radius: 8px; border: 1px dashed var(--border-strong);
  background: none; color: var(--text-dim); font-size: 0.75rem; cursor: pointer; align-self: flex-start;
}
.account-dev-toggle:hover { color: var(--text); border-color: var(--accent); }
.account-social-row { display: flex; flex-direction: column; gap: 8px; }
.account-social-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; }
.account-social-icon { font-weight: 800; display: inline-block; width: 16px; text-align: center; }
.account-divider { display: flex; align-items: center; gap: 10px; color: var(--text-dim); font-size: 0.78rem; }
.account-divider::before, .account-divider::after { content: ""; flex: 1; height: 1px; background: var(--border-soft); }
.account-verify-banner {
  display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: 10px;
  background: rgba(255, 190, 60, 0.12); border: 1px solid rgba(255, 190, 60, 0.35); color: var(--text);
  font-size: 0.82rem;
}

/* ---------------------------------------------------------------------- */
/* Real AdSense ad slots (ad-slot.js)                                      */
/* ---------------------------------------------------------------------- */
.ad-slot-container {
  display: flex; align-items: center; justify-content: center;
  min-height: 90px; width: 100%; margin: 16px 0; overflow: hidden;
}
.ad-slot-container.ad-slot-mock {
  border: 1px dashed var(--border-soft); border-radius: 10px;
  color: var(--text-dim); font-size: 0.78rem; text-align: center; padding: 8px;
}

/* ---------------------------------------------------------------------- */
/* Mock Ad Waterfall modals (ad-service.js / ui-modals.js)                 */
/* ---------------------------------------------------------------------- */
.ace-modal-overlay {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(15, 15, 20, 0.6);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.ace-modal-box {
  background: var(--card-bg, #fff);
  border-radius: 12px;
  padding: 28px 24px;
  max-width: 380px;
  width: 100%;
  text-align: center;
  box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}
.ace-modal-box h3 { margin: 12px 0 8px; }
.ace-modal-box p { margin: 0 0 4px; opacity: 0.85; font-size: 0.95em; }
.ad-player-box .spinner { margin: 0 auto 8px; }
.adblock-actions {
  display: flex; gap: 10px; justify-content: center;
  margin-top: 18px; flex-wrap: wrap;
}
.adblock-box { max-width: 440px; }
.adblock-instructions {
  text-align: left;
  margin-top: 14px;
  font-size: 0.88em;
  border: 1px solid var(--border-color, #ccc);
  border-radius: 8px;
  padding: 8px 12px;
}
.adblock-instructions summary { cursor: pointer; font-weight: 600; }
.adblock-instructions ul { margin: 8px 0 4px; padding-left: 18px; }
.adblock-instructions li { margin-bottom: 6px; }
.adblock-recheck-msg {
  color: #c0392b;
  font-size: 0.9em;
  margin-top: 10px;
}
/* The reprocess-at-higher-quality offer lives inside this modal (see
   ui-modals.js): separated from the download actions by a rule so it reads as
   an optional extra, not a second call to action. Selector is scoped to the box
   so it outranks the generic .ace-modal-box p above. */
.download-ready-box .download-ready-hint {
  margin: 18px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--border-color, #ccc);
  color: var(--text-dim);
  font-size: 0.86em;
  opacity: 1;
}
.download-ready-box #download-ready-extra-btn { font-size: 0.9em; }
.download-ready-box .check {
  width: 60px; height: 60px; border-radius: 50%; margin: 0 auto 16px;
  background: rgba(45,212,167,0.15); color: var(--success, #2dd4a7);
  display: flex; align-items: center; justify-content: center; font-size: 1.8rem;
}
.btn-secondary {
  display: inline-block;
  padding: 10px 18px;
  border-radius: 8px;
  border: 1px solid var(--border-color, #ccc);
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 0.95em;
}
.btn-secondary:hover { background: rgba(0,0,0,0.05); }

/* ---------------------------------------------------------------------- */
/* Thank You page (post-download interstitial, thank-you.js)               */
/* ---------------------------------------------------------------------- */
/* Sits below the ad-waterfall/adblock modals (z-index 9999) so a pending
   rewarded-ad modal, if one is somehow still closing, always stays on top. */
.ty-overlay {
  position: fixed; inset: 0; z-index: 9990;
  background: var(--bg);
  overflow-y: auto;
  padding-bottom: 40px;
}
.ty-topbar-ad {
  display: flex; align-items: center; justify-content: center;
  padding: 14px 0; background: var(--panel, var(--bg));
  border-bottom: 1px solid var(--border-soft);
}
/* The 728x90 leaderboard container's own fixed size is applied inline by
   ad-slot.js (data-ad-w/data-ad-h) -- this just keeps it from ever
   exceeding the viewport width on narrower desktop windows. */
.ty-ad-leaderboard { max-width: calc(100vw - 24px); }

.ty-close {
  position: absolute; top: 14px; right: 18px;
  background: none; border: none; font-size: 1.6rem; line-height: 1;
  cursor: pointer; color: var(--text-dim);
  padding: 4px 8px; border-radius: 6px;
}
.ty-close:hover { background: var(--border-soft); }

.ty-layout {
  position: relative;
  display: grid; grid-template-columns: 1fr 300px; gap: 32px;
  max-width: 1100px; margin: 0 auto; padding: 40px 24px 24px;
  align-items: start;
}
/* Rails render at every desktop width (JS drops the leaderboard/rect in
   exchange, so it's always exactly 2 units) -- a uniform 120x600 rail size
   (matches the tool/upload page rails) keeps this simple across widths,
   no separate breakpoint needed for the ad size itself. */
.ty-layout { grid-template-columns: 140px 1fr 140px; }
.ty-main {
  /* Top-left quadrant: the message + fallback link live here, as far as
     possible from every ad slot on the page so a mis-tap while reaching
     for "click here" can never land on an ad instead. */
  min-height: 260px;
}
.ty-check {
  width: 56px; height: 56px; border-radius: 50%;
  background: rgba(46, 204, 113, 0.15); color: #2ecc71;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.8rem; margin-bottom: 14px;
}
.ty-main h1 { margin: 0 0 10px; font-size: 1.6rem; }
.ty-main p { color: var(--text-dim); font-size: 1rem; line-height: 1.6; margin: 0 0 20px; }
.ty-fallback-note { font-size: 1.15rem; font-weight: 600; color: var(--text); }
.ty-fallback-link { font-weight: 800; text-decoration: underline; color: var(--accent); font-size: 1.15rem; }
.ty-continue-btn { display: inline-block; margin-top: 4px; }
.ty-main .ty-extra-hint {
  color: var(--text-dim);
  font-size: 0.86rem;
  margin: 18px 0 8px;
}
.ty-extra-btn { display: inline-block; font-size: 0.9em; }
.ty-pro-note { color: var(--accent); font-weight: 600; margin-top: 14px; font-size: 0.95rem; }

.ty-sidebar {
  display: flex; justify-content: center;
  position: sticky; top: 24px;
}

.ty-rect-wrap {
  /* Lower-center, well below the message/CTA "cursor zone" -- generous top
     margin is the deliberate anti-accidental-click spacer required here. */
  grid-column: 1;
  margin-top: 90px;
  display: flex; justify-content: center;
}

.ty-ad-caption {
  font-size: 0.7rem; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.06em; text-align: center; margin-bottom: 6px;
}

@media (max-width: 768px) {
  .ty-layout { grid-template-columns: 1fr; padding: 32px 16px 32px; }
  .ty-sidebar { display: none; } /* skyscrapers stack and break the framing on narrow screens -- drop it entirely rather than let it collapse below the fold */
  /* A fixed 728px-wide leaderboard has nowhere to go on a <=768px viewport
     -- rather than let it overflow horizontally (the exact "broken
     framing" problem this page is designed to avoid), drop the whole top
     bar on mobile. Mobile's ad presence is the offset center rectangle
     only, per the mobile spec -- there is no bottom sticky anchor ad
     placement anymore (removed completely, see config.js). */
  /* Mobile keeps the top banner, just resized to a 320x50 unit by
     thank-you.js -- only the desktop 728x90 leaderboard is unfit for
     mobile widths, not the top placement itself. */
  .ty-rect-wrap { margin-top: 60px; }
}

/* Belt-and-suspenders: never let ANY fixed-size ad box force horizontal
   scroll, on any screen size, even if a future placement's px size exceeds
   the viewport (e.g. a very narrow in-app browser). max-width always wins
   over an inline width/min-width because the box must never exceed its
   containing block. */
.ad-slot-container { max-width: 100%; box-sizing: content-box; }
/* Tool/upload page ad placements (renderGenericTool) -- distinct from the
   Thank You card slots (thank-you.js), which appear on the next screen. */
.ad-rail {
  position: fixed; top: 50%; transform: translateY(-50%); z-index: 5;
  display: none;
}
.ad-rail-left { left: 12px; }
.ad-rail-right { right: 12px; }
.ad-mobile-banner { display: none; margin: 0 auto 16px; }
@media (min-width: 1200px) {
  .ad-rail { display: block; }
}
/* Wide layouts (.page-wrap-wide 1400px, .page-wrap-editor 1600px) need a much
   wider viewport before the 120px rails fit BESIDE the content instead of on
   top of it -- injectToolPageAds() tags their rails with .ad-rail-wide. */
.ad-rail.ad-rail-wide { display: none; }
@media (min-width: 1900px) {
  .ad-rail.ad-rail-wide { display: block; }
}
/* Exactly one placement at every width: the banner under the tool header
   covers every viewport where the rails are hidden (mobile, tablet, small
   desktop -- previously 769-1199px showed no ad at all). */
@media (max-width: 1199px) {
  .ad-mobile-banner { display: flex; justify-content: center; }
}
@media (min-width: 1200px) and (max-width: 1899px) {
  .page-wrap-wide .ad-mobile-banner,
  .page-wrap-editor .ad-mobile-banner { display: flex; justify-content: center; }
}

/* --- Visible keyboard focus (audit item 33) ------------------------------
   Three rules in this file set `outline: none` on elements that stay keyboard
   reachable -- the topbar search input, the editor's text overlay, and the
   Edit-PDF-Text span -- and two of them replaced the ring with a border-colour
   change. A 1px border tint is not a focus indicator: it is easy to miss, and
   nowhere near WCAG 2.4.11's 3:1 contrast against the panel beside it. There
   was no :focus-visible rule anywhere in the project, so a keyboard user had
   nothing to follow in exactly the three places the default ring was removed.
   :focus-visible rather than :focus on purpose: a mouse click must not draw a
   ring, which is why the UA removed it from click targets in the first place.
   Everything else keeps the browser's own default ring -- this only re-arms
   the places that opted out. */
.topbar-search input:focus-visible,
.overlay-item.text-item:focus-visible,
.text-span-edit:focus-visible {
  outline: 2px solid var(--accent, #7c5cff);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(124, 92, 255, 0.28);
}
/* The editable overlays sit on a white page render, where the outline alone
   can read as part of the document. A solid border keeps the element's own
   edge legible underneath the ring. */
.overlay-item.text-item:focus-visible,
.text-span-edit:focus-visible { border-style: solid; border-color: var(--accent2); }
