/*
  siphon — mobile first.

  Design notes, so the next edit doesn't undo the reasoning:

  TYPE: no webfont. This is a utility people open on mobile data, often to grab
  one thing quickly; a blocking font request to buy a slightly nicer heading is
  a bad trade, and the service worker would have to cache a third-party origin
  to keep it offline. Hierarchy comes from scale, weight and spacing instead,
  and every *value* — speed, size, ETA, the resolved filename — is set in
  monospace. That split is true to the subject: yt-dlp is a terminal tool, and
  its numbers should read like output.

  COLOR: dark-first, because this is a media tool and most phones are OLED. The
  neutrals carry a slight cyan bias so they sit in the same family as the mint
  accent rather than looking like untinted grey. Mint is the only saturated
  colour on the page; red and amber are reserved for failure and warning, so
  they always mean something.

  LAYOUT: one column, 34rem cap, thumb-reachable. The URL field is the hero.
  The primary button is replaced in place by the progress readout, so the eye
  never has to hunt for where the state went.
*/

:root {
  color-scheme: dark;

  --ground: #0e1315;
  --surface: #151c1f;
  --surface-2: #1c2428;
  --raised: #232d31;
  --line: #2a353a;
  --line-soft: #202a2e;

  --ink: #e9eff1;
  --ink-2: #b3c0c4;
  --muted: #7f8f95;

  --accent: #5ee0c5;
  --accent-ink: #052420;
  --accent-dim: #2a7d6d;
  --accent-wash: rgba(94, 224, 197, 0.12);

  --danger: #ff6b6b;
  --danger-wash: rgba(255, 107, 107, 0.12);
  --warn: #ffc861;

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

  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;

  /* Safe areas: the action bar sits at the bottom on phones, where the home
     indicator and the URL bar both live. */
  --safe-b: env(safe-area-inset-bottom, 0px);
}

:root[data-theme="light"] {
  color-scheme: light;
  --ground: #f2f5f5;
  --surface: #ffffff;
  --surface-2: #f6f9f9;
  --raised: #eaf0f0;
  --line: #d5e0e0;
  --line-soft: #e6eded;
  --ink: #10191b;
  --ink-2: #3c4a4d;
  --muted: #66777b;
  --accent: #0f9a80;
  --accent-ink: #ffffff;
  --accent-dim: #8fd6c8;
  --accent-wash: rgba(15, 154, 128, 0.1);
  --danger: #c93434;
  --danger-wash: rgba(201, 52, 52, 0.09);
  --warn: #a06a00;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --ground: #f2f5f5;
    --surface: #ffffff;
    --surface-2: #f6f9f9;
    --raised: #eaf0f0;
    --line: #d5e0e0;
    --line-soft: #e6eded;
    --ink: #10191b;
    --ink-2: #3c4a4d;
    --muted: #66777b;
    --accent: #0f9a80;
    --accent-ink: #ffffff;
    --accent-dim: #8fd6c8;
    --accent-wash: rgba(15, 154, 128, 0.1);
    --danger: #c93434;
    --danger-wash: rgba(201, 52, 52, 0.09);
    --warn: #a06a00;
  }
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--ground);
  color: var(--ink);
  font: 16px/1.5 var(--sans);
  /* Stops the pull-to-refresh bounce from fighting the sticky action bar. */
  overscroll-behavior-y: contain;
}

a { color: var(--accent); text-underline-offset: 2px; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

.shell {
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
  padding: 0 16px;
  /* Room for the fixed action bar plus the phone's own chrome. */
  padding-bottom: calc(124px + var(--safe-b));
}

/* ------------------------------------------------------------------ header */

.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-block: 18px 14px;
}

.mark {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-right: auto;
  min-width: 0;
}

.mark svg { flex: none; }

.mark-text { min-width: 0; }

.mark-name {
  display: block;
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.015em;
  line-height: 1.15;
}

.mark-sub {
  display: block;
  font: 500 11px/1.3 var(--mono);
  color: var(--muted);
  letter-spacing: 0.03em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  flex: none;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  cursor: pointer;
}
.icon-btn:active { background: var(--raised); }

/* --------------------------------------------------------------- url field */

.field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 6px 6px 6px 14px;
}
.field:focus-within { border-color: var(--accent); }

.field input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  padding: 12px 0;
  /* 16px minimum or iOS Safari zooms the whole page on focus. */
  font-size: 16px;
  font-family: var(--mono);
}
.field input::placeholder { color: var(--muted); font-family: var(--sans); }
.field input:focus { outline: none; }

.chip-btn {
  flex: none;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink-2);
  border-radius: var(--r-sm);
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  min-height: 40px;
}
.chip-btn:active { background: var(--raised); }

/* ------------------------------------------------------------------ result */

.preview {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px;
  margin-top: 12px;
}

.preview img {
  flex: none;
  width: 104px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--r-sm);
  background: var(--raised);
  max-width: 100%;
}

.preview-body { min-width: 0; flex: 1; }

