/* styles-components-2.css — part 2 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. */
    /* ============================================
       FULLSCREEN reading mode — CSS-based (body.app-fullscreen)
       ============================================
       We deliberately avoid the native Fullscreen API: it puts #outputPanel in
       the browser top layer, which paints the body-level Highlights / My Library
       modals (and their buttons) BEHIND the fullscreen layer, making them
       unusable. A body class keeps everything in the normal stacking context —
       modals work, it scrolls with the page, and it clears the status bar on
       mobile browsers. */
    body.app-fullscreen header,
    body.app-fullscreen .app-breadcrumb,
    body.app-fullscreen .mnav-tabbar,
    body.app-fullscreen .mnav-backdrop,
    body.app-fullscreen .mnav-export-btn,
    body.app-fullscreen .input-panel,
    body.app-fullscreen .app-footer,
    body.app-fullscreen #outputHeader,
    body.app-fullscreen #readingStatsSection,
    body.app-fullscreen #outputTogglesBar,
    body.app-fullscreen #bionicSliderContainer,
    body.app-fullscreen #focusToolsBar,
    body.app-fullscreen #alignCustomizeRow,
    body.app-fullscreen #ttsPanel {
      display: none !important;
    }
    body.app-fullscreen,
    body.app-fullscreen #outputPanel { background: #0a0a0a; }

    /* Keep the zoom/reading control bar pinned at the top — below the status bar
       and camera — so Exit + zoom stay reachable while the page scrolls under it.
       z-index sits below the modals (z-index:10000) so Highlights/Library still
       open on top. */
    body.app-fullscreen #zoomControls {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 9000;
      margin: 0 !important;
      padding: 3.75rem 0.75rem 0.5rem; /* fallback if calc/env unsupported */
      padding: calc(env(safe-area-inset-top, 0px) + 3.25rem) 0.75rem 0.5rem;
      background: #0a0a0a;
      flex-wrap: wrap;
    }
    /* Bright labels on the black backdrop. !important because the fullscreen bar
       is always dark, but the app may be in light mode — and `body.light-mode
       .zoom-btn { color:#333 }` has equal specificity and wins on source order,
       turning the labels invisible on black. */
    body.app-fullscreen .zoom-btn {
      color: #ffffff !important;
      background: rgba(255,255,255,0.16) !important;
      border-color: rgba(255,255,255,0.35) !important;
    }
    body.app-fullscreen .zoom-level { color: #ffffff !important; }

    /* Push the document clear of the fixed control bar (which wraps to two rows
       on narrow screens). */
    body.app-fullscreen .preview-wrapper {
      padding-top: 8.75rem; /* fallback */
      padding-top: calc(env(safe-area-inset-top, 0px) + 8.25rem);
    }

    /* Light-mode restyle of the focus-mode floating button */
    body.light-mode .canvas-restore-btn { color: #04140a; }

    /* Preview Wrapper - scrollable area for A4 document */
    .preview-wrapper {
      overflow: auto;
      flex: 1;
      max-height: calc(100vh - 280px);
      background: rgba(0,0,0,0.15);
      border-radius: 8px;
      padding: 1rem;
    }

    /* Preview Container - A4 Size (210mm x 297mm) */
    .preview-container {
      background: #fff;
      border-radius: 2px;
      padding: 25mm 20mm;
      width: 210mm;
      min-height: 297mm;
      margin: 0 auto;
      box-shadow: 0 4px 30px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,0,0,0.08);
      transform-origin: top center;
      transition: transform 0.2s ease;
    }

    .preview-container.dark-mode {
      background: #1a1a1a;
    }

    /* Editable A4 content */
    #outputContent {
      cursor: text;
      min-height: 100px;
      /* The caret inherits the app chrome's near-white text colour, which is
         invisible against the white page — so the document looked read-only
         even though typing worked. Pin it to the page's own ink instead. */
      caret-color: #111827;
    }
    /* Dark Output flips the page to dark, so the caret has to flip too. */
    .preview-container.dark-mode #outputContent,
    body.app-dark-output #outputContent {
      caret-color: #f3f4f6;
    }
    #outputContent:focus {
      outline: 2px solid rgba(34, 197, 94, 0.3);
      outline-offset: 4px;
      border-radius: 2px;
    }
    #outputContent:empty::before {
      content: 'Your formatted text will appear here...';
      color: #a3a3a3;
      font-style: italic;
    }

    /* Links from imported HTML/URL/DOCX content (opened externally — see
       makeLinksOpenExternally() in core-formatting.js). #outputContent forces
       a text-edit cursor everywhere above, which hides the normal "this is
       clickable" affordance; restore it just for links. */
    .ts-ext-link { cursor: pointer; }

    /* When docx-preview is active, adjust preview container */
    .preview-container.docx-active {
      padding: 8px !important;
      background: #fff !important;
    }

    /* Strip inline background the library sets on the render target itself */
    .preview-container.docx-active #outputContent {
      background: transparent !important;
      background-color: transparent !important;
    }

    /* Dark Output on a DOCX import.
       .docx-active above forces an !important white so it can beat the inline
       styles docx-preview writes. That also silently beat .dark-mode, so Dark
       Output flipped its button to "On" and changed nothing on a Word file.
       Both levels have to answer: the container, and each rendered page. Text
       is recoloured the same way dyslexic-mode-on overrides fonts, since
       docx-preview writes its colours inline on every run. Images and the
       highlighter are untouched - highlights paint through the CSS Custom
       Highlight API, not an element background. */
    /* The frame around a Word page. updatePreview() darkens the DOCX render
       itself with an invert filter, but .preview-container sits outside the
       filtered element, so .docx-active's !important white left a bright
       border around a dark page. Only the frame is set here - giving the
       content its own colours would sit UNDER the filter and be inverted back
       into near-black text. */
    .preview-container.docx-active.dark-mode {
      background: #1a1a1a !important;
    }

    /* Dark Output on the text path (imported HTML/PDF/EPUB, and anything the
       template formatter produced). No invert filter here: applyCustomStyles()
       writes the template's body colour inline on each element - #2d3748 by
       default - and dark mode only recoloured the parent, which an inline
       colour on the child beats. That left dark navy text on a #1a1a1a page.
       A stylesheet !important does beat a plain inline style, so force light
       text. Scoped away from .docx-active so the filtered path is untouched. */
    .preview-container.dark-mode:not(.docx-active) #outputContent,
    .preview-container.dark-mode:not(.docx-active) #outputContent *:not(a) {
      color: #f2f2f2 !important;
    }
    .preview-container.dark-mode:not(.docx-active) #outputContent a {
      color: #7dd3fc !important;
    }

    /* docx-preview outer wrapper div (.docx-preview-wrapper-wrapper) — strip the grey background the library injects */
    #outputContent .docx-preview-wrapper-wrapper {
      width: 100% !important;
      padding: 0 !important;
      margin: 0 !important;
      min-height: auto !important;
      background: transparent !important;
      background-color: transparent !important;
    }
    /* Each rendered page section (.docx-preview-wrapper) = white card */
    #outputContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper {
      max-width: 100% !important;
      min-height: auto !important;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15) !important;
      margin-bottom: 16px !important;
      margin-left: auto !important;
      margin-right: auto !important;
      background: #ffffff !important;
      background-color: #ffffff !important;
      border-radius: 3px;
      border: 1px solid #d0d0d0 !important;
      overflow: hidden !important;
    }
    /* Remove margin on last page */
    #outputContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper:last-child {
      margin-bottom: 0 !important;
    }
    /* Force page breaks to actually create separate visual pages */
    #outputContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper + section.docx-preview-wrapper {
      page-break-before: always;
    }

    /* The same page-fitting constraints, for the Compare panes.
       Everything above is scoped to #outputContent, so a Word page inside a
       Compare pane kept its natural width (773px in a 410px pane) and was cut
       off at both edges. The panes are narrower than the main canvas, so the
       page has to scale down rather than merely be clipped. */
    #compareOriginalContent .docx-preview-wrapper-wrapper,
    #compareBionicContent .docx-preview-wrapper-wrapper {
      width: 100% !important;
      padding: 0 !important;
      margin: 0 !important;
      min-height: auto !important;
      background: transparent !important;
      background-color: transparent !important;
    }
    #compareOriginalContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper,
    #compareBionicContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper {
      width: 100% !important;
      max-width: 100% !important;
      min-height: auto !important;
      padding: 12px !important;
      margin: 0 auto 12px !important;
      background: #ffffff !important;
      background-color: #ffffff !important;
      border-radius: 3px;
      border: 1px solid #d0d0d0 !important;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15) !important;
      overflow: hidden !important;
      box-sizing: border-box !important;
    }
    /* docx-preview writes fixed pixel widths on inner tables and images; let
       them reflow to the pane instead of pushing it sideways. */
    #compareOriginalContent .docx-preview-wrapper-wrapper table,
    #compareBionicContent .docx-preview-wrapper-wrapper table,
    #compareOriginalContent .docx-preview-wrapper-wrapper img,
    #compareBionicContent .docx-preview-wrapper-wrapper img {
      max-width: 100% !important;
      height: auto !important;
    }
    #compareOriginalContent, #compareBionicContent {
      overflow-x: hidden !important;
    }

    /* Page break indicator between docx-preview pages */
    .page-break-indicator {
      display: flex;
      align-items: center;
      gap: 10px;
      margin: 4px 0;
      user-select: none;
    }
    .page-break-indicator::before,
    .page-break-indicator::after {
      content: '';
      flex: 1;
      height: 1px;
      border-top: 1px dashed #999;
    }
    .page-break-indicator span {
      font-size: 0.6rem;
      color: #888;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      white-space: nowrap;
      font-family: 'DM Sans', 'Inter', system-ui, sans-serif;
    }

    /* Page break divider for template-formatted content */
    .page-break-divider {
      display: flex;
      align-items: center;
      gap: 10px;
      margin: 1.5rem 0;
      padding: 0.5rem 0;
      user-select: none;
      page-break-before: always;
    }
    .page-break-divider::before,
    .page-break-divider::after {
      content: '';
      flex: 1;
      height: 0;
      border-top: 2px dashed #ccc;
    }
    .page-break-divider span {
      font-size: 0.65rem;
      color: #999;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      white-space: nowrap;
      font-family: 'DM Sans', 'Inter', system-ui, sans-serif;
      padding: 0.15rem 0.6rem;
      background: rgba(0,0,0,0.03);
      border-radius: 3px;
    }
    /* Dark mode page break styling */
    .dark-mode .page-break-divider::before,
    .dark-mode .page-break-divider::after {
      border-top-color: #555;
    }
    .dark-mode .page-break-divider span {
      color: #777;
      background: rgba(255,255,255,0.05);
    }

    /* TOC dot leaders: tab-stop spans in TOC entries get dotted fill */
    #outputContent .docx-preview-wrapper-wrapper .docx-tab-stop {
      display: inline-block;
      min-width: 2em;
    }
    /* Right-aligned tab stops in TOC */
    #outputContent .docx-preview-wrapper-wrapper p .docx-tab-stop[style*="right"] {
      flex-grow: 1;
    }

    /* Compare Mode Container */
    .compare-container {
      display: none;
      gap: 1rem;
    }
    .compare-container.visible {
      display: grid;
      grid-template-columns: 1fr 1fr;
      max-height: calc(100vh - 240px);
      overflow: auto;
    }
    @media (max-width: 800px) {
      .compare-container.visible { grid-template-columns: 1fr; }
    }
    .compare-pane {
      border-radius: 8px;
      padding: 1.5rem;
      min-height: 200px;
      overflow: auto;
    }
    .compare-pane.original {
      background: #f5f5f5;
      border: 2px solid #e5e5e5;
    }
    .compare-pane.bionic {
      background: #fff;
      border: 2px solid #22c55e;
    }
    .compare-pane.dark-mode {
      background: #1a1a1a;
      color: #e5e5e5;
    }
    .compare-pane.dark-mode.original {
      border-color: #404040;
    }
    .compare-label {
      font-size: 0.7rem;
      letter-spacing: 0.1em;
      margin-bottom: 0.75rem;
      padding-bottom: 0.5rem;
      border-bottom: 1px solid rgba(0,0,0,0.1);
    }
    .compare-pane.dark-mode .compare-label {
      border-bottom-color: rgba(255,255,255,0.1);
    }
    .compare-label.original-label { color: #737373; }
    .compare-label.bionic-label { color: #16a34a; }

    .output-stats { font-size: 0.8rem; color: #737373; text-align: right; }

    /* Footer */
    .app-footer {
      background: rgba(12, 12, 12, 0.95);
      border-top: 1px solid rgba(255, 255, 255, 0.1);
      padding: 1.5rem 2rem;
      text-align: center;
      margin-top: auto;
    }
    .footer-content {
      max-width: 1200px;
      margin: 0 auto;
    }
    .footer-content p {
      margin: 0.3rem 0;
      font-size: 0.85rem;
      color: #737373;
    }
    .footer-content a {
      color: #00ff00;
      text-decoration: none;
    }
    .footer-content a:hover {
      text-decoration: underline;
    }

    /* Toast */
    .toast {
      position: fixed;
      bottom: 2rem;
      left: 50%;
      transform: translateX(-50%) translateY(100px);
      background: #1a1a1a;
      border: 1px solid rgba(34, 197, 94, 0.4);
      padding: 1rem 1.5rem;
      border-radius: 8px;
      color: #4ade80;
      font-size: 0.9rem;
      opacity: 0;
      transition: all 0.3s ease;
      z-index: 3000;
      box-shadow: 0 10px 40px rgba(0,0,0,0.3);
    }

    .toast.visible {
      transform: translateX(-50%) translateY(0);
      opacity: 1;
    }

    .toast.error {
      border-color: rgba(239, 68, 68, 0.4);
      color: #f87171;
    }

    /* Theme Toggle Switch */
    .theme-toggle-wrapper {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      margin-right: 1rem;
    }
    .theme-toggle-label {
      font-size: 0.75rem;
      color: #a3a3a3;
      font-weight: 500;
      letter-spacing: 0.05em;
      white-space: nowrap;
    }
    .theme-toggle-track {
      width: 44px;
      height: 24px;
      background: #404040;
      border-radius: 100px;
      position: relative;
      cursor: pointer;
      transition: background 0.3s ease;
      flex-shrink: 0;
    }
    .theme-toggle-track.light {
      background: #22c55e;
    }
    .theme-toggle-thumb {
      position: absolute;
      top: 3px;
      left: 3px;
      width: 18px;
      height: 18px;
      background: #fff;
      border-radius: 50%;
      transition: left 0.3s ease;
      box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    }
    .theme-toggle-track.light .theme-toggle-thumb {
      left: 23px;
    }

    /* Light Mode Overrides */
    body.light-mode {
      background: linear-gradient(160deg, #f5f5f5 0%, #e8e8e8 40%, #f0f0f0 100%);
      color: #1a1a1a;
    }
    body.light-mode::before {
      background-image:
        linear-gradient(rgba(0,0,0,0.03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(0,0,0,0.03) 1px, transparent 1px);
    }
    body.light-mode header {
      background: rgba(255,255,255,0.92);
      border-bottom-color: rgba(0,0,0,0.08);
      box-shadow: 0 1px 4px rgba(0,0,0,0.06);
    }
    body.light-mode .header-center-subtitle { color: #555 !important; }
    body.light-mode .theme-toggle-label { color: #555; }
    body.light-mode .usage-badge {
      background: rgba(34, 197, 94, 0.12);
      color: #16a34a;
      border-color: rgba(34, 197, 94, 0.3);
    }
    body.light-mode .help-dropdown-trigger {
      background: rgba(34, 197, 94, 0.08);
      border-color: rgba(34, 197, 94, 0.25);
      color: #16a34a;
    }
    body.light-mode .help-dropdown-trigger:hover {
      background: rgba(34, 197, 94, 0.15);
    }
    body.light-mode .help-dropdown-menu {
      background: #ffffff;
      border-color: rgba(34, 197, 94, 0.3);
      box-shadow: 0 10px 40px rgba(0,0,0,0.12);
    }
    body.light-mode .help-dropdown-item {
      border-bottom-color: rgba(0,0,0,0.06);
    }
    body.light-mode .help-dropdown-item:hover {
      background: rgba(34, 197, 94, 0.08);
    }
    body.light-mode .help-title { color: #1a1a1a; }
    body.light-mode .help-desc { color: #666; }
    body.light-mode .modal-content {
      background: #ffffff;
      border-color: rgba(34, 197, 94, 0.25);
      box-shadow: 0 20px 60px rgba(0,0,0,0.15);
    }
    body.light-mode .modal-header {
      border-bottom-color: rgba(0,0,0,0.1);
    }
    body.light-mode .modal-close { color: #888; }
    body.light-mode .modal-close:hover { color: #333; }
    body.light-mode .modal-body { color: #444; }
    body.light-mode .modal-overlay {
      background: rgba(0,0,0,0.4);
    }
    body.light-mode .section-label { color: #444; }
    body.light-mode .dropdown-trigger {
      background: rgba(255,255,255,0.7);
      border-color: rgba(0,0,0,0.12);
      color: #1a1a1a;
    }
    body.light-mode .dropdown-trigger:hover {
      border-color: rgba(34, 197, 94, 0.4);
    }
    body.light-mode .dropdown-trigger.open {
      border-color: rgba(34, 197, 94, 0.5);
    }
    body.light-mode .dropdown-selected .style-name { color: #1a1a1a; }
    body.light-mode .dropdown-selected .style-desc { color: #777; }
    body.light-mode .dropdown-arrow { color: #777; }
    body.light-mode .dropdown-menu {
      background: #ffffff;
      border-color: rgba(34, 197, 94, 0.35);
      box-shadow: 0 8px 30px rgba(0,0,0,0.1);
    }
    body.light-mode .dropdown-item {
      border-bottom-color: rgba(0,0,0,0.05);
    }
    body.light-mode .dropdown-item:hover {
      background: rgba(34, 197, 94, 0.06);
    }
    body.light-mode .dropdown-item .style-name { color: #1a1a1a; }
    body.light-mode .dropdown-item.selected .style-name { color: #16a34a; }
    body.light-mode .dropdown-item .style-desc { color: #777; }
    body.light-mode .upload-area {
      border-color: rgba(0,0,0,0.15);
      background: rgba(255,255,255,0.5);
    }
    body.light-mode .upload-area:hover {
      border-color: rgba(34, 197, 94, 0.4);
      background: rgba(34, 197, 94, 0.04);
    }
    body.light-mode .upload-text { color: #444; }
    body.light-mode .upload-hint { color: #777; }
    body.light-mode .format-badge {
      background: rgba(0,0,0,0.06);
      color: #555;
    }
    body.light-mode #inputText {
      background: rgba(255,255,255,0.8);
      border-color: rgba(0,0,0,0.12);
      color: #1a1a1a;
    }
    body.light-mode #inputText:focus {
      border-color: rgba(34, 197, 94, 0.5);
      box-shadow: 0 0 20px rgba(34, 197, 94, 0.08);
    }
    body.light-mode #inputText::placeholder { color: #aaa; }
    body.light-mode .input-stats { color: #777; }
    body.light-mode .small-text-btn {
      border-color: rgba(0,0,0,0.12);
      color: #666;
    }
    body.light-mode .small-text-btn:hover {
      border-color: rgba(0,0,0,0.25);
      color: #333;
    }
    body.light-mode .textarea-header .section-label { color: #444; }
    body.light-mode .output-panel {
      background: rgba(0,0,0,0.01);
    }
    body.light-mode main.split .input-panel {
      border-bottom-color: rgba(0,0,0,0.08);
    }
    body.light-mode .export-btn.copy {
      background: rgba(0,0,0,0.04);
      border-color: rgba(0,0,0,0.12);
      color: #666;
    }
    body.light-mode .export-btn.copy:hover {
      background: rgba(0,0,0,0.08);
      color: #333;
    }
    body.light-mode .toggle-btn {
      background: rgba(0,0,0,0.04);
      border-color: rgba(0,0,0,0.12);
      color: #666;
    }
    body.light-mode .toggle-switch { background: #ccc; }
    body.light-mode .bionic-section {
      background: rgba(168, 85, 247, 0.06);
      border-color: rgba(168, 85, 247, 0.15);
    }
    body.light-mode .bionic-preview {
      background: rgba(0,0,0,0.04);
      color: #333;
    }
    body.light-mode .compare-section {
      background: rgba(6, 182, 212, 0.06);
      border-color: rgba(6, 182, 212, 0.15);
    }
    body.light-mode .dark-output-section {
      background: rgba(139, 92, 246, 0.06);
      border-color: rgba(139, 92, 246, 0.15);
    }
    body.light-mode .dyslexic-section {
      background: rgba(236, 72, 153, 0.06);
      border-color: rgba(236, 72, 153, 0.15);
    }
    body.light-mode .customize-panel {
      background: rgba(0,0,0,0.03);
      border-color: rgba(34, 197, 94, 0.2);
    }
    body.light-mode .tts-panel {
      background: rgba(6, 182, 212, 0.04);
      border-color: rgba(6, 182, 212, 0.2);
    }
    body.light-mode .ocr-progress {
      background: rgba(6, 182, 212, 0.05);
      border-color: rgba(6, 182, 212, 0.2);
    }
    body.light-mode .ocr-progress-text { color: #0e7490; }
    body.light-mode .ocr-progress-track { background: rgba(0,0,0,0.08); }
    body.light-mode .tts-label { color: #555; }
    body.light-mode .tts-voice {
      background: rgba(0,0,0,0.04);
      border-color: rgba(0,0,0,0.12);
      color: #333;
    }
    body.light-mode .tts-progress {
      background: rgba(6, 182, 212, 0.08);
      color: #0e7490;
    }
    body.light-mode .customize-header:hover {
      background: rgba(34, 197, 94, 0.06);
    }
    body.light-mode .control-label { color: #666; }
    body.light-mode .size-input,
    body.light-mode .color-hex,
    body.light-mode .spacing-select {
      background: rgba(255,255,255,0.8);
      border-color: rgba(0,0,0,0.12);
      color: #1a1a1a;
    }
    body.light-mode .spacing-select option {
      background: #fff;
      color: #1a1a1a;
    }
    body.light-mode .color-input {
      border-color: rgba(0,0,0,0.15);
    }
    body.light-mode .size-unit { color: #999; }
    body.light-mode .bionic-labels { color: #999; }
    body.light-mode .recent-files-section {
      background: rgba(59, 130, 246, 0.06);
      border-color: rgba(59, 130, 246, 0.15);
    }
    body.light-mode .recent-file-item {
      background: rgba(59, 130, 246, 0.08);
      border-color: rgba(59, 130, 246, 0.2);
      color: #2563eb;
    }
    body.light-mode .recent-file-item:hover {
      background: rgba(59, 130, 246, 0.15);
    }
    body.light-mode .reading-stats-section {
      background: rgba(245, 158, 11, 0.06);
      border-color: rgba(245, 158, 11, 0.15);
    }
    body.light-mode .file-info-bar {
      background: rgba(34, 197, 94, 0.06);
      border-color: rgba(34, 197, 94, 0.2);
    }
    body.light-mode .app-footer {
      background: rgba(255,255,255,0.92);
      border-top-color: rgba(0,0,0,0.08);
    }
    body.light-mode .footer-content p { color: #888; }
    body.light-mode .footer-content a { color: #16a34a; }
    body.light-mode .toast {
      background: #ffffff;
      border-color: rgba(34, 197, 94, 0.35);
      box-shadow: 0 10px 40px rgba(0,0,0,0.1);
    }
    body.light-mode .toast.error {
      border-color: rgba(239, 68, 68, 0.35);
    }
    body.light-mode .output-stats { color: #999; }

    /* Light mode - zoom controls */
    body.light-mode .zoom-btn {
      background: rgba(0,0,0,0.06);
      border-color: rgba(0,0,0,0.15);
      color: #333;
    }
    body.light-mode .zoom-btn:hover {
      background: rgba(0,0,0,0.12);
      border-color: rgba(0,0,0,0.25);
    }
    body.light-mode .zoom-level { color: #555; }

    /* Light mode - reading stats */
    body.light-mode .stat-value { color: #b45309; }
    body.light-mode .stat-label { color: #555; }
    body.light-mode .stat-highlight { background: rgba(168, 85, 247, 0.1); }
    body.light-mode .stat-highlight .stat-value { color: #7c3aed; }

    /* Light mode - toggle buttons */
    body.light-mode .toggle-btn { color: #444; }
    body.light-mode .toggle-name { color: #444; }
    body.light-mode .toggle-state { color: #666; }

    /* Light mode - recent files */
    body.light-mode .recent-files-clear { color: #555; }
    body.light-mode .recent-files-clear:hover { color: #dc2626; }

    /* Light mode - file info */
    body.light-mode .file-info-details { color: #16a34a; }
    body.light-mode .file-remove { color: #dc2626; }

    /* Light mode - output header */
    body.light-mode .output-header-title { color: #16a34a; }
    body.light-mode .export-btn.clear {
      background: rgba(0,0,0,0.04);
      border-color: rgba(0,0,0,0.12);
      color: #666;
    }
    body.light-mode .export-btn.clear:hover {
      background: rgba(0,0,0,0.08);
      color: #333;
    }

    /* Light mode - customize panel */
    body.light-mode .customize-title { color: #16a34a; }
    body.light-mode .customize-toggle { color: #16a34a; }

    /* Light mode - bionic slider */
    body.light-mode .bionic-slider-container { color: #444; }
    body.light-mode .bionic-value { color: #555; }

    /* Light mode - customize dropdown overlay */
    body.light-mode .customize-content {
      background: rgba(255, 255, 255, 0.97);
      border-color: rgba(34, 197, 94, 0.25);
      box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    }

    /* ============================================
       MOBILE RESPONSIVE — Components
       ============================================ */

    /* Tablets */
    @media (max-width: 900px) {
      .compare-container.visible {
        grid-template-columns: 1fr;
      }
      /* Override base 210mm width so preview fits tablet viewport */
      .preview-container {
        width: 100%;
        min-height: auto;
        box-sizing: border-box;
      }
    }

    /* Mobile phones */
    @media (max-width: 768px) {
      /* Override base 210mm/297mm — fit document to mobile viewport */
      .preview-container {
        width: 100%;
        min-height: auto;
        box-sizing: border-box;
        overflow-x: hidden;
      }
      /* Prevent content overflow inside the document area */
      #outputContent {
        word-break: break-word;
        overflow-wrap: anywhere;
        max-width: 100%;
        overflow-x: hidden;
        /* Small reading gutter so text doesn't run edge-to-edge after Shift My
           Text. Applied to the editable content area so the white canvas
           still spans the full viewport width — only the text is padded. */
        padding-left: 1rem;
        padding-right: 1rem;
        box-sizing: border-box;
      }
      /* docx-preview pages: constrain to viewport on mobile */
      #outputContent .docx-preview-wrapper-wrapper > section.docx-preview-wrapper {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
      }
      /* Prevent preview wrapper from scrolling horizontally (document fits within) */
      .preview-wrapper {
        overflow-x: hidden;
      }
      /* Show zoom + the Highlights button on mobile. applyZoom() uses the CSS
         `zoom` property here (reflows text) instead of transform:scale, which
         clipped the page and was the reason these were hidden before. */
      .zoom-controls {
        display: flex !important;
        flex-wrap: wrap;
        justify-content: center;
        gap: 0.4rem;
      }
      /* AI Tools (plus Undo/Redo beside it) was sitting early in the row,
         eating the width "+" needed to stay on the same wrapped line as
         "100%" — push all three past Fullscreen instead so the zoom cluster
         (−/100%/+) stays together. Reordering only, not moving in the DOM,
         so nothing else (tab order, the wide desktop layout above 768px)
         changes. */
      #aiToolsBtn, #undoBtn, #redoBtn { order: 1; }
      /* Match Copy to Hide Panel & Fullscreen's size and text colour on
         mobile, where .export-btn's own sizing/colour rules (smaller font,
         dimmer grey) made it look inconsistent with the zoom-controls row it
         visually sits alongside. ID selector beats .export-btn's class rules
         regardless of source order, including the tighter override at the
         480px breakpoint further down. */
      #copyOutputBtn {
        padding: 0.25rem 0.6rem;
        font-size: 0.75rem;
        color: #e5e5e5;
      }
      /* The SEO-only <h1> must never render. Some mobile browsers don't honour
         the clip-based .sr-only pattern, so force it off here. */
      h1.sr-only { display: none !important; }
      .output-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.3rem;
      }
      .output-actions {
        width: 100%;
        flex-wrap: wrap;
        gap: 0.3rem;
      }
      .export-btn {
        flex: 1 1 auto;
        min-width: 0;
        justify-content: center;
        font-size: 0.62rem;
        padding: 0.35rem 0.4rem;
      }
      .output-toggles-bar {
        flex-direction: column;
        gap: 0.25rem;
      }
      .output-toggles-bar > div {
        width: 100%;
      }
      .output-toggles-bar .compare-header,
      .output-toggles-bar .dark-output-header,
      .output-toggles-bar .dyslexic-header,
      .output-toggles-bar .bionic-header {
        justify-content: space-between;
      }
      .bionic-slider-container {
        max-width: 100%;
        flex-direction: column;
        gap: 0.3rem;
      }
      .bionic-slider {
        width: 100%;
      }
      .align-customize-row.visible {
        flex-direction: column;
      }
      .text-align-group {
        align-self: flex-start;
      }
      .text-format-group {
        align-self: flex-start;
        flex-wrap: wrap;
      }
      .format-font {
        width: 80px;
      }
      .customize-panel {
        padding: 0.4rem;
      }

      /* Let the align-customize-row wrap so the Customize button gets its own
         line at full width instead of being squeezed beside Font/Size/Colour. */
      .align-customize-row {
        flex-wrap: wrap;
      }
      .align-customize-row .customize-panel {
        flex: 1 1 100%;
        max-width: 100%;
      }
      .align-customize-row .customize-header {
        white-space: nowrap;
      }

      /* main.split adds extra rules (max-width: 500px on panel, min-width: 580px
         on content) that override the mobile sizing. Neutralise them so the
         customize panel and dropdown behave the same regardless of split mode. */
      main.split .input-panel > .customize-panel {
        max-width: 100% !important;
        flex: 1 1 100% !important;
      }

      /* The Customize Sizes & Colours dropdown becomes a bottom-anchored sheet
         on mobile: always full viewport width, capped at 70vh tall, with its
         own scroll. Position fixed means it ignores stacking contexts of the
         canvas above and always sits in the same place regardless of where the
         button is in the layout. */
      .customize-content,
      main.split .input-panel > .customize-panel .customize-content.open {
        position: fixed !important;
        top: auto !important;
        bottom: 0 !important;
        left: 0 !important;
        right: 0 !important;
        width: 100vw !important;
        max-width: 100vw !important;
        min-width: 0 !important;
        max-height: 70vh !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        z-index: 200 !important;
        border-radius: 12px 12px 0 0 !important;
        box-shadow: 0 -8px 24px rgba(0,0,0,0.5) !important;
        box-sizing: border-box;
      }

      /* Sticky "Done" header at the top of the bottom-sheet so the user can
         always dismiss the sheet, regardless of how far they've scrolled. */
      .customize-sheet-header {
        display: flex !important;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.65rem 0.4rem 0.65rem 0.2rem;
        margin: -0.6rem -0.6rem 0.5rem -0.6rem;
        position: sticky;
        top: -0.6rem;
        background: rgba(20, 20, 20, 0.98);
        border-bottom: 1px solid rgba(34, 197, 94, 0.25);
        z-index: 5;
      }
      body.light-mode .customize-sheet-header {
        background: rgba(250, 250, 252, 0.98);
        border-bottom-color: rgba(34, 197, 94, 0.3);
      }
      .customize-sheet-title {
        font-size: 0.88rem;
        font-weight: 600;
        color: #4ade80;
      }
      body.light-mode .customize-sheet-title { color: #16a34a; }
      .customize-sheet-close {
        background: rgba(34, 197, 94, 0.15);
        border: 1px solid rgba(34, 197, 94, 0.4);
        color: #4ade80;
        padding: 0.4rem 0.85rem;
        font-size: 0.82rem;
        font-weight: 600;
        font-family: inherit;
        border-radius: 6px;
        cursor: pointer;
        white-space: nowrap;
        min-height: 36px;
      }
      .customize-sheet-close:hover,
      .customize-sheet-close:active {
        background: rgba(34, 197, 94, 0.25);
      }
      body.light-mode .customize-sheet-close {
        background: rgba(34, 197, 94, 0.1);
        border-color: rgba(34, 197, 94, 0.4);
        color: #16a34a;
      }

      /* Backdrop behind the sheet — tap to close. Provided by a ::before
         pseudo-element on body when the sheet is open. The backdrop is invisible
         pointer-events: none unless the sheet is open. */
      body:has(.customize-content.open)::before {
        content: '';
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.4);
        z-index: 199;
        pointer-events: none;
      }
      .control-group {
        grid-template-columns: 1fr;
      }
      .compare-pane {
        padding: 1rem;
      }
      .theme-toggle-wrapper {
        margin-right: 0.3rem;
      }
      .theme-toggle-label {
        font-size: 0.65rem;
      }
      .app-footer {
        padding: 1rem;
      }
      .footer-content p {
        font-size: 0.75rem;
      }

      /* ============================================================
         HYBRID MOBILE LAYOUT (only affects screens 768px and below).
         Goal: canvas dominates, TTS panel is sticky and compact,
         each control gets a comfortable tap target. Desktop layout
         is completely unaffected.
         ============================================================ */

      /* Visibility of .input-panel, #outputHeader, #readingStatsSection,
         #outputTogglesBar, #bionicSliderContainer, #alignCustomizeRow and
         #ttsPanel on mobile — plus the tab bar that shows them — now lives in
         css/mobile-nav.css (loaded after this file) alongside js/mobile-nav.js. */

      /* Canvas (preview wrapper) edge-to-edge on mobile and tall enough to
         own the bottom of the screen. The footer is hidden on mobile so the
         canvas can extend to the viewport bottom without wasted space. */
      .preview-wrapper {
        margin: 0 !important;
        padding: 0 !important;
        border-radius: 0 !important;
        width: 100% !important;
        min-height: calc(100dvh - 120px);
      }
      .preview-container {
        border-radius: 0 !important;
        padding: 0 !important;
        margin: 0 !important;
        width: 100% !important;
        max-width: 100% !important;
        box-shadow: none !important;
        min-height: calc(100dvh - 130px);
      }
      /* output-panel: remove any horizontal margins on mobile so canvas is truly edge-to-edge */
      .output-panel {
        padding: 0 !important;
        margin: 0 !important;
      }
      /* Footer eats valuable mobile screen space. The canvas owns the bottom. */
      .app-footer { display: none !important; }

      /* docx-preview renders A4 pages with native margins (typically 1 inch),
         which leaves only ~60% of the canvas width for actual text on mobile.
         Compress those margins so text reads closer to edge-to-edge.
         The library uses className "docx-preview-wrapper" so the rendered DOM is:
           <div class="docx-preview-wrapper-wrapper">
             <section class="docx-preview-wrapper" style="padding: 1in; ...">
               ...content...
         These inline styles win without !important, so we hammer them. */
      #outputContent .docx-preview-wrapper-wrapper,
      #outputContent section.docx-preview-wrapper {
        padding-left: 0.6rem !important;
        padding-right: 0.6rem !important;
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
      }
      #outputContent section.docx-preview-wrapper > * {
        max-width: 100% !important;
      }

      /* TTS panel: full width, sticky above canvas so it's reachable
         even while the user is reading the document */
      .tts-panel {
        max-width: 100%;
        margin: 0.4rem 0;
        padding: 0.65rem 0.7rem;
        position: sticky;
        top: 0;
        z-index: 20;
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
        background: rgba(10, 14, 20, 0.92);
        border-color: rgba(6, 182, 212, 0.35);
      }
      body.light-mode .tts-panel {
        background: rgba(250, 250, 252, 0.92);
        border-color: rgba(6, 182, 212, 0.35);
      }

      /* The bottom-sheet "Listen" tab already acts as the drop-down on
         mobile, so hide the desktop collapse toggle and always show the body
         (ignore the "collapsed" class, which is desktop-only state). */
      .tts-toggle { display: none; }
      .tts-panel.collapsed .tts-body { display: block; }
      .tts-actions-break { display: none; }

      /* Same reasoning as .tts-toggle above: the Export/Display/Format/Import
         bottom-sheet tabs already show #uploadBlock/#actionStatsRow/
         #readingStatsSection/#outputTogglesBar/#outputHeader/
         #bionicSliderContainer/#alignCustomizeRow individually, so hide these
         desktop-only toggles here. The force-hide rules that key off
         .import-collapsed/.format-collapsed (styles-core.css) are themselves
         scoped to desktop, so there's no "ignore collapsed state" override
         needed here the way the old wrapper-based version required. */
      .input-toolbar-toggle,
      .output-toolbar-toggle {
        display: none;
      }

      /* Stack the TTS controls into a tidy 2-column grid — Engine/Voice/Speed
         each take the full row, Read-along + Colour share a row */
      .tts-controls {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.8rem 0.7rem;
        align-items: stretch;
      }
      .tts-engine-control,
      .tts-voice-control,
      .tts-speed-control {
        grid-column: 1 / -1;
        max-width: 100%;
        min-width: 0;
      }
      .tts-highlight-control,
      .tts-color-control {
        grid-column: span 1;
        max-width: 100%;
        min-width: 0;
      }
      .tts-engine-control .tts-voice,
      .tts-voice-control .tts-voice,
      .tts-speed-control .tts-speed,
      .tts-highlight-control .tts-highlight,
      .tts-color-control .tts-highlight {
        width: 100%;
      }

      /* Roomier labels and dropdowns, with a custom chevron replacing the
         cramped native one */
      .tts-label { font-size: 0.68rem; }
      .tts-engine-control .tts-voice,
      .tts-voice-control .tts-voice,
      .tts-highlight-control .tts-highlight,
      .tts-color-control .tts-highlight {
        padding: 0.85rem 2.2rem 0.85rem 0.9rem;
        font-size: 1rem;
        border-radius: 10px;
        background-color: rgba(255,255,255,0.06);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: right 0.9rem center;
        appearance: none;
        -webkit-appearance: none;
      }

      /* Speed row: "1.0x" becomes its own pill badge beside the SPEED label,
         a gradient track with a bigger thumb, and 0.5x/2.0x hints under the
         slider's ends */
      .tts-speed-control { position: relative; padding-bottom: 1.1rem; }
      .tts-speed-control .tts-label { display: flex; align-items: center; gap: 0.4rem; }
      #ttsSpeedLabel {
        background: rgba(6, 182, 212, 0.18);
        color: #67e8f9;
        border-radius: 999px;
        padding: 0.15rem 0.55rem;
        font-size: 0.72rem;
        font-weight: 700;
        text-transform: none;
        letter-spacing: normal;
      }
      .tts-speed {
        height: 6px;
        border-radius: 999px;
        background: linear-gradient(90deg, #7c3aed 0%, #06b6d4 100%);
        appearance: none;
        -webkit-appearance: none;
        margin-top: 0.5rem;
      }
      .tts-speed::-webkit-slider-thumb {
        appearance: none;
        -webkit-appearance: none;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: #22d3ee;
        border: 3px solid #0a0e14;
        box-shadow: 0 1px 4px rgba(0,0,0,0.4);
      }
      .tts-speed::-moz-range-thumb {
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: #22d3ee;
        border: 3px solid #0a0e14;
        box-shadow: 0 1px 4px rgba(0,0,0,0.4);
      }
      .tts-speed-control::before,
      .tts-speed-control::after {
        position: absolute;
        bottom: 0;
        font-size: 0.68rem;
        color: #a3a3a3;
      }
      .tts-speed-control::before { content: '0.5x'; left: 0; }
      .tts-speed-control::after { content: '2.0x'; right: 0; }

      .tts-listen { grid-column: 1; }
      .tts-stop { grid-column: 2; }
      .tts-record { grid-column: 1 / -1; }
      .tts-record-full { grid-column: 1 / -1; }
      .tts-record-selection { grid-column: 1 / -1; }

      /* Bigger, more tap-friendly action buttons. Listen/Stop become a pill;
         the three Save buttons become full-width rows with the label on the
         left and a chevron on the right — Save Full Doc stays the solid
         "primary" action, Save Recording/Save Selection become outlined
         secondary actions to match. */
      .tts-listen,
      .tts-stop {
        width: 100%;
        padding: 0.85rem 1rem;
        font-size: 1rem;
        min-height: 48px;
        border-radius: 999px;
      }
      .tts-record,
      .tts-record-full,
      .tts-record-selection {
        width: 100%;
        padding: 0.8rem 1rem;
        font-size: 0.9rem;
        min-height: 48px;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
      .tts-record::after,
      .tts-record-full::after,
      .tts-record-selection::after {
        content: '\203A';
        font-size: 1.3em;
        line-height: 1;
        opacity: 0.7;
      }
      .tts-record {
        background: rgba(34, 197, 94, 0.12);
        border: 1px solid rgba(34, 197, 94, 0.4);
        color: #4ade80;
      }
      .tts-record:hover:not(:disabled) { background: rgba(34, 197, 94, 0.2); }
      .tts-record-selection {
        background: rgba(245, 158, 11, 0.12);
        border: 1px solid rgba(245, 158, 11, 0.4);
        color: #fbbf24;
      }
      .tts-record-selection:hover:not(:disabled) { background: rgba(245, 158, 11, 0.2); }

      /* Inside the rendered document, slightly tighter inline margins */
      #outputContent > * {
        max-width: 100% !important;
      }

      /* The output toggles (Compare, Dark Output, Dyslexic, Bionic)
         take significant vertical space on mobile. Keep them stacked
         but make each row more compact. */
      .output-toggles-bar {
        gap: 0.2rem;
        padding: 0.3rem 0;
      }
      .output-toggles-bar > div {
        padding: 0.35rem 0.55rem;
      }

      /* Stats panel: shrink the giant numbers so all 4 stats fit
         comfortably on a narrow screen without wrapping awkwardly */
      .action-stats-row .stat-pill .stat-pill-value {
        font-size: 1.1rem;
      }
      .action-stats-row .stat-pill .stat-pill-label {
        font-size: 0.55rem;
      }
    }

    /* Small mobile phones */
    @media (max-width: 480px) {
      .preview-container {
        width: 100%;
        min-height: auto;
        box-sizing: border-box;
        overflow-x: hidden;
      }
      .output-actions {
        gap: 0.2rem;
      }
      .export-btn {
        font-size: 0.58rem;
        padding: 0.3rem 0.3rem;
        gap: 0.15rem;
      }
      .toggle-btn {
        font-size: 0.6rem;
        padding: 0.25rem 0.4rem;
      }
      .customize-title {
        font-size: 0.65rem;
      }
      .bionic-preview {
        font-size: 0.7rem;
      }
      .toast {
        left: 0.5rem;
        right: 0.5rem;
        transform: translateX(0) translateY(100px);
        width: auto;
        text-align: center;
        font-size: 0.8rem;
        padding: 0.75rem 1rem;
      }
      .toast.visible {
        transform: translateX(0) translateY(0);
      }
    }

