/* =========================================================================
   PDF Cleaner Web — stylesheet

   Notes on the choices here:

   * Fonts are system stacks. The previous sheet named IBM Plex without ever
     loading it, so the real rendering was Courier New for everything mono.
   * Layout uses CSS logical properties (inline-start/end, margin-inline), so
     the Farsi RTL locale works from the same rules instead of a pile of
     `[dir=rtl] … { flex-direction: row-reverse }` overrides.
   * Every colour is a token defined once per theme; both themes were checked
     for WCAG AA at the sizes actually used.
   ========================================================================= */

/* ---------- reset ---------- */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button, input, select { font: inherit; color: inherit; }

/* ---------- tokens ---------- */

:root {
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-full: 999px;

  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  --dur: 160ms;
  --ease: cubic-bezier(0.2, 0, 0.13, 1);

  --page-max: 900px;

  /* light theme */
  --bg:        #f4f7fb;
  --bg-glow:   #e6eefb;
  --surface:   #ffffff;
  --surface-2: #f1f5fa;
  --surface-3: #e7edf5;
  --border:    #d7e0ec;
  --border-strong: #bccbdd;

  --text:      #101a29;
  --text-muted:#526580;
  --text-faint:#7286a1;

  --accent:      #1d5fd0;
  --accent-hover:#164ead;
  --accent-soft: rgba(29, 95, 208, 0.09);
  --accent-ring: rgba(29, 95, 208, 0.35);
  --on-accent:   #ffffff;

  --ok:      #10714a;
  --ok-soft: rgba(16, 113, 74, 0.10);
  --warn:      #8a5a00;
  --warn-soft: rgba(138, 90, 0, 0.11);
  --danger:      #b3261e;
  --danger-soft: rgba(179, 38, 30, 0.09);

  --shadow-1: 0 1px 2px rgba(16, 26, 41, 0.06),
              0 2px 8px rgba(16, 26, 41, 0.05);
  --shadow-2: 0 8px 30px rgba(16, 26, 41, 0.13);
  --shadow-3: 0 24px 60px rgba(16, 26, 41, 0.22);
}

[data-theme="dark"] {
  --bg:        #0b0f14;
  --bg-glow:   #101822;
  --surface:   #141a22;
  --surface-2: #1a222c;
  --surface-3: #222c38;
  --border:    #26313e;
  --border-strong: #38465a;

  --text:      #e6ebf2;
  --text-muted:#9aabc0;
  --text-faint:#7387a0;

  --accent:      #5b9dfb;
  --accent-hover:#7cb2ff;
  --accent-soft: rgba(91, 157, 251, 0.14);
  --accent-ring: rgba(91, 157, 251, 0.45);
  --on-accent:   #08121f;

  --ok:      #4ed08d;
  --ok-soft: rgba(78, 208, 141, 0.13);
  --warn:      #e0b155;
  --warn-soft: rgba(224, 177, 85, 0.13);
  --danger:      #ff8078;
  --danger-soft: rgba(255, 128, 120, 0.13);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45), 0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-2: 0 10px 34px rgba(0, 0, 0, 0.55);
  --shadow-3: 0 28px 70px rgba(0, 0, 0, 0.7);
}

/* ---------- base ---------- */

html { -webkit-text-size-adjust: 100%; }

body {
  min-height: 100dvh;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background:
    radial-gradient(1100px 480px at 50% -12%, var(--bg-glow), transparent 70%),
    var(--bg);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

body.is-dragging { overflow: hidden; }

.sprite { display: none; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute;
  inset-inline-start: var(--sp-3);
  inset-block-start: -100px;
  z-index: 200;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-sm);
  background: var(--accent);
  color: var(--on-accent);
  transition: inset-block-start var(--dur) var(--ease);
}
.skip-link:focus { inset-block-start: var(--sp-3); }

.icon { width: 1.05em; height: 1.05em; flex: none; }

/* ---------- app bar ---------- */

.app-bar {
  position: sticky;
  inset-block-start: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5);
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(12px);
  border-block-end: 1px solid var(--border);
}

