/* styles-components-3.css — part 3 of 3 of the former styles-components.css, split in Phase 0.3 with every rule unchanged. Link the parts consecutively, 1 then 2 then 3: the cascade depends on it. */
    /* ============================================
       DYSLEXIC TOGGLE — info button + DOCX-preview font override
       ============================================ */

    /* Small circular info icon next to the Dyslexic toggle title. Opens a
       modal explaining on-screen / PDF / DOCX behaviour. */
    .dyslexic-info-btn {
      background: transparent;
      border: 1px solid rgba(244, 114, 182, 0.4);
      color: #f472b6;
      border-radius: 999px;
      width: 22px;
      height: 22px;
      padding: 0;
      margin-left: 0.35rem;
      font-size: 0.95rem;
      line-height: 1;
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      vertical-align: middle;
    }
    .dyslexic-info-btn:hover {
      background: rgba(244, 114, 182, 0.12);
      border-color: rgba(244, 114, 182, 0.7);
    }
    .dyslexic-info-btn:active {
      background: rgba(244, 114, 182, 0.2);
    }

    /* When the Dyslexic toggle is on, force OpenDyslexic over every inline
       font-family that docx-preview puts on rendered elements. Without this,
       toggling Dyslexic on a freshly imported DOCX does nothing visible until
       a template is applied. The class is set/cleared by updatePreview in
       core-formatting.js. */
    #outputContent.dyslexic-mode-on,
    #outputContent.dyslexic-mode-on *,
    #outputContent.dyslexic-mode-on .docx-preview-wrapper-wrapper *,
    #outputContent.dyslexic-mode-on section.docx-preview-wrapper * {
      font-family: 'OpenDyslexic', 'Comic Sans MS', sans-serif !important;
    }

    /* Selecting a style template for a DOCX import only overlays a font —
       colours/structure/images stay exactly as Word rendered them, since
       docx-preview's markup doesn't map onto the ff-h1/ff-h2/ff-body classes
       applyCustomStyles() uses for other imports. Same override mechanism as
       dyslexic-mode-on above (must beat docx-preview's own inline
       font-family), toggled by updatePreview()/updateCompareView(). Not
       scoped to #outputContent so it also applies in the compare view. */
    .docx-template-font,
    .docx-template-font *,
    .docx-template-font .docx-preview-wrapper-wrapper *,
    .docx-template-font section.docx-preview-wrapper * {
      font-family: var(--ts-docx-font, inherit) !important;
    }

    /* ============================================
       FOCUS TOOLS — reading ruler + colour overlays
       ============================================ */
    .focus-tools-bar { display: none; }
    .focus-tools-bar.visible {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 0.9rem;
      padding: 0.3rem 0;
      max-width: 600px;
    }
    .focus-tool { display: flex; align-items: center; gap: 0.4rem; }
    .focus-tool-title {
      font-size: 0.62rem; font-weight: 600;
      text-transform: uppercase; letter-spacing: 0.05em;
      color: #a3a3a3; white-space: nowrap;
    }

    .overlay-swatches { display: flex; gap: 0.3rem; }
    .overlay-swatch {
      width: 21px; height: 21px; border-radius: 50%;
      border: 2px solid rgba(255, 255, 255, 0.25);
      cursor: pointer; padding: 0;
      display: flex; align-items: center; justify-content: center;
      font-size: 0.7rem; line-height: 1; color: #9aa0ac;
      background: #3a3a42;
      transition: transform 0.1s ease, box-shadow 0.1s ease;
    }
    .overlay-swatch:hover { transform: scale(1.12); }
    .overlay-swatch.active {
      border-color: #818cf8;
      box-shadow: 0 0 0 2px rgba(129, 140, 248, 0.45);
    }
    .overlay-swatch[data-tint="none"]  { background: transparent; }
    .overlay-swatch[data-tint="cream"] { background: #faf3e0; }
    .overlay-swatch[data-tint="blue"]  { background: #dbeafc; }
    .overlay-swatch[data-tint="rose"]  { background: #fbe3ec; }
    .overlay-swatch[data-tint="green"] { background: #e4f3e1; }
    .overlay-swatch[data-tint="peach"] { background: #fde7d6; }
    .overlay-swatch[data-tint="grey"]  { background: #e9e9ec; }

    /* Colour overlays: tint the reading surface behind the text. !important so
       they win over the default white / dark-output backgrounds. */
    .preview-container.overlay-cream, .compare-pane.overlay-cream { background-color: #faf3e0 !important; }
    .preview-container.overlay-blue,  .compare-pane.overlay-blue  { background-color: #dbeafc !important; }
    .preview-container.overlay-rose,  .compare-pane.overlay-rose  { background-color: #fbe3ec !important; }
    .preview-container.overlay-green, .compare-pane.overlay-green { background-color: #e4f3e1 !important; }
    .preview-container.overlay-peach, .compare-pane.overlay-peach { background-color: #fde7d6 !important; }
    .preview-container.overlay-grey,  .compare-pane.overlay-grey  { background-color: #e9e9ec !important; }
    /* Keep text dark on a tint even if Dark Output classes linger. */
    .preview-container[class*="overlay-"] #outputContent { color: #1a1a1a; }

    /* Reading ruler: a fixed strip over the reading viewport. The band is clear;
       the box-shadow spread (clipped by overflow:hidden) dims everything else. */
    .focus-overlay {
      position: fixed;
      z-index: 45;
      pointer-events: none;
      overflow: hidden;
    }
    .focus-overlay[hidden] { display: none; }
    .focus-ruler-band {
      position: absolute;
      left: 0; right: 0; top: 0;
      box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
      border-top: 2px solid rgba(129, 140, 248, 0.6);
      border-bottom: 2px solid rgba(129, 140, 248, 0.6);
      background: rgba(129, 140, 248, 0.05);
    }

    /* ============================================
       MY LIBRARY — launcher, modal, document cards
       ============================================ */
    .library-launcher {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      align-self: flex-start;
      gap: 0.45rem;
      width: auto;
      padding: 0.5rem 0.9rem;
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.18), rgba(126, 34, 206, 0.18));
      border: 1px solid rgba(168, 85, 247, 0.35);
      border-radius: 6px;
      color: #e9d5ff;
      font-size: 0.82rem;
      font-weight: 600;
      font-family: inherit;
      cursor: pointer;
      transition: all 0.15s ease;
    }
    .library-launcher:hover { background: linear-gradient(135deg, rgba(168, 85, 247, 0.3), rgba(126, 34, 206, 0.3)); transform: translateY(-1px); }
    .library-count { font-weight: 500; opacity: 0.8; font-size: 0.76rem; }

    /* Modal shell */
    .library-modal { position: fixed; inset: 0; z-index: 10000; }
    .library-modal[hidden] { display: none; }
    .library-modal-backdrop {
      position: absolute; inset: 0;
      background: rgba(0, 0, 0, 0.62);
      backdrop-filter: blur(3px);
      -webkit-backdrop-filter: blur(3px);
    }
    .library-modal-panel {
      position: relative;
      max-width: 760px;
      margin: 4vh auto 0;
      max-height: 92vh;
      display: flex;
      flex-direction: column;
      background: #14161c;
      border: 1px solid rgba(168, 85, 247, 0.28);
      border-radius: 12px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
      padding: 1.1rem 1.25rem 1rem;
      overflow: hidden;
    }
    .library-modal-head {
      display: flex; align-items: center; justify-content: space-between;
    }
    .library-modal-head h2 { margin: 0; font-size: 1.15rem; color: #f3e8ff; }
    .library-modal-close {
      background: rgba(255, 255, 255, 0.08);
      border: none; color: #ddd;
      width: 30px; height: 30px; border-radius: 6px;
      cursor: pointer; font-size: 0.9rem; line-height: 1;
    }
    .library-modal-close:hover { background: rgba(255, 255, 255, 0.16); }
    .library-modal-sub { margin: 0.35rem 0 0.9rem; color: #9aa0ac; font-size: 0.82rem; }
    .library-empty { color: #9aa0ac; font-size: 0.9rem; padding: 2rem 0.5rem; text-align: center; }

    .library-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
      gap: 0.7rem;
      overflow-y: auto;
      padding: 0.15rem 0.15rem 0.3rem;
    }

    .lib-card {
      display: flex; gap: 0.65rem;
      padding: 0.7rem 0.75rem;
      background: rgba(255, 255, 255, 0.04);
      border: 1px solid rgba(255, 255, 255, 0.1);
      border-radius: 9px;
      transition: border-color 0.15s ease, background 0.15s ease;
      /* Without this, a grid item's automatic min-width defaults to its
         content's unwrapped size — a long document name (white-space: nowrap
         below) then forces the whole card wider than its grid column,
         pushing the card off-screen instead of letting it wrap/truncate. */
      min-width: 0;
    }
    .lib-card:hover { border-color: rgba(168, 85, 247, 0.4); background: rgba(168, 85, 247, 0.07); }
    .lib-card-icon { font-size: 1.5rem; line-height: 1.2; flex: 0 0 auto; }
    .lib-card-body { flex: 1 1 auto; min-width: 0; }
    .lib-card-name {
      font-size: 0.9rem; font-weight: 600; color: #f1f1f4;
      line-height: 1.3;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .lib-card-meta { font-size: 0.72rem; color: #8b909c; margin: 0.15rem 0 0.5rem; }
    /* Where a page came from (AI Phase 20, feature 49). One line, cut off
       rather than wrapped, with the whole address in the tooltip. */
    .lib-card-source {
      font-size: 0.72rem; color: #8b909c; margin: -0.35rem 0 0.5rem;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    .lib-progress {
      height: 6px; border-radius: 4px;
      background: rgba(255, 255, 255, 0.1);
      overflow: hidden;
    }
    .lib-progress-bar {
      height: 100%;
      background: linear-gradient(90deg, #a855f7, #22d3ee);
      border-radius: 4px;
      transition: width 0.2s ease;
    }

    .lib-card-foot {
      display: flex; align-items: center; justify-content: space-between;
      margin-top: 0.5rem; gap: 0.4rem;
    }
    .lib-card-status { font-size: 0.72rem; color: #a3a8b4; }
    .lib-card-actions { display: flex; gap: 0.35rem; }
    .lib-btn {
      border: none; border-radius: 5px; cursor: pointer;
      font-family: inherit; font-size: 0.74rem; font-weight: 600;
      padding: 0.32rem 0.6rem; transition: all 0.15s ease;
    }
    .lib-btn-resume { background: linear-gradient(135deg, #a855f7, #7e22ce); color: #fff; }
    .lib-btn-resume:hover { transform: translateY(-1px); }
    .lib-btn-remove { background: rgba(239, 68, 68, 0.15); color: #f87171; padding: 0.32rem 0.5rem; }
    .lib-btn-remove:hover { background: rgba(239, 68, 68, 0.28); color: #fca5a5; }

    .library-modal-foot {
      margin-top: 0.85rem; padding-top: 0.7rem;
      border-top: 1px solid rgba(255, 255, 255, 0.08);
      display: flex; justify-content: flex-end;
    }
    .library-clear-btn {
      background: none; border: 1px solid rgba(239, 68, 68, 0.3);
      color: #f87171; border-radius: 5px; cursor: pointer;
      font-family: inherit; font-size: 0.74rem; padding: 0.35rem 0.7rem;
    }
    .library-clear-btn:hover { background: rgba(239, 68, 68, 0.12); }

    /* Light theme */
    body.light-mode .library-modal-panel { background: #ffffff; border-color: rgba(168, 85, 247, 0.3); }
    body.light-mode .library-modal-head h2 { color: #6b21a8; }
    body.light-mode .library-modal-sub,
    body.light-mode .library-empty { color: #6b7280; }
    body.light-mode .library-modal-close { background: rgba(0,0,0,0.06); color: #444; }
    body.light-mode .lib-card { background: rgba(0,0,0,0.02); border-color: rgba(0,0,0,0.1); }
    body.light-mode .lib-card:hover { background: rgba(168, 85, 247, 0.06); }
    body.light-mode .lib-card-name { color: #1f2430; }
    body.light-mode .lib-card-meta, body.light-mode .lib-card-status, body.light-mode .lib-card-source { color: #6b7280; }
    body.light-mode .lib-progress { background: rgba(0,0,0,0.1); }
    body.light-mode .library-launcher { color: #6b21a8; }

    @media (max-width: 600px) {
      .library-modal-panel { margin: 0; max-height: 100vh; height: 100vh; border-radius: 0; }
      .library-grid { grid-template-columns: 1fr; }
    }

    /* Floating selection toolbar (Highlight) shown above a text selection */
    .library-sel-toolbar {
      position: fixed;
      z-index: 10001;
      display: flex;
      gap: 1px;
      border-radius: 7px;
      overflow: hidden;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
      animation: selToolbarIn 0.12s ease;
    }
    .library-sel-toolbar[hidden] { display: none; }
    .sel-tool-btn {
      border: none;
      padding: 0.38rem 0.62rem;
      font-family: inherit;
      font-size: 0.74rem;
      font-weight: 600;
      color: #fff;
      cursor: pointer;
      white-space: nowrap;
    }
    .sel-tool-highlight { background: linear-gradient(135deg, #f59e0b, #d97706); }
    .sel-tool-btn:hover { filter: brightness(1.08); }
    @keyframes selToolbarIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }

    /* Mobile: anchored to the top-centre, below the fixed top bar, and made
       bigger for thumbs. It is deliberately NOT at the bottom any more: that
       overlapped the tab bar (Import / Listen / Format / Display). Android's own
       selection menu tracks the selection rather than an edge, so the top is
       just as clear of it. Position is set in library.js. */
    .library-sel-toolbar.sel-toolbar-mobile {
      gap: 2px;
      border-radius: 11px;
      box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
      animation: selBarUp 0.16s ease;
      /* It is centred with left:50% and translateX(-50%), so anything wider
         than the window hangs off BOTH edges and its end buttons cannot be
         reached. Measured at 412px wide: 548px of toolbar sitting at left -68,
         with Highlight - the first button - off the left edge. Found on a
         phone, but this rule applies to any window under 768px, which a
         resized desktop window reaches too. max-content lets it use the width
         it has before wrapping, rather than stacking nearly one per row. */
      width: max-content;
      max-width: calc(100vw - 16px);
      flex-wrap: wrap;
      justify-content: center;
    }
    .sel-toolbar-mobile .sel-tool-btn {
      padding: 0.7rem 1.1rem;
      font-size: 0.92rem;
    }
    /* Slides down from under the top bar now that the toolbar is top-anchored. */
    @keyframes selBarUp { from { opacity: 0; transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); } }

    /* ============================================
       HIGHLIGHTS & NOTES — header button + modal
       ============================================ */
    /* Highlights button (lives in the zoom-controls bar above the canvas).
       Always amber + white so it's readable on day one, before any highlight
       exists; gains a ring once the document has highlights. */
    .hl-open-btn {
      background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
      color: #fff !important;
      border: none !important;
      font-weight: 600;
      white-space: nowrap;
    }
    .hl-open-btn:hover { filter: brightness(1.08); }
    .hl-open-btn.has-highlights { box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.45); }

    .hl-modal { position: fixed; inset: 0; z-index: 10000; }
    .hl-modal[hidden] { display: none; }
    .hl-modal-backdrop {
      position: absolute; inset: 0;
      background: rgba(0, 0, 0, 0.62);
      backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
    }
    .hl-modal-panel {
      position: relative;
      max-width: 680px; margin: 4vh auto 0; max-height: 92vh;
      display: flex; flex-direction: column;
      background: #14161c;
      border: 1px solid rgba(245, 158, 11, 0.28);
      border-radius: 12px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
      padding: 1.1rem 1.25rem 1rem;
      overflow: hidden;
    }
    .hl-modal-head { display: flex; align-items: center; justify-content: space-between; }
    .hl-modal-head h2 { margin: 0; font-size: 1.15rem; color: #fde68a; }
    .hl-modal-close {
      background: rgba(255,255,255,0.08); border: none; color: #ddd;
      width: 30px; height: 30px; border-radius: 6px; cursor: pointer; font-size: 0.9rem; line-height: 1;
    }
    .hl-modal-close:hover { background: rgba(255,255,255,0.16); }
    .hl-modal-sub { margin: 0.3rem 0 0.85rem; color: #9aa0ac; font-size: 0.82rem; font-style: italic; }
    .hl-empty { color: #9aa0ac; font-size: 0.9rem; padding: 2rem 0.5rem; text-align: center; }

    .hl-list { overflow-y: auto; display: flex; flex-direction: column; gap: 0.6rem; padding: 0.15rem; }
    .hl-item {
      display: grid;
      grid-template-columns: 1fr auto;
      grid-template-areas: "quote del" "note note";
      gap: 0.4rem 0.5rem;
      padding: 0.6rem 0.7rem;
      background: rgba(255,255,255,0.04);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 9px;
    }
    .hl-item-quote {
      grid-area: quote;
      text-align: left; cursor: pointer;
      background: none; border: none; padding: 0;
      color: #f1f1f4; font-family: inherit; font-size: 0.86rem; line-height: 1.5;
      border-left: 3px solid #f59e0b; padding-left: 0.6rem;
    }
    .hl-item-quote:hover { color: #fbbf24; }
    .hl-item-del {
      grid-area: del;
      align-self: start;
      background: rgba(239,68,68,0.12); border: none; color: #f87171;
      border-radius: 5px; cursor: pointer; font-size: 0.72rem; padding: 0.25rem 0.45rem;
    }
    .hl-item-del:hover { background: rgba(239,68,68,0.25); }
    .hl-item-note {
      grid-area: note;
      width: 100%; resize: none; overflow: hidden;
      background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.1);
      border-radius: 5px; color: #d4d4d8;
      font-family: inherit; font-size: 0.78rem; padding: 0.35rem 0.5rem; line-height: 1.4;
    }
    .hl-item-note:focus { outline: none; border-color: rgba(245,158,11,0.5); }

    .hl-modal-foot {
      margin-top: 0.85rem; padding-top: 0.7rem;
      border-top: 1px solid rgba(255,255,255,0.08);
      display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap;
    }
    .hl-export-group { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; }
    .hl-export-label { font-size: 0.72rem; color: #9aa0ac; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
    .hl-export-group button {
      background: linear-gradient(135deg, #f59e0b, #d97706); color: #fff;
      border: none; border-radius: 5px; cursor: pointer;
      font-family: inherit; font-size: 0.74rem; font-weight: 600; padding: 0.34rem 0.6rem;
    }
    .hl-export-group button:hover { filter: brightness(1.08); }
    .hl-clear-btn {
      background: none; border: 1px solid rgba(239,68,68,0.3); color: #f87171;
      border-radius: 5px; cursor: pointer; font-family: inherit; font-size: 0.74rem; padding: 0.34rem 0.6rem;
    }
    .hl-clear-btn:hover { background: rgba(239,68,68,0.12); }

    /* Light theme */
    body.light-mode .hl-modal-panel { background: #ffffff; border-color: rgba(245,158,11,0.35); }
    body.light-mode .hl-modal-head h2 { color: #b45309; }
    body.light-mode .hl-modal-sub, body.light-mode .hl-empty { color: #6b7280; }
    body.light-mode .hl-modal-close { background: rgba(0,0,0,0.06); color: #444; }
    body.light-mode .hl-item { background: rgba(0,0,0,0.02); border-color: rgba(0,0,0,0.1); }
    body.light-mode .hl-item-quote { color: #1f2430; }
    body.light-mode .hl-item-note { background: #f7f7f8; color: #333; border-color: rgba(0,0,0,0.12); }

    @media (max-width: 600px) {
      .hl-modal-panel { margin: 0; max-height: 100vh; height: 100vh; border-radius: 0; }
    }

    /* The exact-text flash highlight (used when jumping to a saved highlight)
       is applied via the CSS Custom Highlight API (::highlight(ts-flash)),
       injected by library.js so it can't get stuck behind a stale CSS cache
       and never mutates the editable output. */
/* ============================================
   SYNC STATUS STRIP (Library modal)
   Sync runs silently; this is the only place it reports itself.
   ============================================ */
.ts-sync-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--border-color, #d8dde5);
  border-radius: 10px;
  background: var(--surface-2, #f6f8fb);
}
.ts-sync-icon { font-size: 18px; line-height: 1; flex: 0 0 auto; }
.ts-sync-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.ts-sync-state { font-size: 14px; font-weight: 600; color: var(--text-color, #1c2430); }
.ts-sync-detail { font-size: 12px; color: var(--text-muted, #66707e); }
.ts-sync-btn {
  flex: 0 0 auto;
  padding: 7px 14px;
  border: 1px solid var(--border-color, #d8dde5);
  border-radius: 8px;
  background: var(--surface-1, #fff);
  color: var(--text-color, #1c2430);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.ts-sync-btn:hover:not(:disabled) { background: var(--surface-2, #eef2f7); }
.ts-sync-btn:disabled { opacity: .55; cursor: default; }

/* Tone is set from the sync state, never from the button. */
.ts-sync-strip[data-tone="ok"]    { border-color: #b7e0c2; background: #f0faf3; }
.ts-sync-strip[data-tone="ok"]    .ts-sync-state { color: #1d6b38; }
.ts-sync-strip[data-tone="busy"]  { border-color: #b9d3f0; background: #f1f7fd; }
.ts-sync-strip[data-tone="error"] { border-color: #f0c2c2; background: #fdf3f3; }
.ts-sync-strip[data-tone="error"] .ts-sync-state { color: #98322f; }
.ts-sync-strip[data-tone="off"]   { border-style: dashed; }

/* Sync on/off switch: a checkbox drawn as a switch, so it stays a real
   form control for keyboards and screen readers. */
.ts-sync-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-color, #1c2430);
  cursor: pointer;
  user-select: none;
}
.ts-sync-toggle input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 34px;
  height: 20px;
  margin: 0;
  border-radius: 999px;
  background: #aab3bf;
  cursor: pointer;
  transition: background .15s;
}
.ts-sync-toggle input::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
  transition: transform .15s;
}
.ts-sync-toggle input:checked { background: #2563eb; }
.ts-sync-toggle input:checked::before { transform: translateX(14px); }
.ts-sync-toggle input:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; }
.ts-sync-toggle input:disabled { opacity: .55; cursor: default; }
@media (prefers-reduced-motion: reduce) {
  .ts-sync-toggle input, .ts-sync-toggle input::before { transition: none; }
}

@media (max-width: 480px) {
  .ts-sync-strip { flex-wrap: wrap; }
  .ts-sync-btn { width: 100%; }
}

/* ============================================
   HEAVY RE-RENDER FEEDBACK
   Rebuilding a book-length preview takes seconds. Say so, rather than
   letting the app look frozen.
   ============================================ */
/* The 'ts-rendering' busy cursor was added and removed around every toggle,
   flashing the mouse pointer on each click. Toggles are synchronous again,
   so there is no window to flag and nothing to flash. */
/* The switch must stay at full strength while work happens - dimming it
   is exactly the "nothing happened" impression we are trying to remove. */

/* ============================================
   LONG-DOCUMENT RENDERING
   Bionic turns 825KB of HTML into 7.8MB across ~162,000 nodes on a
   book-length document. Laying all of that out at once froze the app for
   about four seconds every time a Transform toggle was pressed, which is
   why the buttons felt dead.

   content-visibility lets the browser skip layout and paint for blocks that
   are scrolled out of view — measured 4411ms -> 913ms on the same document.
   Ranges inside skipped blocks still report geometry, so the read-along
   highlight and its auto-scroll are unaffected.
   ============================================ */
/* Target the text blocks themselves. The rendered document is wrapped in a
   single container div, so a "> *" rule matched only that wrapper and skipped
   nothing at all. */
#outputContent p, #outputContent li, #outputContent blockquote,
#outputContent h1, #outputContent h2, #outputContent h3,
#outputContent h4, #outputContent h5, #outputContent h6,
#compareOriginalContent p, #compareOriginalContent li,
#compareBionicContent p, #compareBionicContent li {
  content-visibility: auto;
  contain-intrinsic-size: auto 3em;
}

/* Printing and PDF export must lay the whole document out, never skip it. */
@media print {
  #outputContent p, #outputContent li, #outputContent blockquote,
  #outputContent h1, #outputContent h2, #outputContent h3,
  #outputContent h4, #outputContent h5, #outputContent h6,
  #compareOriginalContent p, #compareOriginalContent li,
  #compareBionicContent p, #compareBionicContent li {
    content-visibility: visible;
  }
}
