/* ==========================================================================
   PodBridge — design tokens
   ========================================================================== */
:root {
  --bg: #f6f5f3;
  --bg-elevated: #ffffff;
  --bg-sunken: #edece8;
  --border: #e3e1db;
  --text: #1c1b19;
  --text-muted: #6b6862;
  --text-faint: #9a968d;

  --accent: #ff6b3d;       /* iVoox-ish warmth, but distinct */
  --accent-ink: #ffffff;
  --accent-soft: #ffe9df;
  --link: #d94f9c;         /* Pocket Casts-ish leg of the bridge */

  --success: #1f9d55;
  --success-soft: #e3f7ea;
  --danger: #d43d3d;
  --danger-soft: #fbe8e8;
  --originals: #7c4dff;
  --originals-soft: #efe8ff;
  --exclusive: #b8860b;
  --exclusive-soft: #fbf1da;

  --radius-s: 8px;
  --radius-m: 14px;
  --radius-l: 20px;
  --shadow-s: 0 1px 2px rgba(20, 18, 14, .06);
  --shadow-m: 0 8px 24px rgba(20, 18, 14, .08);
  --shadow-l: 0 20px 60px rgba(20, 18, 14, .18);

  --font-display: "Manrope", "Inter", system-ui, sans-serif;
  --font-body: "Inter", system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #15140f;
    --bg-elevated: #1e1c17;
    --bg-sunken: #100f0c;
    --border: #322f27;
    --text: #f3f1ec;
    --text-muted: #a7a297;
    --text-faint: #726e64;

    --accent: #ff7a4a;
    --accent-soft: #3a2115;
    --link: #ef7fbf;

    --success: #45c479;
    --success-soft: #10301e;
    --danger: #ff6161;
    --danger-soft: #3a1414;
    --originals: #a88bff;
    --originals-soft: #251c40;
    --exclusive: #e0b64d;
    --exclusive-soft: #392c10;

    --shadow-s: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-m: 0 8px 24px rgba(0, 0, 0, .35);
    --shadow-l: 0 20px 60px rgba(0, 0, 0, .55);
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}
img { max-width: 100%; display: block; }
button { font: inherit; }
code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  background: var(--bg-sunken);
  padding: .12em .4em;
  border-radius: 5px;
  font-size: .9em;
}

.app-shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 20px 24px 64px;
}

/* ===== Header ===== */
.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0 28px;
  gap: 12px;
}
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* El propio SVG del icono ya trae su fondo naranja y las esquinas
   redondeadas dibujadas — no hace falta recortarlo ni ponerle fondo aquí. */
.brand-mark { width: 44px; height: 44px; flex: none; display: block; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; font-family: var(--font-display); min-width: 0; }
.brand-text strong { font-size: 17px; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand-text span { font-size: 12.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.header-actions { display: flex; align-items: center; gap: 10px; flex: none; }

.pc-status {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 14px 7px 10px;
  font-size: 13px;
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
  min-width: 0; /* deja que el label de dentro se pueda truncar en vez de desbordar */
}
.pc-status span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pc-status:hover { border-color: var(--accent); color: var(--text); }
.pc-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); flex: none; }
.pc-dot[data-state="connected"] { background: var(--success); box-shadow: 0 0 0 3px var(--success-soft); }
.pc-dot[data-state="connecting"] { background: var(--exclusive); animation: pulse 1.1s ease-in-out infinite; }
.pc-dot[data-state="error"] { background: var(--danger); }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* La pastilla de estado ya no abre Ajustes (eso es lo que hace el
   engranaje de al lado, y hacer lo mismo dos veces era redundante):
   ahora solo enseña un resumen genérico y, al pasar el ratón o pulsar,
   un detalle del Worker y de Pocket Casts por separado. */
.pc-status-wrap, .jobs-status-wrap { position: relative; }
.status-tooltip {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 260px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-m);
  padding: 12px;
  display: none;
  flex-direction: column;
  gap: 10px;
  z-index: 30;
}
.pc-status-wrap:hover .status-tooltip,
.pc-status-wrap:focus-within .status-tooltip,
.jobs-status-wrap:hover .status-tooltip,
.jobs-status-wrap:focus-within .status-tooltip,
.status-tooltip.is-open {
  display: flex;
}
.status-tooltip-row { display: flex; align-items: flex-start; gap: 8px; }
.status-tooltip-row .pc-dot { margin-top: 5px; }
.status-tooltip-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--text-faint); margin: 0; }
.status-tooltip-text { font-size: 13px; margin: 2px 0 0; word-break: break-word; }