.brand { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.brand-mark { width: 30px; height: 30px; color: var(--accent); flex: none; }
.brand-text { min-width: 0; }
.brand-name { font-size: 16px; font-weight: 650; letter-spacing: -0.01em; }
.brand-tagline {
  font-size: 12.5px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Part of the name, not a chip beside it: a pill wider than the number it
   held was the loudest thing in the bar. */
.version-badge {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  color: var(--text-faint);
  margin-inline-start: 7px;
  letter-spacing: 0;
}

.app-bar-controls { display: flex; align-items: center; gap: var(--sp-2); }

/* ---------- segmented control ---------- */

/* A three-stop theme switch. Two states cannot say "follow the system",
   which is the default, so the thumb has a middle position and each stop
   carries its own symbol: sun, monitor, moon. */
.theme-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 3px;
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
}
.theme-thumb {
  position: absolute;
  inset-block: 3px;
  inset-inline-start: 3px;
  width: 30px;
  border-radius: var(--r-full);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur) var(--ease);
}
.theme-switch[data-position="1"] .theme-thumb { transform: translateX(30px); }
.theme-switch[data-position="2"] .theme-thumb { transform: translateX(60px); }
[dir="rtl"] .theme-switch[data-position="1"] .theme-thumb { transform: translateX(-30px); }
[dir="rtl"] .theme-switch[data-position="2"] .theme-thumb { transform: translateX(-60px); }
@media (prefers-reduced-motion: reduce) {
  .theme-thumb { transition: none; }
}
.theme-stop {
  position: relative;
  width: 30px;
  height: 24px;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--text-faint);
  border-radius: var(--r-full);
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}
.theme-stop .icon { width: 15px; height: 15px; }
.theme-stop:hover { color: var(--text-muted); }
.theme-stop[aria-checked="true"] { color: var(--accent); }

/* On the light theme the bar, the track and the selected pill were three
   near-whites, so the control did not read as a control at all. The track is
   recessed and the pill keeps the surface colour, which separates them in
   both themes. */
.seg {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
}
.seg-btn {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 12.5px;
  padding: 5px 12px;
  border-radius: var(--r-full);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.seg-btn:hover { color: var(--text); }
.seg-btn[aria-pressed="true"] {
  background: var(--surface);
  color: var(--text);
  font-weight: 550;
  box-shadow: var(--shadow-1);
}

.select {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 6px 10px;
  font-size: 13px;
  cursor: pointer;
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 9px 16px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: var(--surface-2);
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn:not(:disabled):active { transform: translateY(1px); }

.btn-quiet { border-color: var(--border); }
.btn-quiet:not(:disabled):hover {
  border-color: var(--border-strong);
  background: var(--surface-3);
}

.btn-accent {
  background: var(--accent);
  color: var(--on-accent);
  border-color: transparent;
}
.btn-accent:not(:disabled):hover { background: var(--accent-hover); }

.btn-ok {
  background: var(--ok-soft);
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent);
}
.btn-ok:not(:disabled):hover {
  background: color-mix(in srgb, var(--ok) 18%, transparent);
}

.btn-danger, .btn-danger-outline {
  background: transparent;
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}
.btn-danger:not(:disabled):hover, .btn-danger-outline:not(:disabled):hover {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.btn-lg { padding: 11px 20px; font-size: 14px; }
.btn-xs { padding: 5px 10px; font-size: 12px; border-radius: var(--r-xs); }
.btn-icon-only { padding: 8px; }
.btn-icon-only .btn-label { display: none; }
.btn.is-busy { pointer-events: none; opacity: 0.7; }

/* ---------- layout ---------- */

.app-main {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--sp-5) var(--sp-4) var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
}
.panel-head h2 { font-size: 15px; font-weight: 620; }

/* ---------- usage meter ---------- */

.usage { display: flex; align-items: center; gap: var(--sp-3); }
.usage-meter {
  width: 120px; height: 5px;
  background: var(--surface-3);
  border-radius: var(--r-full);
  overflow: hidden;
}
.usage-fill {
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: var(--r-full);
  transition: width 300ms var(--ease), background var(--dur) var(--ease);
}
.usage-fill.is-tight { background: var(--warn); }
.usage-text {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
}

/* ---------- drop zone ---------- */

.drop-zone {
  margin: var(--sp-4);
  padding: var(--sp-6) var(--sp-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-align: center;
  border: 2px dashed var(--border-strong);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.drop-zone:hover { border-color: var(--accent); background: var(--accent-soft); }
.drop-icon { width: 32px; height: 32px; color: var(--text-faint); }
.drop-title { font-size: 14.5px; font-weight: 550; }
.drop-hint { font-size: 12.5px; color: var(--text-muted); }
.drop-or {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.drop-zone.is-compact {
  flex-direction: row;
  align-items: center;
  justify-content: center;
  /* The row carries a button, so it needs more than the text's own height
     before the dashed border. */
  padding: var(--sp-4);
  gap: var(--sp-3);
}
.drop-zone.is-compact .drop-icon { width: 20px; height: 20px; }
.drop-zone.is-compact .drop-hint,
.drop-zone.is-compact .drop-or { display: none; }
.drop-zone.is-compact .drop-title { font-size: 13px; font-weight: 500; }

.upload-progress {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-4) var(--sp-4);
}
.upload-label {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
  min-width: 92px;
  text-align: end;
}

/* ---------- drop overlay ---------- */

.drop-overlay {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(6px);
}
.drop-overlay-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-6) var(--sp-6);
  border: 2px dashed var(--accent);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  font-size: 16px;
  font-weight: 550;
}
.drop-overlay-icon { width: 40px; height: 40px; color: var(--accent); }

/* ---------- toolbar ---------- */

.list-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  border-block: 1px solid var(--border);
  background: var(--surface-2);
}

