/* ============================================================
   Comfreessor Web — design tokens & base layout
   Permanent dark mode, matching the mobile/desktop apps.
   ============================================================ */

:root {
  --bg: #121417;
  --surface: #1a1d20;
  --surface-elevated: #22262a;
  --on-bg: #e5e7ea;
  --on-bg-muted: #9ba1a8;
  --on-bg-faint: #6b7280;
  --primary: #afd4ea;
  --primary-dark: #6c9dc0;
  --primary-tint: rgba(175, 212, 234, 0.15);
  --border: #2c3035;
  --danger: #d0342c;
  --success: #5eb37c;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --shadow-1: 0 2px 4px rgba(0,0,0,0.25);
  --shadow-2: 0 8px 24px rgba(0,0,0,0.35);

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

  --font-stack: -apple-system, BlinkMacSystemFont, "SF Pro Display",
                "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--on-bg);
  font-family: var(--font-stack);
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ============================================================
   Top bar
   ============================================================ */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 10;
}

/* Brand cluster — icon + title together, both inside a single anchor
   that links to the marketing/landing site. Sits on the left of the
   topbar; the actions group is pushed to the right via margin-left:
   auto on .topbar__actions below. */
.topbar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--on-bg);
  border-radius: var(--radius-md);
  padding: 2px 4px 2px 2px;
  transition: opacity 0.15s;
}

.topbar__brand:hover {
  opacity: 0.85;
}

.topbar__title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.topbar__brand-icon {
  width: 36px;
  height: 36px;
  border-radius: 9px;
  background: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

/* Right-aligned group of icon buttons (privacy / terms / donate). */
.topbar__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 4px;
}

.topbar__brand-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.topbar__back {
  background: none;
  border: none;
  color: var(--on-bg);
  font-size: 20px;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.15s;
}

.topbar__back:hover:not(:disabled) {
  background: var(--surface);
}

.topbar__back:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

/* Generic icon button used in the topbar for privacy / terms / donate.
   They sit in a row to the right of the brand icon. */
.topbar__icon-btn {
  background: none;
  border: none;
  color: var(--on-bg-muted);
  cursor: pointer;
  padding: var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.15s, color 0.15s;
  width: 36px;
  height: 36px;
}

.topbar__icon-btn:hover {
  background: var(--surface);
  color: var(--on-bg);
}

.topbar__icon-btn svg {
  display: block;
}

/* ============================================================
   Modal — used by Privacy and Terms (and any future legal text).
   ============================================================ */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: var(--space-4);
  animation: fade-in 0.12s ease-out;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  max-width: 560px;
  max-height: 80vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  position: relative;
  animation: slide-up 0.16s ease-out;
}

.modal__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: transparent;
  border: none;
  color: var(--on-bg-muted);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s, color 0.12s;
}

.modal__close:hover {
  background: var(--surface-elevated);
  color: var(--on-bg);
}

.modal__close svg {
  display: block;
}

.modal__title {
  margin: 0;
  padding: var(--space-4) var(--space-5) var(--space-2) var(--space-5);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.modal__body {
  padding: 0 var(--space-5) var(--space-5) var(--space-5);
  overflow-y: auto;
  white-space: pre-line;
  color: var(--on-bg);
  font-size: 14px;
  line-height: 1.55;
}

/* CTA block at the bottom of the info modal — a prominent button
   that takes the user to the donation page. */
.modal__cta {
  margin-top: var(--space-4);
  display: flex;
  justify-content: center;
  /* break out of the parent's pre-line wrapping so the button isn't
     preceded by a stray blank line from the body's trailing newline */
  white-space: normal;
}

.modal__cta-btn {
  background: var(--primary);
  color: var(--bg);
  border: none;
  border-radius: var(--radius-pill);
  padding: 10px 22px;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s;
}

.modal__cta-btn:hover {
  background: var(--primary-dark);
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes slide-up {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}

/* ============================================================
   Main content area
   ============================================================ */

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.screen__content {
  flex: 1;
  overflow: auto;
  padding: var(--space-4);
}

/* ============================================================
   Welcome screen
   ============================================================ */

.welcome {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-6);
  gap: var(--space-4);
}

.welcome__icon {
  width: 96px;
  height: 96px;
  border-radius: 24px;
  background: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  margin-bottom: var(--space-3);
}

.welcome__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.welcome__title {
  font-size: 28px;
  font-weight: 700;
  margin: 0;
  letter-spacing: -0.02em;
}

.welcome__subtitle {
  max-width: 460px;
  color: var(--on-bg-muted);
  font-size: 15px;
  line-height: 1.5;
  margin: 0;
}

.welcome__warning {
  max-width: 460px;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--on-bg-muted);
  line-height: 1.5;
}