.preview-title {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 4px;
  /* Two lines then ellipsis: titles get long and this card must not grow
     tall enough to push the quality row off a small screen. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.preview-meta {
  margin: 0;
  font: 500 12px/1.45 var(--mono);
  color: var(--muted);
  word-break: break-word;
}

.skeleton {
  background: linear-gradient(90deg, var(--raised) 25%, var(--surface-2) 50%, var(--raised) 75%);
  background-size: 200% 100%;
  border-radius: 6px;
  color: transparent;
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: shimmer 1.3s ease-in-out infinite; }
  @keyframes shimmer { to { background-position: -200% 0; } }
}

/* ---------------------------------------------------------------- quality */

.section-label {
  display: block;
  font: 600 11px/1 var(--mono);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 22px 0 9px;
}

.qualities {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px;
}

.quality { position: relative; }
.quality input {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.quality span {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 58px;
  padding: 8px 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  text-align: center;
}
.quality b { font-size: 14px; font-weight: 650; line-height: 1.2; }
.quality small { font: 500 10.5px/1.2 var(--mono); color: var(--muted); letter-spacing: 0.02em; }
.quality input:checked + span {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.quality input:checked + span b { color: var(--accent); }
.quality input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------- action bar */

.actionbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  padding: 12px 16px calc(12px + var(--safe-b));
  background: color-mix(in srgb, var(--ground) 88%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--line-soft);
}

.actionbar-inner { width: 100%; max-width: 34rem; margin: 0 auto; }

.btn-go {
  width: 100%;
  min-height: 54px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.btn-go:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-go:not(:disabled):active { transform: translateY(1px); }

/* --------------------------------------------------------------- progress */

.progress {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px 14px;
}

.progress-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 9px;
}

.progress-stage { font-size: 14px; font-weight: 600; }

.progress-pct {
  margin-left: auto;
  font: 650 14px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.bar {
  height: 7px;
  border-radius: 999px;
  background: var(--raised);
  overflow: hidden;
}
.bar-fill {
  height: 100%;
  width: 0%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 0.25s ease;
}
/* Unknown total: the server is working but cannot say how far along. */
.bar-fill.indeterminate {
  width: 35%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .bar-fill.indeterminate { animation: slide 1.1s ease-in-out infinite; }
  @keyframes slide { from { transform: translateX(-100%); } to { transform: translateX(340%); } }
}
@media (prefers-reduced-motion: reduce) {
  .bar-fill { transition: none; }
}

.progress-foot {
  display: flex;
  gap: 12px;
  margin: 9px 0 0;
  font: 500 12px/1.3 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.progress-foot .cancel {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  font: inherit;
}

/* ----------------------------------------------------------------- notices */

.notice {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: 14px;
  line-height: 1.45;
}
.notice.error { border-color: var(--danger); background: var(--danger-wash); }
.field-error { margin: 6px 0 0; font-size: 12.5px; line-height: 1.4; color: var(--danger); }
.notice.error strong { color: var(--danger); }
.notice p { margin: 0; }
.notice p + p { margin-top: 6px; }
.notice .retry {
  margin-top: 10px;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  min-height: 38px;
}

/* ----------------------------------------------------------------- history */

.history { margin-top: 26px; }
.history ol {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 8px;
  /* A track that may shrink. An auto one grows to a row's longest unbroken
     line — a row is titled with its link until a title arrives — and takes
     the page, and the row's buttons, past the edge of a phone. */
  grid-template-columns: minmax(0, 1fr);
}
.history li {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  padding: 10px 12px;
}
.history .h-body { min-width: 0; flex: 1; }
.history .h-title {
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.history .h-meta { font: 500 11px/1.3 var(--mono); color: var(--muted); }
.history .h-save {
  flex: none;
  border: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 8px 11px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  min-height: 38px;
  text-decoration: none;
  color: var(--ink);
  display: grid;
  place-items: center;
}

/* ---------------------------------------------------------------- settings */

dialog.sheet {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 100%;
  max-height: 100%;
  width: 100%;
  margin: auto auto 0;
}
dialog.sheet::backdrop { background: rgba(0, 0, 0, 0.55); }

.sheet-inner {
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: 18px 18px calc(20px + var(--safe-b));
  max-width: 34rem;
  margin: 0 auto;
  max-height: 86dvh;
  overflow-y: auto;
}
@media (min-width: 560px) {
  dialog.sheet { margin: auto; }
  .sheet-inner { border-radius: var(--r-lg); border-bottom: 1px solid var(--line); }
}

.sheet-head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.sheet-head h2 { margin: 0; font-size: 1.05rem; margin-right: auto; }

.sheet p.explain { color: var(--ink-2); font-size: 13.5px; margin: 6px 0 16px; }

.sheet label.lbl { display: block; font-size: 12.5px; font-weight: 650; margin: 14px 0 5px; }
.sheet input[type="text"], .sheet input[type="password"], .sheet input[type="url"] {
  width: 100%;
  padding: 12px;
  font-size: 16px;
  font-family: var(--mono);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.sheet .hint { font-size: 12.5px; color: var(--muted); margin: 6px 0 0; line-height: 1.45; }

.status-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  font: 500 12.5px/1.4 var(--mono);
  color: var(--muted);
}
.dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); flex: none; }
.dot.ok { background: var(--accent); }
.dot.bad { background: var(--danger); }
.dot.warn { background: var(--warn); }

.sheet-actions { display: flex; gap: 8px; margin-top: 18px; }
.sheet-actions button {
  flex: 1;
  min-height: 48px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-weight: 650;
  cursor: pointer;
}
.sheet-actions .primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }

footer.legal {
  margin-top: 30px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.5;
}
footer.legal p { margin: 0 0 7px; }

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

[hidden] { display: none !important; }

/* ------------------------------------------------------------ install cta */

.install-cta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 24px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-sm);
  background: var(--surface);
}
.install-cta > div { flex: 1; min-width: 0; }
.install-cta strong { display: block; font-size: 13.5px; }
.install-cta p { margin: 3px 0 0; font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.install-cta #installDismiss { padding: 9px 11px; }

/* The guide. */
.tour {
  margin-top: 16px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: 13.5px;
  line-height: 1.45;
}
.tour-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tour-head strong { font-size: 14.5px; }
.tour-head .chip-btn { padding: 7px 10px; }
.tour-steps { margin: 10px 0 0; padding-left: 20px; }
.tour-steps li + li { margin-top: 6px; }
.tour-desktop { margin: 10px 0 0; color: var(--muted); font-size: 12.5px; }
.tour-desktop a { color: var(--accent); font-weight: 600; }
.tour-youtube { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.tour-youtube p { margin: 6px 0 0; }
.tour-youtube a { color: var(--accent); font-weight: 600; }
.tour-youtube code { display: inline-block; margin-top: 4px; padding: 2px 6px; border-radius: 6px; background: var(--raised); font-size: 12px; word-break: break-all; }
.tour-youtube .chip-btn { margin-left: 6px; padding: 5px 9px; font-size: 12px; }
.tour-owner { color: var(--muted); font-size: 12.5px; }

/* The finished file, when the platform will not take it automatically. */
.save-now {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
  min-height: 48px;
  border-radius: var(--r-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  text-decoration: none;
}

/* --------------------------------------------------------- segmented rows */

/*
  A row of mutually exclusive choices, for places where the full card grid used
  by Quality would be too heavy. The input is visually hidden but keeps its size
  and stays in the keyboard focus order: a display:none input is unreachable by
  keyboard, so it is made transparent and stretched over its label instead.
*/
.seg { display: flex; flex-wrap: wrap; gap: 7px; }
.seg label { position: relative; }
.seg input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.seg span {
  display: block;
  padding: 10px 14px;
  min-height: 40px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.45;
}
.seg input:checked + span {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
  font-weight: 650;
}
.seg input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------- playlists */

.playlist-choice {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}
.playlist-choice .seg span { padding: 6px 12px; }
.playlist-note {
  width: 100%;
  margin: 0;
  font: 500 11.5px/1.4 var(--mono);
  color: var(--muted);
}

/* ----------------------------------------------------------------- queue */

/*
  One row per download. Paste, tap, paste again — the row is what makes that
  safe, because you can see the first one still running while you queue the
  second. Rows stay put when they finish rather than moving, so the thing you
  were watching does not jump under your thumb.
*/
#queueList li {
  display: block;
  padding: 11px 12px;
}
.q-top { display: flex; align-items: baseline; gap: 8px; }
.q-title {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.q-pct {
  font: 650 12px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  flex: none;
}
.q-bar {
  height: 4px;
  border-radius: 999px;
  background: var(--raised);
  overflow: hidden;
  margin-top: 8px;
}
.q-fill { height: 100%; width: 0; background: var(--accent); border-radius: inherit; transition: width .25s ease; }
.q-fill.indeterminate { width: 35%; background: linear-gradient(90deg, transparent, var(--accent), transparent); }
@media (prefers-reduced-motion: no-preference) {
  .q-fill.indeterminate { animation: slide 1.1s ease-in-out infinite; }
}
.q-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  font: 500 11.5px/1.3 var(--mono);
  color: var(--muted);
}
.q-foot .spacer { margin-left: auto; }
.q-act {
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink);
  border-radius: 8px;
  padding: 7px 11px;
  font: 600 12px/1 var(--sans);
  cursor: pointer;
  min-height: 34px;
  text-decoration: none;
  display: grid;
  place-items: center;
  flex: none;
}
.q-act.primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
li.q-error { border-color: var(--danger); background: var(--danger-wash); }
li.q-error .q-msg { color: var(--danger); }
/* An error can quote a link, and a filename can be one long word. */
.q-msg { font-size: 12px; line-height: 1.45; margin-top: 6px; color: var(--ink-2); overflow-wrap: anywhere; }

/* The yt-dlp options apply to your own server; with any other helper they
   wait, greyed but kept, rather than vanish. */
#ytdlpBlock.off { opacity: 0.45; pointer-events: none; }
#ytdlpBlock select { width: 100%; padding: 10px 12px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface-2); color: var(--ink); font: inherit; }