.check { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: 13px; cursor: pointer; }
.check input { accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer; }

.selection-count {
  font-size: 12.5px;
  color: var(--accent);
  font-weight: 550;
}

.search {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  flex: 1 1 160px;
  min-width: 140px;
}
.search input {
  border: 0;
  background: transparent;
  outline: none;
  width: 100%;
  font-size: 13px;
}
.search:focus-within { border-color: var(--accent); }

.filters { display: flex; gap: var(--sp-1); flex-wrap: wrap; }
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px 11px;
  font-size: 12.5px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--dur) var(--ease);
}
.filter-chip:hover { border-color: var(--border-strong); color: var(--text); }
.filter-chip.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.chip-count {
  font-family: var(--font-mono);
  font-size: 11px;
  opacity: 0.75;
}

/* ---------- file list ---------- */

.file-list { list-style: none; }

.file-card {
  border-block-end: 1px solid var(--border);
  transition: background var(--dur) var(--ease);
  animation: card-in 200ms var(--ease);
  position: relative;
}
.file-card:last-child { border-block-end: 0; }
.file-card::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 3px;
  background: transparent;
  transition: background var(--dur) var(--ease);
}
.file-card[data-state="done"]::before  { background: var(--ok); }
.file-card[data-state="error"]::before { background: var(--danger); }
.file-card[data-state="processing"]::before { background: var(--accent); }
.file-card.is-selected { background: var(--accent-soft); }

.file-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}

.file-pick { display: inline-flex; align-items: center; cursor: pointer; }
.file-check { accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer; }

.file-icon {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  flex: none;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
}
.file-icon .icon { width: 17px; height: 17px; }
.file-card[data-state="done"] .file-icon {
  color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, transparent);
  background: var(--ok-soft);
}
.file-card[data-state="error"] .file-icon {
  color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: var(--danger-soft);
}
.file-card[data-state="processing"] .file-icon {
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-soft);
}
.file-card[data-state="processing"] .file-icon .icon { animation: spin 800ms linear infinite; }

.file-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.file-name {
  font-size: 13.5px;
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.file-meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
}
.file-meta > span:empty { display: none; }
.file-meta > span + span::before {
  content: "·";
  margin-inline-end: var(--sp-2);
  color: var(--text-faint);
}
.file-ttl.is-urgent { color: var(--warn); }

.file-progress { display: flex; align-items: center; gap: var(--sp-2); margin-block-start: 2px; }
.progress-track {
  flex: 1;
  height: 4px;
  min-width: 60px;
  background: var(--surface-3);
  border-radius: var(--r-full);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: var(--r-full);
  transition: width 350ms var(--ease);
}
.progress-fill.is-indeterminate {
  width: 35%;
  animation: slide 1.3s ease-in-out infinite;
}
.progress-stage, .progress-label {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  flex: none;
}
.progress-label { min-width: 34px; text-align: end; }