/* Indicador de descargas/subidas en curso — mismo patrón que el de
   conexión (pastilla + tooltip al hover/click), pero con una lista de
   episodios y su progreso individual en vez de dos líneas fijas. */
.jobs-status.pc-status { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.jobs-status .spinner { color: var(--accent); }
.jobs-tooltip { width: 280px; max-height: 320px; overflow-y: auto; }
.jobs-tooltip-empty { font-size: 13px; color: var(--text-muted); margin: 0; }
.jobs-tooltip-list { display: flex; flex-direction: column; gap: 10px; }
.job-row-title {
  font-size: 13px; font-weight: 700; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.job-row-status { font-size: 12px; color: var(--text-muted); margin: 2px 0 4px; }
.job-row-bar { height: 4px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; }
.job-row-bar-fill { height: 100%; border-radius: inherit; background: var(--accent); transition: width .2s ease; }
.job-row-bar-fill.is-indeterminate {
  width: 40%;
  animation: indeterminate-sweep 1.3s ease-in-out infinite;
}
@keyframes indeterminate-sweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

.icon-btn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, transform .15s ease;
}
.icon-btn:hover { color: var(--text); border-color: var(--accent); transform: rotate(20deg); }

/* ===== Hero / search ===== */
.hero { text-align: center; padding: 36px 0 32px; }
.hero h1 {
  font-family: var(--font-display);
  font-size: clamp(24px, 4vw, 34px);
  font-weight: 800;
  letter-spacing: -.02em;
  max-width: 640px;
  margin: 0 auto 10px;
}
.hero-sub { color: var(--text-muted); max-width: 520px; margin: 0 auto 28px; font-size: 15px; }

.search-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  align-items: center;
}
.search-type {
  display: inline-flex;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.chip {
  border: none;
  background: transparent;
  color: var(--text-muted);
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 13.5px;
  font-weight: 600;
  transition: background .15s ease, color .15s ease;
}
.chip.is-active { background: var(--bg-elevated); color: var(--text); box-shadow: var(--shadow-s); }

.search-input-wrap,
.program-episode-search {
  position: relative;
  flex: 1 1 320px;
}
.search-input-wrap { max-width: 420px; }
.search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-faint); }

/* El buscador de dentro de un programa ocupa el ancho entero, a diferencia
   del de la portada, que va acotado junto a las pestañas. */
.program-episode-search { margin-bottom: 18px; }
.program-episode-search input {
  width: 100%;
  padding: 10px 14px 10px 40px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  font-size: 13.5px;
}
.program-episode-search input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
#search-input {
  width: 100%;
  padding: 12px 14px 12px 42px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  font-size: 15px;
}
#search-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.btn {
  border-radius: 999px;
  border: 1px solid transparent;
  padding: 12px 22px;
  font-weight: 700;
  font-size: 14.5px;
  cursor: pointer;
  transition: transform .12s ease, background .15s ease, border-color .15s ease, opacity .15s ease;
  white-space: nowrap;
}
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .55; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
.btn-secondary { background: var(--bg-sunken); color: var(--text); border-color: var(--border); }
.btn-secondary:hover:not(:disabled) { border-color: var(--accent); }
.btn-ghost { background: transparent; color: var(--text-muted); border-color: var(--border); }
.btn-ghost:hover:not(:disabled) { color: var(--text); border-color: var(--text-faint); }
.btn-sm { padding: 8px 14px; font-size: 13px; }

/* ===== State blocks (idle / empty / error / loading) ===== */
.state-block {
  text-align: center;
  padding: 56px 20px;
  color: var(--text-muted);
}
.state-icon { font-size: 40px; margin-bottom: 12px; }
.state-block h2 { font-family: var(--font-display); font-size: 19px; color: var(--text); margin: 0 0 8px; }
.state-block p { max-width: 420px; margin: 0 auto; font-size: 14px; }
.state-block[data-tone="error"] .state-icon { filter: saturate(1.4); }
.state-block .btn { margin-top: 18px; }