.welcome__warning strong {
  color: var(--on-bg);
}

/* ============================================================
   Buttons
   ============================================================ */

.btn {
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s, border-color 0.15s;
  white-space: nowrap;
}

.btn--primary {
  background: var(--primary);
  color: var(--bg);
}

.btn--primary:hover:not(:disabled) {
  background: var(--primary-dark);
}

.btn--primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn--secondary {
  background: transparent;
  color: var(--primary);
  border-color: var(--border);
}

.btn--secondary:hover:not(:disabled) {
  background: var(--surface);
  border-color: var(--primary-dark);
}

.btn--secondary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* "Armed" state for the Limpiar lista button (one click made, waiting
   for the confirmation click). Borrows the row-X danger style. */
.btn--danger-confirm {
  color: var(--bg);
  background: var(--danger);
  border-color: var(--danger);
}

.btn--danger-confirm:hover:not(:disabled) {
  background: var(--danger);
  border-color: var(--danger);
}

.btn--text {
  background: transparent;
  color: var(--primary);
  padding: 8px 12px;
}

.btn--text:hover:not(:disabled) {
  background: var(--surface);
}

/* ============================================================
   Level selector (chips)
   ============================================================ */

.level-selector {
  margin-bottom: var(--space-3);
}

.level-selector__title {
  font-size: 12px;
  color: var(--on-bg-muted);
  margin: 0 0 var(--space-2);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}

.level-selector__row {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  scrollbar-width: none;
}

.level-selector__row::-webkit-scrollbar {
  display: none;
}

.chip {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
  font-size: 13px;
  color: var(--on-bg);
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  transition: all 0.15s;
}

.chip:hover:not(.chip--active) {
  border-color: var(--primary-dark);
}

.chip--active {
  background: var(--primary-tint);
  border-color: var(--primary);
  color: var(--primary);
}

/* Banner shown while the queue is in PAUSING state — pause was
   requested but the worker is still finishing the current file
   (the file is being processed by ffmpeg, which we can't interrupt
   mid-job). Shows a quick shortcut to bail out of the current file. */
.pausing-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin: 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  background: rgba(175, 212, 234, 0.10);
  border: 1px solid var(--primary-dark);
  border-radius: var(--radius-md);
  color: var(--primary);
  font-size: 13px;
  text-align: center;
}

.pausing-banner__text {
  flex: 0 1 auto;
}

.pausing-banner__btn {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: var(--radius-pill);
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  flex-shrink: 0;
}

.pausing-banner__btn:hover {
  background: var(--danger);
  color: var(--bg);
}

/* ============================================================
   Toolbar — sits below the topbar with the add-buttons.
   ============================================================ */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) 0;
  flex-wrap: wrap;
}

.toolbar__warning {
  flex: 1 1 100%;
  font-size: 12px;
  color: var(--on-bg-muted);
  padding: var(--space-2) var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-top: var(--space-2);
  line-height: 1.4;
}

/* ============================================================
   Level selector block (two side-by-side selectors)
   ============================================================ */

.level-block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
}

@media (max-width: 600px) {
  .level-block {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* ============================================================
   File list (single-screen layout, header + body siblings)
   ============================================================ */

.file-list__header,
.file-list__row {
  display: grid;
  grid-template-columns: 1.7fr 0.9fr 0.9fr 1.3fr;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-4);
  font-size: 13px;
}

.file-list__header {
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--on-bg-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  flex-shrink: 0;
}

.file-list__body {
  flex: 1;
  overflow-y: auto;
  min-height: 200px;
  transition: background 0.15s, box-shadow 0.15s;
}

/* Dragging state — light wash + dashed inset border so the drop
   zone is visually obvious without shifting the layout. */
.file-list__body--dragging {
  background: var(--primary-tint);
  box-shadow: inset 0 0 0 2px var(--primary);
}

.file-list__row {
  border-bottom: 1px solid var(--border);
  transition: background 0.1s;
}

.file-list__row:hover {
  background: var(--surface);
}

.file-list__row:last-child {
  border-bottom: none;
}

.file-list__name {
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.file-list__name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* X-button to remove a file from the list. Hidden by default and
   revealed when the row is hovered. The "armed" state (after the first
   click) overrides hover and forces it visible in red. */
.row__cancel {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--on-bg-muted);
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.12s, background 0.12s, color 0.12s;
}

.row__cancel svg {
  display: block;
}

.file-list__row:hover .row__cancel {
  opacity: 1;
}

.row__cancel:hover {
  background: var(--surface-elevated);
  color: var(--on-bg);
}

.row__cancel--armed,
.file-list__row:hover .row__cancel--armed {
  opacity: 1;
  color: var(--bg);
  background: var(--danger);
}

.file-list__reduction {
  color: var(--primary);
}

.file-list__reduction--none {
  color: var(--on-bg-faint);
}

/* Red size cell for videos rejected as too large. */
.file-list__size--too-big {
  color: var(--danger);
  font-weight: 600;
}

.file-list__empty {
  padding: var(--space-6);
  text-align: center;
  color: var(--on-bg-faint);
  font-size: 14px;
  /* Pointer feedback so users know they can drop here. */
  pointer-events: none;
}

/* ============================================================
   Folder list (between welcome and file list)
   ============================================================ */

.folder-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin: 0 var(--space-4);
}