.file-actions { display: flex; align-items: center; gap: var(--sp-1); flex: none; }

/* The log is a side panel rather than a drawer under the card: it is read
   while the run is going, and a panel that pushes the whole list down moved
   the very rows the reader was watching. */
.log-panel {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: 160;
  width: min(560px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-inline-start: 1px solid var(--border);
  box-shadow: var(--shadow-3);
}
.log-panel-head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-block-end: 1px solid var(--border);
}
.log-panel-heading { min-width: 0; flex: 1; }
.log-panel-title {
  margin: 0;
  font-size: 15px;
  font-weight: 650;
}
.log-panel-file {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
/* The whole log, scrolled -- never trimmed to fit a box. */
.log-panel-body {
  flex: 1;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.65;
  color: var(--text-muted);
  white-space: pre-wrap;
  word-break: break-word;
  padding: var(--sp-3) var(--sp-4) var(--sp-5);
  background: var(--surface-2);
  overflow: auto;
  overscroll-behavior: contain;
}
.log-scrim {
  position: fixed;
  inset: 0;
  z-index: 155;
  background: color-mix(in srgb, var(--bg) 55%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .log-panel { animation: log-in var(--dur) var(--ease); }
}
@keyframes log-in {
  from { transform: translateX(var(--log-slide, 100%)); opacity: 0.4; }
  to { transform: translateX(0); opacity: 1; }
}
[dir="rtl"] .log-panel { --log-slide: -100%; }

/* ---------- empty state ---------- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-5);
  text-align: center;
}
.empty-icon { width: 34px; height: 34px; color: var(--text-faint); opacity: 0.6; }
.empty-title { font-size: 14px; font-weight: 550; }
.empty-desc { font-size: 13px; color: var(--text-muted); max-width: 34ch; }

/* ---------- options ---------- */

.options {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border-block-start: 1px solid var(--border);
}

.switch { display: flex; align-items: flex-start; gap: var(--sp-3); cursor: pointer; }
.switch input {
  position: absolute;
  opacity: 0;
  width: 40px;
  height: 22px;
  margin: 0;
  cursor: pointer;
}
.switch-track {
  position: relative;
  width: 40px; height: 22px;
  flex: none;
  margin-block-start: 1px;
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.switch-thumb {
  position: absolute;
  inset-block-start: 2px;
  inset-inline-start: 2px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  transition: translate var(--dur) var(--ease);
}
.switch input:checked ~ .switch-track {
  background: var(--accent);
  border-color: var(--accent);
}
.switch input:checked ~ .switch-track .switch-thumb { translate: 18px 0; }
[dir="rtl"] .switch input:checked ~ .switch-track .switch-thumb { translate: -18px 0; }
.switch input:focus-visible ~ .switch-track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* The app-bar variant: one line, no description, the hint lives in `title`. */
.switch-compact {
  align-items: center;
  gap: var(--sp-2);
  padding: 4px var(--sp-2) 4px 4px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--surface-2);
}
.switch-compact .switch-track { margin-block-start: 0; }
.switch-compact .switch-label {
  font-size: 12.5px;
  color: var(--text-muted);
  white-space: nowrap;
}
@media (max-width: 720px) {
  .switch-compact .switch-label { display: none; }
  .switch-compact { padding-inline-end: 4px; }
}

.switch-copy { display: flex; flex-direction: column; gap: 1px; }
.switch-title { font-size: 13.5px; font-weight: 500; }
.switch-desc { font-size: 12.5px; color: var(--text-muted); }

.params {
  display: flex;
  gap: var(--sp-4);
  flex-wrap: wrap;
  /* Line the fields up under the switch copy: track width plus its gap. */
  padding-inline-start: calc(40px + var(--sp-3));
}
.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
  flex: 1 1 150px;
  max-width: 260px;
}
.field label {
  font-size: 11.5px;
  font-family: var(--font-mono);
  color: var(--text-muted);
}
.field input {
  width: 100%;
  min-width: 0;
  padding: 7px 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: 13px;
  font-family: var(--font-mono);
  outline: none;
  transition: border-color var(--dur) var(--ease);
}
.field input:focus { border-color: var(--accent); }

.actions, .results-bar {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.actions {
  align-items: center;
  justify-content: space-between;
}
.actions .btn { flex: 0 1 auto; }
.mode-picker {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.mode-label { font-size: 13px; color: var(--text-muted); }
.run-icon { display: inline-flex; }
.results-bar {
  padding: var(--sp-4);
  border-block-start: 1px solid var(--border);
  background: var(--surface-2);
}
/* One action left in the bar; stretching it across the panel made a single
   button look like an unfinished row. */
.results-bar .btn { flex: 0 1 auto; }

/* ---------- toasts ---------- */

.toast-region {
  position: fixed;
  inset-block-end: var(--sp-4);
  inset-inline-end: var(--sp-4);
  z-index: 180;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: min(400px, calc(100vw - var(--sp-5)));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--text-muted);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  font-size: 13.5px;
  pointer-events: auto;
  animation: toast-in 220ms var(--ease);
}
.toast.is-leaving { animation: toast-out 200ms var(--ease) forwards; }
.toast-icon { width: 18px; height: 18px; flex: none; margin-block-start: 1px; }
.toast-msg { flex: 1; min-width: 0; }
.toast-success { border-inline-start-color: var(--ok); }
.toast-success .toast-icon { color: var(--ok); }
.toast-error { border-inline-start-color: var(--danger); }
.toast-error .toast-icon { color: var(--danger); }
.toast-warning { border-inline-start-color: var(--warn); }
.toast-warning .toast-icon { color: var(--warn); }
.toast-info { border-inline-start-color: var(--accent); }
.toast-info .toast-icon { color: var(--accent); }

.toast-action {
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: var(--r-xs);
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
  flex: none;
}
.toast-action:hover { border-color: var(--accent); color: var(--accent); }
.toast-close {
  border: 0;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  padding: 2px;
  border-radius: var(--r-xs);
  flex: none;
}
.toast-close:hover { color: var(--text); }

/* ---------- dialogs ---------- */

.dialog {
  /* The global reset zeroes margin, which kills the UA's `margin: auto`
     centering for modal <dialog> elements. Restore it explicitly. */
  margin: auto;
  width: min(640px, calc(100vw - var(--sp-5)));
  max-height: min(80dvh, 720px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.dialog-wide { width: min(1100px, calc(100vw - var(--sp-4))); max-height: 92dvh; }
.dialog::backdrop {
  background: rgba(4, 8, 14, 0.6);
  backdrop-filter: blur(3px);
}
.dialog[open] { display: flex; flex-direction: column; animation: dialog-in 200ms var(--ease); }

.dialog-head { padding: var(--sp-5) var(--sp-5) var(--sp-3); }
.dialog-head h2 { font-size: 17px; font-weight: 620; }
.dialog-desc { font-size: 13.5px; color: var(--text-muted); margin-block-start: var(--sp-2); }

.dialog-tools {
  display: flex;
  gap: var(--sp-2);
  padding-inline: var(--sp-5);
  padding-block-end: var(--sp-3);
}
.dialog-body { flex: 1; overflow: auto; padding: 0 var(--sp-5) var(--sp-4); }
.dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  border-block-start: 1px solid var(--border);
  background: var(--surface-2);
}

.review-group {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  margin-block-end: var(--sp-3);
  background: var(--surface-2);
}
.review-objects { list-style: none; display: flex; flex-direction: column; gap: var(--sp-2); }
.review-object {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.review-check { display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.review-check input { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.review-object-name { font-family: var(--font-mono); font-size: 12.5px; }
.review-reasons {
  font-size: 11.5px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.review-patterns { margin-block-start: var(--sp-3); }
.review-patterns-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  margin-block-end: var(--sp-2);
}
.review-scan-summary {
  font-size: 11.5px;
  color: var(--text-muted);
  margin-block-end: var(--sp-2);
}

/* Blanket approval and free-text entry, below the per-file lists. */
.dialog-extra {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-block-start: 1px solid var(--border);
}
.dialog-extra[hidden] { display: none; }
.review-all { display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.review-all input { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.review-hint, .review-custom-label { font-size: 11.5px; color: var(--text-muted); }
.review-custom-label { margin-block-start: var(--sp-2); }
#review-custom:disabled { opacity: 0.55; cursor: not-allowed; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- preview ---------- */

.preview-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.preview-head h2 {
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Nothing inside the preview is worth selecting except the file name, and a
   stray drag used to paint the labels blue mid-comparison. */
#preview-dialog { user-select: none; }
#preview-title { user-select: text; }

/* A fixed stage. The panes used to shrink-wrap their page, so turning to a
   narrower page resized the dialog and moved the arrows out from under the
   pointer -- the next click landed on the backdrop and closed the preview. */
.preview-stage {
  /* An explicit height, not `flex: 1`: a flex basis of zero inside an
     auto-height dialog would collapse the stage instead of filling it. */
  height: 66dvh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 0 var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  overflow: hidden;
  min-height: 0;
  height: 66dvh;
}
.preview-pane {
  position: relative;
  padding: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 0;
}
/* One divider between before and after, rather than two boxes side by side. */
.preview-pane-after { border-inline-start: 1px solid var(--border); }
.preview-label {
  font-size: 11.5px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
/* The page fills what the label leaves and is letterboxed inside it, so the
   image box is the same rectangle on every page. The render is opaque, so the
   white of the paper is the page itself -- a background here would paint the
   letterbox white too. */
.preview-pane img {
  flex: 1;
  min-height: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: var(--r-xs);
}
.preview-pane-after .preview-label { color: var(--ok); }

.dialog.is-loading .preview-pane img { opacity: 0.35; }

.preview-controls {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-block-start: 1px solid var(--border);
  background: var(--surface-2);
}
.preview-status {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  flex: 1;
  text-align: center;
}

/* ---------- responsive ---------- */

@media (max-width: 760px) {
  .brand-tagline { display: none; }
  .app-bar { padding: var(--sp-3); gap: var(--sp-2); }
  .app-bar-controls { width: 100%; justify-content: space-between; }
  .seg-btn { padding: 5px 9px; font-size: 12px; }
}

@media (max-width: 620px) {
  body { font-size: 14.5px; }
  .app-main { padding: var(--sp-3) var(--sp-2) var(--sp-5); }
  .panel { border-radius: var(--r-md); }
  .file-row { flex-wrap: wrap; gap: var(--sp-2); }
  .file-actions { width: 100%; justify-content: flex-end; }
  .btn-xs .btn-label { display: none; }
  .btn-xs { padding: 7px; }
  .file-actions .btn-xs .icon { width: 16px; height: 16px; }
  .usage { width: 100%; }
  .usage-meter { flex: 1; width: auto; }
  .actions { align-items: stretch; flex-direction: column; }
  .actions .btn, .results-bar .btn { flex: 1 1 100%; }
  .mode-picker { justify-content: space-between; }
  .mode-picker .seg { flex: 1; }
  .seg-btn { flex: 1; }
  .params { padding-inline-start: 0; }
  .log-panel { width: 100vw; }
  .field input { width: 100%; }

  /* Stack the two renders instead of squeezing them side by side. */
  .preview-stage { grid-template-columns: 1fr; }
  .preview-pane img { max-height: 44dvh; }
}

@media (max-width: 420px) {
  .filter-chip { padding: 4px 9px; font-size: 12px; }
  .drop-zone { padding: var(--sp-5) var(--sp-3); }
}

/* ---------- motion ---------- */

@keyframes spin { to { rotate: 360deg; } }
@keyframes slide {
  0%   { translate: -140% 0; }
  100% { translate: 400% 0; }
}
@keyframes card-in {
  from { opacity: 0; translate: 0 -4px; }
  to   { opacity: 1; translate: 0 0; }
}
@keyframes toast-in {
  from { opacity: 0; translate: 0 12px; scale: 0.98; }
  to   { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes toast-out {
  to { opacity: 0; translate: 0 8px; scale: 0.98; }
}
@keyframes dialog-in {
  from { opacity: 0; scale: 0.97; }
  to   { opacity: 1; scale: 1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .file-card[data-state="processing"] .file-icon .icon,
  .progress-fill.is-indeterminate {
    animation: none !important;
  }
  .progress-fill.is-indeterminate { width: 100%; opacity: 0.4; }
}

@media (prefers-contrast: more) {
  :root, [data-theme="dark"] {
    --border: var(--border-strong);
    --text-muted: var(--text);
  }
}