/* ===== Results grid ===== */
.results { min-height: 40vh; }
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Program card */
.program-card {
  position: relative;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.program-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-m); border-color: var(--accent); }
.program-card-open {
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: inherit;
  font: inherit;
}
.favorite-btn {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg-elevated) 85%, transparent);
  backdrop-filter: blur(3px);
  color: var(--text-faint);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, transform .1s ease;
}
.favorite-btn:hover { color: var(--danger); border-color: var(--danger); transform: scale(1.08); }
.favorite-btn.is-favorite { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.favorite-btn.is-favorite svg { fill: currentColor; }
.program-cover {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-s);
  overflow: hidden;
  background: var(--bg-sunken);
}
.program-cover img { width: 100%; height: 100%; object-fit: cover; }
.program-info { display: flex; flex-direction: column; gap: 4px; }
.program-title { font-family: var(--font-display); font-size: 14.5px; font-weight: 700; margin: 0; line-clamp: 2; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.program-badges { margin: 0; }
.program-author {
  font-size: 12.5px; color: var(--text-muted); margin: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Episode card (search results) */
.episode-card {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 14px;
  align-items: center;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: 12px;
}
.episode-cover { width: 64px; height: 64px; border-radius: var(--radius-s); flex: none; }
.episode-body { min-width: 0; }
.episode-program { font-size: 11.5px; color: var(--text-faint); margin: 0 0 2px; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; }
.episode-title { font-family: var(--font-display); font-size: 14.5px; font-weight: 700; margin: 0 0 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.episode-meta { font-size: 12.5px; color: var(--text-muted); margin: 0; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.tag-exclusive {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--exclusive); background: var(--exclusive-soft);
  border-radius: 999px; padding: 2px 8px; font-weight: 700; font-size: 11px;
}
.tag-original { color: var(--originals); background: var(--originals-soft); border-radius: 999px; padding: 2px 8px; font-weight: 700; font-size: 11px; }

.episode-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.action-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  color: var(--text);
  /* Ancho mínimo fijo: el texto cambia ("Descargar y subir" → "Subiendo…
     100%" → "✓ En Pocket Casts"...) y sin esto el botón de +info de al
     lado se desplazaba cada vez que cambiaba el estado. */
  min-width: 176px;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.action-btn:hover:not(:disabled) { border-color: var(--accent); }
.action-btn:disabled { opacity: .5; cursor: not-allowed; }
.action-btn.is-locked { color: var(--text-faint); cursor: not-allowed; }
.action-btn.is-working { color: var(--accent); }
/* Al pasar el ratón, un job en marcha se puede cancelar pulsándolo — el
   cambio de color avisa de que el clic ya no es "descargar" sino
   "cancelar" (el texto exacto va en el title, más simple y accesible
   que sustituir el contenido por CSS). */
.action-btn.is-working:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }
.action-btn.is-done { color: var(--success); background: var(--success-soft); border-color: transparent; }
.action-btn.is-error { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.spinner {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ===== Program view (episode list) ===== */
.program-view { padding-top: 8px; }
.back-btn { margin-bottom: 18px; display: inline-flex; align-items: center; gap: 6px; }
.program-header {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  padding: 20px;
  margin-bottom: 24px;
}
.program-header img { width: 88px; height: 88px; border-radius: var(--radius-m); object-fit: cover; flex: none; }
.program-header-body { min-width: 0; display: flex; flex-direction: column; }
.program-header-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.program-header-title-row .favorite-btn { position: static; flex: none; }
.program-header h2 { font-family: var(--font-display); margin: 0 0 6px; font-size: 20px; }
.program-header-description {
  margin: 0 0 6px; color: var(--text-muted); font-size: 13.5px; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.program-header-description.is-expanded { -webkit-line-clamp: unset; overflow: visible; }
.program-header-footer {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
}
.read-more-btn {
  background: none; border: none; padding: 0;
  font-size: 13px; font-weight: 700; color: var(--accent); cursor: pointer;
}
.read-more-btn:hover { text-decoration: underline; }
.program-header-link {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: auto; /* al final de la fila aunque el botón "Leer más" esté oculto */
  font-size: 13px; font-weight: 700; color: var(--accent);
  text-decoration: none;
}
.program-header-link:hover { text-decoration: underline; }

.episode-list { display: flex; flex-direction: column; gap: 10px; }
.load-more-sentinel {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px;
  color: var(--text-muted);
  font-size: 13px;
}
.episode-row, .program-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: 14px 16px;
}
.episode-row-cover { width: 56px; height: 56px; border-radius: var(--radius-s); flex: none; }
.episode-row-main { min-width: 0; flex: 1; }
.episode-row .episode-title { white-space: normal; font-size: 14px; }

/* Fila de programa (pestaña Favoritos) — misma altura compacta que
   .episode-row, con el botón de favorito fuera del flujo absoluto que
   usa en la tarjeta grande (aquí no hay portada grande sobre la que
   flotar). */
.program-row-open {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  min-width: 0;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.program-row .program-title { font-size: 14px; -webkit-line-clamp: 1; }
.program-row .program-author { -webkit-line-clamp: 1; }
.program-row .program-badges { margin: 2px 0; }
.program-row .favorite-btn { position: static; flex: none; }

.info-btn {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.info-btn svg { display: block; }
.info-btn:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* ===== Skeletons ===== */
.skeleton-card { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.skeleton { background: linear-gradient(90deg, var(--bg-sunken) 25%, var(--border) 37%, var(--bg-sunken) 63%); background-size: 400% 100%; animation: shimmer 1.4s ease infinite; border-radius: var(--radius-s); }
.skeleton-cover { aspect-ratio: 1/1; border-radius: var(--radius-s); }
.skeleton-line { height: 12px; border-radius: 6px; }

/* Misma forma que .episode-row — ver tpl-skeleton-row en index.html. */
.skeleton-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: 14px 16px;
}
.skeleton-row-cover { width: 56px; height: 56px; border-radius: var(--radius-s); flex: none; }
.skeleton-row-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* ===== Settings panel =====
   IMPORTANTE: estos overlays se muestran/ocultan con la clase .is-open, NO
   con el atributo `hidden`. Si alguna vez añades aquí una regla `display`
   incondicional en un selector que también pueda llevar `[hidden]`, el CSS
   de autor gana SIEMPRE sobre la hoja de estilos del user-agent y el
   `hidden` deja de tener efecto visual (aunque el DOM lo siga reflejando
   correctamente) — es justo el bug que tenía este panel antes. */
.backdrop {
  position: fixed; inset: 0;
  background: rgba(10, 9, 7, .45);
  backdrop-filter: blur(2px);
  z-index: 40;
  display: none;
}
.backdrop.is-open { display: block; }

.settings-panel {
  position: fixed;
  top: 0; right: 0;
  height: 100%;
  width: min(420px, 100%);
  background: var(--bg-elevated);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-l);
  z-index: 50;
  display: none;
  flex-direction: column;
}
.settings-panel.is-open { display: flex; animation: slide-in .22s ease; }
@keyframes slide-in { from { transform: translateX(24px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.settings-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.settings-head h2 { font-family: var(--font-display); font-size: 17px; margin: 0; }
.settings-body { padding: 18px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; background: var(--bg-sunken); }

/* Cada bloque de ajustes es una tarjeta propia — antes eran solo
   secciones separadas por espacio en blanco, que en una columna larga se
   veía como un totum revolutum sin jerarquía visual. */
.settings-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: 16px;
}
.settings-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.settings-card-icon {
  width: 26px; height: 26px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
}
.settings-card h3 { font-size: 14px; margin: 0; font-family: var(--font-display); }
.hint { font-size: 12.5px; color: var(--text-muted); margin: 0 0 14px; line-height: 1.5; }

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; font-size: 13px; font-weight: 600; }
.field input {
  padding: 10px 12px;
  border-radius: var(--radius-s);
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text);
  font-size: 14px;
  font-weight: 400;
}
.field input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.field-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.field-row + .field-row { margin-top: 10px; }

/* Botón del ojo para mostrar/ocultar contraseñas y secretos. */
.field-input-wrap { position: relative; }
.field-input-wrap input { width: 100%; padding-right: 38px; }
.field-toggle-visibility {
  position: absolute;
  right: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: none;
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  transition: color .15s ease;
}
.field-toggle-visibility:hover, .field-toggle-visibility:focus-visible { color: var(--accent); }
.field-status { font-size: 12.5px; color: var(--success); }

/* "Control de versiones" de exportar/importar — neutro normalmente, y en
   el mismo tono ámbar que el resto de avisos de "atención, no error"
   (p. ej. el badge de contenido exclusivo) cuando hay cambios sin
   exportar. */
.data-sync-status { font-size: 12.5px; color: var(--text-muted); margin: 0 0 12px; line-height: 1.5; }
.data-sync-status.is-attention { color: var(--exclusive); font-weight: 600; }

/* Alternativa manual a la descarga (ver downloadExportedFile en main.js):
   algunos WebViews que envuelven la web como app (Hermit y similares) no
   descargan blobs ni dan ningún error al fallar — este bloque es la vía
   de escape que siempre funciona, copiar y pegar a mano. Lo mismo en
   sentido contrario para importar: pegar en un textarea es pegado nativo
   del teclado, así que funciona igual en cualquier WebView. */
#export-fallback-toggle { margin-top: 10px; }
.export-fallback, .import-paste-box { margin-top: 10px; }
.data-io-textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-s);
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12px;
  line-height: 1.4;
  resize: vertical;
  margin-bottom: 10px;
}

/* Ficha de cuenta conectada: antes era una fila que envolvía mal con
   emails largos (el botón "Desconectar" quedaba flotando junto a la
   primera línea del email). Ahora es su propio bloque con el email en
   una columna que puede partirse limpiamente y el botón siempre
   alineado a la derecha, sin que se monten. */
.pc-account-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 10px 12px;
  margin-bottom: 14px;
}
.pc-account-card > div { min-width: 0; }
.pc-account-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--text-faint); margin: 0 0 2px; font-weight: 700; }
.pc-account-email { font-size: 13.5px; font-weight: 700; margin: 0; word-break: break-all; }