.folder-list__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
}

.folder-list__row:last-child { border-bottom: none; }
.folder-list__row:hover { background: var(--surface); }

.folder-list__check {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.folder-list__info {
  flex: 1;
  min-width: 0;
}

.folder-list__name {
  font-size: 15px;
  font-weight: 500;
  margin: 0 0 2px;
}

.folder-list__meta {
  font-size: 12px;
  color: var(--on-bg-muted);
}

.folder-list__selected {
  font-size: 12px;
  color: var(--primary);
  margin-top: 2px;
}

/* ============================================================
   Bottom bar
   ============================================================ */

.bottombar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border);
  background: var(--bg);
  flex-shrink: 0;
}

.bottombar__status {
  flex: 1;
  font-size: 13px;
  color: var(--on-bg-muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   Status pill (for file rows)
   ============================================================ */

.status-pending      { color: var(--on-bg-muted); }
.status-processing   { color: var(--primary); }
.status-done         { color: var(--success); }
.status-skipped      { color: var(--on-bg-faint); }
.status-failed       { color: var(--danger); }
.status-too_big      { color: var(--danger); }
.status-too_complex  { color: var(--danger); }
.status-too_long     { color: var(--danger); }

/* Status cell while a file is processing — a label + (optionally) a
   progress bar after the 3-second grace period.

   The label is laid out as a *fixed-width* slot regardless of how many
   dots are visible at the current animation frame. Without this fix
   the dots animation would push the progress bar back and forth as
   ".", "..", "..." cycle. */
.status-cell {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.processing-label {
  /* Reserve enough room for the longest label we ship ("Modo robusto"
     + 3 dots) so the slot width is constant. The dots animation lives
     inside the slot (see .processing-label__dots) so its width changes
     never push the row's progress bar around. */
  width: 115px;
  flex-shrink: 0;
  color: var(--primary);
  white-space: nowrap;
}

.processing-label--paused {
  color: var(--on-bg-muted);
}

/* The text itself plus a contained span that holds only the dots, so
   the dots can pulse without ever pushing the rest of the row around. */
.processing-label__dots {
  display: inline-block;
  width: 1.5em;
  text-align: left;
}

.processing-label__dots::after {
  content: "...";
  /* Linear timing because the keyframes themselves do the stepping
     (with plateaus). steps(4) doubled up with multi-keyframe plateaus
     made the animation visit unintended widths. */
  animation: dots 1.6s linear infinite;
  display: inline-block;
  width: 0;
  text-align: left;
  overflow: hidden;
  vertical-align: bottom;
}

.processing-label--paused .processing-label__dots::after {
  /* Stop the animation when paused; the label reads "En pausa" with
     no trailing dots. */
  content: "";
  animation: none;
}

.progress-bar {
  flex: 1;
  height: 4px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
  max-width: 120px;
}

.progress-bar__fill {
  height: 100%;
  background: var(--primary);
  transition: width 0.25s ease-out;
}


/* Cycle: "" → "." → ".." → "..." → "" → …
   Each plateau holds for 25% of the cycle. We pin the width in
   absolute em values matched to our font's character width so the
   reveal lands on exact dot boundaries. Linear timing function (no
   `steps()`) because mixing `steps()` with multi-value keyframes is
   under-specified and renders inconsistently across engines. */
@keyframes dots {
  0%,  24% { width: 0;     }
  25%, 49% { width: 0.5em; }
  50%, 74% { width: 1em;   }
  75%, 100% { width: 1.5em; }
}

/* ============================================================
   Misc
   ============================================================ */

.center-loader {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-bg-muted);
  font-size: 14px;
}

.error-banner {
  background: rgba(208, 52, 44, 0.12);
  border: 1px solid rgba(208, 52, 44, 0.35);
  color: var(--danger);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  margin: var(--space-3) var(--space-4);
  font-size: 13px;
}

/* Hide scroll bars in a subtle way */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--on-bg-faint);
}