/* Interruptor tipo slider (no un checkbox nativo) */
.switch-field {
  display: flex; align-items: center; gap: 10px;
  margin: 10px 0 14px; font-size: 12.5px; font-weight: 400; color: var(--text-muted);
  cursor: pointer;
}
.switch { position: relative; flex: none; width: 38px; height: 22px; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.switch-track {
  position: absolute; inset: 0;
  background: var(--border);
  border-radius: 999px;
  transition: background .15s ease;
}
.switch-thumb {
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--shadow-s);
  transition: transform .15s ease;
}
.switch input:checked ~ .switch-track { background: var(--accent); }
.switch input:checked ~ .switch-track .switch-thumb { transform: translateX(16px); }
.switch input:focus-visible ~ .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

.hint-small { font-size: 12px; margin: 0; }
.worker-health { font-size: 12.5px; color: var(--text-faint); margin: 10px 0 0; }
.worker-health.is-ok { color: var(--success); }
.worker-health.is-error { color: var(--danger); }

.pc-usage { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.pc-usage-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--text-muted); margin-bottom: 6px; }
.pc-usage-row span:last-child { font-weight: 700; color: var(--text); }
.pc-usage-bar { height: 6px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; }
.pc-usage-bar-fill { height: 100%; border-radius: inherit; background: var(--accent); transition: width .3s ease; }
.pc-usage-bar-fill.is-full { background: var(--danger); }
.field-error {
  font-size: 12.5px; color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--radius-s);
  padding: 8px 10px;
  margin-top: 8px;
}

/* ===== Popup de episodio ===== */
.episode-modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - 32px));
  max-height: min(85vh, 720px);
  overflow-y: auto;
  background: var(--bg-elevated);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-l);
  z-index: 55;
  display: none;
  padding: 0 0 24px;
}
.episode-modal.is-open { display: block; animation: modal-in .18s ease; }
@keyframes modal-in { from { opacity: 0; transform: translate(-50%, -50%) scale(.97); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
.modal-close { position: absolute; top: 14px; right: 14px; background: var(--bg-elevated); z-index: 1; }
.episode-modal-body { display: flex; flex-direction: column; }
.episode-modal-cover { width: 100%; aspect-ratio: 16/7; object-fit: cover; background: var(--bg-sunken); border-radius: var(--radius-l) var(--radius-l) 0 0; }
.episode-modal-content { padding: 20px 24px 0; }
.episode-modal-program { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .03em; font-weight: 700; margin: 0 0 6px; }
.episode-modal-title { font-family: var(--font-display); font-size: 19px; font-weight: 800; margin: 0 0 10px; line-height: 1.3; }
.episode-modal-badges { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.episode-modal-meta { font-size: 13px; color: var(--text-muted); margin: 0 0 16px; display: flex; gap: 10px; flex-wrap: wrap; }
.episode-modal-description { font-size: 14px; line-height: 1.65; color: var(--text); white-space: pre-line; }
.episode-modal-description:empty::before,
.episode-modal-description.is-empty::before { content: "No hay descripción disponible para este episodio."; color: var(--text-faint); font-style: italic; }
.episode-modal-link { display: inline-flex; margin-top: 14px; }
.episode-modal-footer { padding: 20px 24px 0; }

/* ===== Toasts ===== */
.toasts {
  position: fixed;
  bottom: 20px; right: 20px;
  display: flex; flex-direction: column; gap: 10px;
  z-index: 60;
  max-width: min(360px, calc(100vw - 40px));
}
.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-s);
  padding: 12px 14px;
  box-shadow: var(--shadow-m);
  font-size: 13.5px;
  animation: toast-in .18s ease;
}
.toast-text { flex: 1; }
.toast-action {
  flex: none;
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.toast[data-tone="success"] { border-left-color: var(--success); }
.toast[data-tone="error"] { border-left-color: var(--danger); }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* ===== Footer ===== */
.app-footer { margin-top: 56px; text-align: center; color: var(--text-faint); font-size: 12px; padding-top: 20px; border-top: 1px solid var(--border); }
.app-footer p + p { margin-top: 8px; }
.app-footer a { color: var(--text-muted); }
.app-footer a:hover { color: var(--accent); }

/* ===== Responsive ===== */
@media (max-width: 640px) {
  .app-shell { padding: 16px 16px 48px; }

  .app-header { padding: 4px 0 20px; }
  .brand-text span { max-width: 38vw; }
  .pc-status span:last-child { max-width: 34vw; }

  /* En escritorio, cada tooltip se ancla a su propia pastilla (estrecha)
     con `right: 0` — en un móvil estrecho eso puede sacar la mitad del
     tooltip fuera de la pantalla por la izquierda, según en qué parte de
     la cabecera caiga esa pastilla en concreto. Se resuelve haciendo que
     el tooltip se ancle a toda la cabecera en vez de a la pastilla:
     quitarles `position: relative` a los envoltorios estrechos hace que
     el `position: absolute` del tooltip suba hasta el siguiente
     ancestro posicionado, que pasa a ser `.app-header` entero. */
  .app-header { position: relative; }
  .pc-status-wrap, .jobs-status-wrap { position: static; }
  .status-tooltip { left: 16px; right: 16px; width: auto; }
  .jobs-tooltip { width: auto; }

  .search-bar { gap: 8px; }

  .program-header { padding: 16px; gap: 14px; }
  .program-header img { width: 64px; height: 64px; }

  .episode-card {
    grid-template-columns: 64px 1fr;
    row-gap: 10px;
  }
  .episode-actions { grid-column: 1 / -1; justify-content: flex-end; }

  /* En vez de apilar imagen/título/acciones en columna (que separaba la
     portada del título en su propia línea), se deja en flex-wrap: la
     portada y el título se quedan juntos en la primera línea mientras
     quepan, y las acciones bajan enteras a la siguiente. */
  .episode-row { flex-wrap: wrap; row-gap: 10px; }
  .episode-row-main { flex-basis: 180px; }
  .episode-actions { flex-basis: 100%; justify-content: flex-end; }

  .action-btn { min-width: 150px; }

  .settings-panel { width: 100%; }
  .episode-modal-content { padding: 16px 16px 0; }
  .episode-modal-footer { padding: 16px 16px 0; }
}

@media (max-width: 480px) {
  .brand-text span { display: none; } /* con tan poco ancho, el subtítulo sobra */
  .pc-status span:last-child { max-width: 30vw; }

  .program-header { flex-direction: column; }
  .program-header img { width: 56px; height: 56px; }
  .program-header-link { margin-top: 8px; }
}
