/* ------------------------------------------------------------------ *
 * grabr — design tokens
 *
 * "Honest tool" aesthetic. Workshop, not SaaS pitch deck.
 * - Amber on warm black
 * - Serif headlines (Fraunces), sans body (Inter), mono for inputs (JetBrains Mono)
 * - 1px borders, no shadows, no rounded corners
 * - Real-feeling ads (paper-cream) instead of generic purple boxes
 * ------------------------------------------------------------------ */

:root {
  --bg:           #0a0a0a;
  --bg-2:         #131311;
  --bg-3:         #1c1c1a;
  --bg-paper:     #f1e8d6;   /* warm cream for ad slots */
  --border:       #2a2a28;
  --border-strong: #3a3a37;
  --text:         #f0ebde;
  --text-dim:     #9b968a;
  --text-mute:    #6a665b;
  --text-paper:   #1a1814;  /* dark text on paper-cream ad */

  --accent:       #ff6b35;  /* amber */
  --accent-2:     #e85a26;  /* hover */
  --accent-soft:  rgba(255, 107, 53, 0.12);
  --success:      #5fb37e;
  --danger:       #ff5d6c;

  --radius:       0;        /* sharp corners, brutalist */
  --radius-sm:    0;

  --font-serif:   'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
}

html {
  color-scheme: dark;        /* forces the native <select> dropdown
                                to render in dark mode (Chrome/Edge) */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

::selection { background: var(--accent); color: var(--bg); }

/* Global safety net: any element with the HTML `hidden` attribute is
   *meant* to be invisible. CSS `display: flex/grid/block` rules on
   specific classes would normally override the user-agent's
   `display: none` for [hidden], so we re-assert it with !important
   to make the contract work as documented. */
[hidden] { display: none !important; }

.wrap { max-width: 980px; margin: 0 auto; padding: 0 28px; }

/* ------------------------------------------------------------------ *
 * Topbar
 * Thin. No box-shadow. Brand mark is a hand-drawn download arrow.    */

.topbar {
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.topbar__inner {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  min-width: 0;
  justify-content: space-between;
  gap: 12px;
  height: 56px;
}
.brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;                 /* never let the brand be squished */
  gap: 8px;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.02em;
}
.brand:hover { color: var(--text); text-decoration: none; }
.brand__mark {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  color: var(--accent);
}
.brand__mark svg { width: 100%; height: 100%; }
.nav {
  display: flex;
  align-items: center;
  gap: 22px;
  /* nowrap: nav items must stay on one line. The mobile breakpoint at
     1024px hides this whole nav into a drawer, so this only ever needs
     to fit on viewports >= 1024px. flex-wrap: wrap was letting items
     drop to a second line, which ballooned the topbar to ~120px tall. */
  flex-wrap: nowrap;
  flex-shrink: 0;
  /* Reset all padding/margin on the desktop nav so the @supports iOS
     safe-area rule below doesn't accidentally inflate the nav's height
     to 68px+ on desktop viewports. That bug made the inline nav overflow
     above and below the topbar (it was centered in 56px but ~114px tall),
     so the LIFETIME badge was the only item still partially visible. */
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  min-width: 0;
}
.nav > * { flex-shrink: 0; }
.nav a {
  color: var(--text-dim);
  font-size: 14px;
  font-weight: 500;
}
.nav a:hover { color: var(--text); text-decoration: none; }
.nav__form { margin: 0; }
.nav__form .btn { padding: 6px 14px; font-size: 13px; }

.badge {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid var(--border-strong);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--bg-2);
}
.badge--lifetime {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}
.badge--monthly {
  color: var(--accent);
  border-color: var(--accent);
  background: transparent;
}

/* ------------------------------------------------------------------ *
 * Main / Hero
 * Serif headline. Generous whitespace. No gradient buttons.         */

.main { padding: 48px 28px 80px; }

.hero { text-align: left; padding: 24px 0 32px; }
.hero h1 {
  font-family: var(--font-serif);
  font-size: clamp(36px, 6vw, 64px);
  line-height: 1.05;
  margin: 0 0 16px;
  letter-spacing: -0.025em;
  font-weight: 500;
  font-variation-settings: "opsz" 144;
}
.hero h1 em {
  font-style: italic;
  color: var(--accent);
  font-weight: 500;
}
.hero__sub {
  color: var(--text-dim);
  margin: 0 0 36px;
  max-width: 580px;
  font-size: 16px;
  line-height: 1.6;
}
.hero--small { padding: 12px 0 16px; }
.hero--small h1 { font-size: 32px; }
.center { text-align: center; }

/* ------------------------------------------------------------------ *
 * Command bar (the main download form)
 * Looks like a terminal input. Mono font. Single line. Brutalist.    */

.cmd {
  display: flex;
  align-items: stretch;
  background: var(--bg-2);
  border: 1px solid var(--border-strong);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 15px;
  max-width: 720px;
  position: relative;
  transition: border-color 0.12s;
}
.cmd:focus-within { border-color: var(--accent); }
.cmd__platform {
  position: relative;          /* scopes the absolute select to just the chip */
  display: flex;
  align-items: center;
  padding: 0 16px;
  background: var(--bg-3);
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color 0.12s;
  flex-shrink: 0;              /* never let the chip get squished */
}
.cmd__platform:hover { color: var(--text); }
.cmd__platform::after {
  content: "▾";
  margin-left: 8px;
  color: var(--text-mute);
  font-size: 10px;
}
/* Smaller secondary chip — used for format (MP4/MP3) + quality (BEST/1080p/…) */
.cmd__chip {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 12px;
  background: var(--bg-3);
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color 0.12s;
  flex-shrink: 0;
}
.cmd__chip:hover { color: var(--text); }
.cmd__chip::after {
  content: "▾";
  margin-left: 6px;
  color: var(--text-mute);
  font-size: 9px;
}
.cmd__chip select {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding: 0;
  margin: 0;
  z-index: 1;
}
.cmd__chip select option {
  background: var(--bg-2);
  color: var(--text);
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 13px;
  text-transform: none;
  letter-spacing: normal;
}
.cmd__chip select option:checked {
  background: var(--accent) !important;
  color: var(--bg) !important;
  font-weight: 600;
}
.cmd__platform select {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding: 0;
  margin: 0;
  z-index: 1;                  /* below the input — input sits on top */
}
/* Style the native dropdown popover.
   Chrome/Edge honor color-scheme: dark + these option rules.
   Firefox/Safari fall back to native (acceptable for v1). */
.cmd__platform select option {
  background: var(--bg-2);
  color: var(--text);
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 13px;
  text-transform: none;
  letter-spacing: normal;
}
.cmd__platform select option:checked {
  background: var(--accent) !important;
  color: var(--bg) !important;
  font-weight: 600;
}
.cmd__platform--auto::before {
  content: "AUTO";
  color: var(--accent);
  margin-right: 6px;
  font-weight: 700;
}
.cmd__input {
  flex: 1;
  position: relative;          /* sit above the platform <select> */
  z-index: 3;                  /* so clicks land on the input, not the select */
  background: transparent;
  border: 0;
  color: var(--text);
  padding: 16px 18px;
  font: inherit;
  outline: 0;
  min-width: 0;
}
.cmd__input::placeholder { color: var(--text-mute); }
.cmd__go {
  padding: 0 22px;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 110px;
  justify-content: center;
  transition: background 0.1s;
}
.cmd__go:hover { background: var(--accent-2); }
.cmd__go:disabled { opacity: 0.5; cursor: not-allowed; }
.cmd__go svg { width: 14px; height: 14px; }

.cmd__meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 720px;
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--text-mute);
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}
.cmd__meta a,
.cmd__meta button,
.cmd__meta__link {
  color: var(--text-dim);
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px dotted var(--text-mute) !important;
  padding: 0 !important;
  margin: 0 !important;
  font: inherit !important;
  font-family: var(--font-mono) !important;
  letter-spacing: inherit !important;
  text-align: left;
  text-transform: none;
  text-decoration: none;
  box-shadow: none !important;
  text-shadow: none !important;
  border-radius: 0 !important;
  appearance: none !important;
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  cursor: pointer;
  line-height: 1.4;
}
.cmd__meta a:hover,
.cmd__meta button:hover,
.cmd__meta__link:hover {
  color: var(--accent);
  text-decoration: none;
  border-color: var(--accent) !important;
}

/* Preview card (after typing a URL — shows title + thumbnail) */
.preview {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 720px;
  margin: 18px 0 0;
  padding: 12px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 13px;
}
/* The HTML `hidden` attribute is normally equivalent to `display: none`,
   but our `.preview { display: flex }` rule overrides that. This explicit
   selector restores the expected behaviour so a preview card with
   `hidden` actually stays hidden until JS unhides it. */
.preview[hidden] { display: none; }
.preview__thumb {
  width: 56px;
  height: 56px;
  object-fit: cover;
  flex-shrink: 0;
}
.preview__meta { display: flex; flex-direction: column; min-width: 0; }
.preview__meta strong {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
}
.preview__sub { color: var(--text-mute); font-size: 11px; margin-top: 2px; }

/* Playlist preview — same shell as .preview but stacked (no thumb) and
   with a teaser list + cap hint. The amber left-bar says "this is a
   playlist, not a single video" so the user doesn't accidentally hit
   the regular Download button. */
.preview--playlist {
  align-items: flex-start;
  border-left: 3px solid var(--accent, #ff6b35);
  padding-left: 14px;
}
.preview--playlist .preview__meta { flex: 1; }
.playlist-items {
  list-style: none;
  padding: 8px 0 0;
  margin: 0;
  font-size: 12px;
  color: var(--text-mute);
  max-height: 110px;
  overflow: hidden;
  position: relative;
  width: 100%;
}
.playlist-items li {
  padding: 2px 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* display:block + max-width:100% is required for the ellipsis to work
     inside a flex container — without it the li inherits min-content
     width from its text and the parent can let the line wrap mid-word. */
  display: block;
  max-width: 100%;
}
.playlist-items li.muted { font-style: italic; }
.playlist-items::after {
  /* Fade-out at the bottom so the truncation feels intentional. */
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 28px;
  background: linear-gradient(to bottom, transparent, var(--bg, #1a1410));
  pointer-events: none;
}

/* Bulk sheet — slides down when the "paste multiple" link is clicked */
.bulk-sheet {
  max-width: 720px;
  margin: 14px 0 0;
  background: var(--bg-2);
  border: 1px solid var(--border-strong);
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.25s ease;
}
.bulk-sheet.is-open { max-height: 600px; }
.bulk-sheet__inner {
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bulk-sheet textarea {
  width: 100%;
  min-height: 120px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.7;
  resize: vertical;
  outline: 0;
}
.bulk-sheet textarea:focus { border-color: var(--accent); }
.bulk-sheet__bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--text-mute);
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}
.bulk-sheet__bar strong { color: var(--text); }
.bulk-sheet__bar strong.over { color: var(--danger); }

/* Status / progress message */
.status {
  max-width: 720px;
  margin: 18px 0 0;
  padding: 12px 16px;
  border: 1px solid var(--border);
  font-size: 13px;
  font-family: var(--font-mono);
  background: var(--bg-2);
  color: var(--text-dim);
}
.status--ok    { border-color: var(--success); color: var(--success); }
.status--err   { border-color: var(--danger);  color: var(--danger); }

/* Ad slot — looks like a paper sticky-note. Self-aware. */
.ad {
  max-width: 720px;
  margin: 28px 0 0;
  background: var(--bg-paper) !important;   /* warm cream — make sure it shows */
  color: var(--text-paper) !important;
  border: 2px solid #c9b790 !important;     /* slightly darker cream border so the
                                              box is unmistakable against the page */
  padding: 16px 20px !important;
  display: flex !important;
  align-items: center;
  gap: 14px;
  font-size: 13px;
  position: relative;
  font-family: var(--font-sans);
  box-shadow: none;
}
.ad::before {
  content: "AD";
  position: absolute;
  top: -8px;
  left: 12px;
  background: var(--bg);
  color: var(--bg-paper);
  padding: 1px 6px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.1em;
  font-family: var(--font-mono);
}
.ad__body { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ad__body strong { font-weight: 700; }
.ad__body a {
  color: var(--text-paper);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}
.ad--banner { max-width: 980px; margin: 0 auto 0; }

/* Inline "see plans" link on the ad */
.ad__plans { margin-left: auto; }

/* Wait-time ad (the one that shows while a download is being prepared) */
.wait-ad {
  max-width: 720px;
  margin: 18px 0 0;
}
.wait-ad .ad { margin: 0; }

/* ------------------------------------------------------------------ *
 * Bulk results
 * List of per-file download links. Minimal.                            */

.bulk-results {
  max-width: 720px;
  margin: 20px 0 0;
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 16px 18px;
}
.bulk-results p { margin: 0 0 10px; }
.bulk-results__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bulk-results__list li {
  padding: 8px 0;
  border-top: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 13px;
}
.bulk-results__list li:first-child { border-top: 0; }
.bulk-results__list a {
  color: var(--text);
  text-decoration: none;
}
.bulk-results__list a:hover { color: var(--accent); }
.bulk-results__list--err li { color: var(--danger); font-size: 12px; }

/* ------------------------------------------------------------------ *
 * "Supported sites" — big brand chips, not bullets                    */

.sites {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}
.sites__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--text);
  font-family: var(--font-mono);
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: border-color 0.12s, background 0.12s;
}
.sites__chip:hover {
  border-color: var(--accent);
  background: var(--bg-3);
  text-decoration: none;
}
.sites__chip svg { width: 16px; height: 16px; flex-shrink: 0; }
.sites__chip--muted { color: var(--text-dim); }
.sites__note {
  margin: 18px 0 0;
  color: var(--text-mute);
  font-size: 13px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------------------ *
 * Cards (general)                                                      */

.card {
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 24px;
}
.card h2 {
  margin: 0 0 12px;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.01em;
}
.card p  { margin: 0 0 8px; color: var(--text-dim); }

.grid { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; margin-top: 32px; }
.grid--2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 720px) {
  .grid, .grid--2 { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ *
 * Buttons (general, used by auth pages + dashboard actions)            */

.btn {
  display: inline-block;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
  padding: 11px 18px;
  border: 1px solid var(--border-strong);
  background: var(--bg-2);
  color: var(--text);
  cursor: pointer;
  transition: background 0.1s, border-color 0.1s, transform 0.05s;
  text-decoration: none;
}
.btn:hover { background: var(--bg-3); border-color: var(--accent); text-decoration: none; }
.btn:active { transform: translate(1px, 1px); }
.btn--primary {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.btn--primary:hover { background: var(--accent-2); border-color: var(--accent-2); color: var(--bg); }
.btn--block { display: block; width: 100%; }
.btn--sm { padding: 6px 14px; font-size: 13px; }
.btn--ghost { background: transparent; border-color: var(--border); color: var(--text-dim); }

/* ------------------------------------------------------------------ *
 * Tables (dashboard, history)                                          */

.table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th, .table td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--border); }
.table th {
  color: var(--text-mute);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.truncate { max-width: 280px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ------------------------------------------------------------------ *
 * Auth pages (login, signup, account_delete)                          */

.auth { max-width: 380px; margin: 60px auto 0; }
.auth h1 {
  font-family: var(--font-serif);
  font-size: 32px;
  font-weight: 500;
  margin: 0 0 8px;
  letter-spacing: -0.02em;
}
.form { display: flex; flex-direction: column; gap: 14px; margin: 24px 0; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field span {
  font-size: 11px;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}
.field .input,
.field input[type="email"],
.field input[type="password"] {
  background: var(--bg-2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  padding: 11px 14px;
  font-family: var(--font-mono);
  font-size: 14px;
  outline: 0;
  transition: border-color 0.1s;
}
.field .input:focus { border-color: var(--accent); }
.alert {
  padding: 10px 14px;
  border: 1px solid var(--danger);
  color: var(--danger);
  background: rgba(255, 93, 108, 0.08);
  font-size: 13px;
  margin: 12px 0;
}
.center { text-align: center; }

/* ------------------------------------------------------------------ *
 * Demo banner (only shows when DB is SQLite)                           */

.demo-banner {
  margin: 12px auto;
  max-width: 980px;
  padding: 8px 18px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 12px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  text-align: center;
}
.demo-banner code {
  background: var(--bg-3);
  padding: 1px 6px;
  border: 1px solid var(--border);
  font-size: 11px;
}

/* ------------------------------------------------------------------ *
 * Pricing — tilted price-tag cards                                     */

.plans {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  margin: 32px 0 0;
  position: relative;
}
@media (max-width: 1100px) {
  .plans { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .plans { grid-template-columns: 1fr; }
}
.plan {
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 32px 24px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.plan + .plan { border-left: 0; }
.plan__tag {
  position: absolute;
  top: -10px;
  left: 16px;
  background: var(--accent);
  color: var(--bg);
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  font-family: var(--font-mono);
  text-transform: uppercase;
}
.plan__name {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
}
.plan__price {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 500;
  letter-spacing: -0.02em;
}
.plan__price .currency { font-size: 22px; color: var(--text-dim); font-weight: 400; }
.plan__price .amount   { font-size: 64px; line-height: 1; color: var(--text); }
.plan__price .period   { font-size: 13px; color: var(--text-mute); font-family: var(--font-mono); margin-left: 6px; }
./* "MOST POPULAR" card — brighter background only, no orange border.
   The orange is reserved for the .plan--current outline so the two
   signals (popular vs. current) read as distinct instead of identical. */
.plan--featured { background: var(--bg-3); z-index: 1; }
.plan--featured .amount { color: var(--accent); }
.plan--featured::after {
  content: "MOST POPULAR";
  position: absolute;
  top: 12px;
  right: 16px;
  font-size: 9px;
  font-weight: 800;
  color: var(--accent);
  letter-spacing: 0.12em;
  font-family: var(--font-mono);
}
.plan--best .plan__name::after {
  content: "★";
  color: var(--accent);
  margin-left: 6px;
}
.plan--current {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.plan--current .plan__name::before {
  content: "✓ Current plan · ";
  color: var(--accent);
  font-weight: 600;
}
.muted.small { font-size: 12px; }
.plan__list {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
  color: var(--text-dim);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.plan__list li {
  display: flex;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border);
}
.plan__list li:first-child { border-top: 0; }
.plan__list .yes { color: var(--success); font-family: var(--font-mono); }
.plan__list .no  { color: var(--text-mute); font-family: var(--font-mono); }
.plan__cta { margin-top: auto; }

/* ------------------------------------------------------------------ *
 * Dashboard — minimal, no chrome                                      */

.dash-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 24px 0 0;
}
@media (max-width: 720px) { .dash-grid { grid-template-columns: 1fr; } }
.stat {
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 20px 22px;
}
.stat__label {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  margin: 0 0 10px;
}
.stat__value {
  font-family: var(--font-serif);
  font-size: 36px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.02em;
  line-height: 1;
}
.stat__sub {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--text-mute);
  font-family: var(--font-mono);
}
.stat--accent .stat__value { color: var(--accent); }
.stat--danger .stat__value { color: var(--danger); }

.muted { color: var(--text-mute); font-size: 13px; }
.dash-section {
  background: var(--bg-2);
  border: 1px solid var(--border);
  margin-top: 16px;
  padding: 22px;
}
.dash-section h2 {
  margin: 0 0 16px;
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
}

/* ------------------------------------------------------------------ *
 * Footer                                                              */

.footer { border-top: 1px solid var(--border); margin-top: 80px; padding: 24px 0; }
.footer__inner {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  color: var(--text-mute);
  font-size: 12px;
  font-family: var(--font-mono);
}
.footer__brand { font-family: var(--font-serif); font-weight: 600; color: var(--text-dim); font-size: 14px; }
.footer__links a { color: var(--text-dim); }
.footer__links a:hover { color: var(--accent); }

/* ------------------------------------------------------------------ *
 * Privacy / About page                                                 */

.prose {
  max-width: 700px;
  margin: 0 auto;
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 32px 36px;
}
.prose h2 {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 500;
  margin: 28px 0 12px;
  letter-spacing: -0.01em;
}
.prose h2:first-child { margin-top: 0; }
.prose p, .prose ul { font-size: 14px; line-height: 1.7; color: var(--text-dim); }
.prose ul { padding-left: 20px; }
.prose li { margin: 4px 0; }
.prose code {
  font-family: var(--font-mono);
  background: var(--bg-3);
  padding: 1px 6px;
  font-size: 12px;
  border: 1px solid var(--border);
  color: var(--text);
}
.prose strong { color: var(--text); }

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================
   Owner-only tier switcher
   ============================================================ */

.owner-section {
  border-left: 3px solid var(--accent);
  background: linear-gradient(180deg, rgba(255,107,53,0.04), transparent 60%);
}

.owner-form__row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
}

/* Extra-small button variant for in-row actions (e.g. tier switcher). */
.btn--xs {
  padding: 4px 10px;
  font-size: 0.78rem;
  letter-spacing: 0;
}

/* ------------------------------------------------------------------ *
 * Mobile UI — hamburger drawer, stacked command bar, touch targets
 *
 * Breakpoints:
 *   <= 720px  phone / small tablet — major layout changes
 *   <= 480px  small phone — extra-compact spacing + font sizes
 *
 * The "desktop" styles above (>=721px) are the primary layout; everything
 * below overrides for narrow viewports. Always test in mobile-first.   */

/* Hamburger button — hidden on desktop, shown on mobile. */
.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 1px solid var(--border);
  cursor: pointer;
  padding: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  margin-left: auto;
  /* Larger tap target on mobile */
  -webkit-tap-highlight-color: transparent;
}
.nav-toggle__bar {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--text);
  transition: transform 0.2s, opacity 0.2s;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Backdrop behind the drawer — full-screen, click-to-close. */
.nav-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 90;
  animation: fade-in 0.18s ease;
}
.nav-backdrop[hidden] { display: none; }
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ===== Topbar breakpoint — 1024px.
   Reason: the inline nav (Home / Pricing / Dashboard / tier badge / Log in
   or Log out / Sign up) doesn't fit alongside the brand below ~1024px on
   most browsers — the 720-1024px range is when the brand sits on the left
   and the nav wraps to a second line, ballooning the topbar. Swapping to
   the drawer at 1024px keeps the topbar a single 52px row on everything
   from iPad landscape down. 820px wasn't enough — users on 900-1023px
   viewports still saw the wrap. */
@media (max-width: 1024px) {
  .nav-toggle { display: flex; }
  /* Slightly tighter side padding so things have room to breathe. */
  .wrap { padding: 0 16px; }
  .main { padding: 24px 16px 60px; }

  /* Topbar: shrink height, show the hamburger, hide the inline nav. */
  .topbar__inner { height: 52px; }
  .nav-toggle { display: flex; }

  /* Nav becomes a slide-in drawer from the right. */
  .nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(320px, 85vw);
    background: var(--bg-2);
    border-left: 1px solid var(--border);
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.4);
    transform: translateX(100%);
    transition: transform 0.22s ease;
    z-index: 100;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: 68px 0 24px;        /* room for the close button at top */
    margin: 0;
    flex-wrap: nowrap;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .nav.is-open { transform: translateX(0); }
  .nav a,
  .nav .btn,
  .nav__form .btn {
    display: block;
    width: 100%;
    text-align: left;
    padding: 16px 24px;
    font-size: 16px;
    border-radius: 0;
    border: 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    background: transparent;
  }
  .nav a:hover, .nav a:focus { color: var(--accent); background: var(--bg-3); }
  .nav .badge {
    margin: 12px 24px;
    width: max-content;
    border: 0;
    padding: 4px 10px;
  }
  .nav__form { margin: 0; padding: 0; }
  .nav__form .btn {
    border: 0;
    color: var(--text-dim);
    text-align: left;
    cursor: pointer;
  }

  /* Hero — smaller font, tighter spacing, full width subtitle. */
  .hero { padding: 16px 0 20px; }
  .hero h1 { font-size: 36px; line-height: 1.08; }
  .hero__sub { font-size: 15px; margin: 0 0 24px; max-width: none; }

  /* Command bar — the most important mobile fix.
     Wrap the chips into one row, then the input on its own row,
     then the button on its own row. Each row is a comfortable
     48px+ tap target. */
  .cmd {
    flex-wrap: wrap;
    border-radius: 0;
  }
  .cmd__platform,
  .cmd__chip {
    /* Three chips share the first row, equal width. */
    flex: 1 1 0;
    min-width: 0;
    padding: 14px 8px;
    font-size: 11px;
    text-align: center;
    justify-content: center;
    border-right: 1px solid var(--border);
  }
  .cmd__chip:last-of-type { border-right: 0; }
  /* Drop the dropdown arrow on mobile — the chip is clearly tappable
     and the native picker UI is enough affordance. */
  .cmd__platform::after,
  .cmd__chip::after { display: none; }
  /* Input — full width on its own row, generous height. */
  .cmd__input {
    flex: 1 0 100%;
    order: 4;
    padding: 16px 14px;
    font-size: 16px;        /* 16px prevents iOS zoom on focus */
    border-top: 1px solid var(--border);
  }
  /* Download button — full width on its own row, large. */
  .cmd__go {
    flex: 1 0 100%;
    order: 5;
    min-width: 0;
    padding: 18px 20px;
    font-size: 15px;
  }
  .cmd__go svg { width: 16px; height: 16px; }

  /* Meta line — stack the bulk toggle above the usage counter. */
  .cmd__meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin: 12px 0 0;
  }
  #usageDisplay { font-size: 11px; }

  /* Bulk sheet — same width, but the textarea gets a smaller min-height
     so the keyboard doesn't cover the action button. */
  .bulk-sheet__inner { padding: 14px; }
  .bulk-sheet textarea { min-height: 100px; font-size: 16px; }
  .bulk-sheet__bar { flex-wrap: wrap; gap: 6px; font-size: 11px; }

  /* Preview / playlist cards — full width, no border-left bar (it crowds
     the limited horizontal space). */
  .preview {
    max-width: none;
    padding: 12px 14px;
  }
  .preview--playlist {
    border-left-width: 2px;
    padding-left: 12px;
  }
  .preview__thumb { width: 48px; height: 48px; }
  /* Playlist items: keep them on one line (block + max-width:100%
     was added above so the ellipsis works inside the flex container).
     On mobile the card is narrow, so 11px font + 92px max-height shows
     ~5 items before the fade-out kicks in. */
  .playlist-items { max-height: 92px; font-size: 11px; }
  .playlist-items::after { height: 20px; }
  .preview--playlist .preview__meta strong { font-size: 13px; }
  .preview--playlist .preview__sub { font-size: 11px; }

  /* Sites — smaller chips, two per row. */
  .sites { gap: 8px; }
  .sites__chip {
    padding: 8px 12px;
    font-size: 13px;
  }

  /* Ad slot — smaller padding. */
  .ad { padding: 12px 14px; margin: 20px 0 0; }
  .ad__body {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  .ad__plans { align-self: flex-start; }

  /* Footer — stack each piece on its own line. */
  .footer__inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  /* Plans — already stack at <820px, but tighten the cards. */
  .plan { padding: 24px 18px; }
  .plan__price .amount { font-size: 48px; }

  /* Auth forms — flush to edges instead of centering with 380px max. */
  .auth { max-width: none; margin: 24px 0 0; padding: 0 4px; }

  /* Tables (dashboard history) — allow horizontal scroll. */
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .table { min-width: 480px; }

  /* Bulk results — let the file links wrap. */
  .bulk-results__list a {
    word-break: break-all;
  }
}

/* ===== Even smaller phones (iPhone SE etc.) — <= 480px ===== */
@media (max-width: 480px) {
  .wrap { padding: 0 12px; }
  .main { padding: 20px 12px 60px; }

  /* Hero gets even tighter. */
  .hero h1 { font-size: 30px; }
  .hero__sub { font-size: 14px; }

  /* Command bar chips — drop the chevron entirely; the label is enough. */
  .cmd__platform,
  .cmd__chip {
    padding: 12px 6px;
    font-size: 10px;
    letter-spacing: 0;
  }
  .cmd__platform--auto::before { display: none; }  /* "AUTO" prefix is redundant on a small chip */

  /* Button — more compact. */
  .cmd__go { padding: 16px; font-size: 14px; }
  .cmd__input { padding: 14px 12px; font-size: 16px; }

  /* Footer — keep things compact. */
  .footer { font-size: 11px; }

  /* Dashboard stat cards — smaller numbers. */
  .stat__value { font-size: 28px; }
}

/* iOS safe-area support (notched phones) — add a bit of padding
   inside the drawer so the close button doesn't get hidden behind
   the notch. The .nav rule was here originally but it was firing
   on ALL viewports and inflating the desktop nav by 68px (the
   topbar was centering a 114px nav in 56px, so the nav overflowed
   above and below — only the LIFETIME badge stayed partially
   visible). The .nav safe-area rule now lives inside the
   (max-width: 1024px) mobile breakpoint above. */
@supports (padding: max(0px)) {
  .topbar__inner {
    padding-top: max(0px, env(safe-area-inset-top) / 2);
    padding-bottom: max(0px, env(safe-area-inset-bottom) / 2);
  }
  .main {
    padding-bottom: max(60px, env(safe-area-inset-bottom));
  }
}

/* Body scroll lock when the mobile nav drawer is open. */
body.nav-open {
  overflow: hidden;
  /* Prevent rubber-band scroll showing the underlying page on iOS. */
  position: fixed;
  width: 100%;
  top: var(--scroll-y, 0);
}

/* Reduced motion — keep transforms instant. */
@media (prefers-reduced-motion: reduce) {
  .nav, .nav-toggle__bar, .nav-backdrop {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- /donate/checkout redirect card --------------------------- */
/* Used after the user clicks "Pay $X" — instead of a silent 302 that
 * some privacy/shields setups swallow, we render a visible "taking you
 * to Stripe…" card with a spinner, a clickable fallback link, and a
 * JS redirect (50 ms delay so the page paints first). */
.redirect-card {
  max-width: 480px;
  margin: 80px auto;
  padding: 48px 32px;
  text-align: center;
  border: 1px solid var(--border);
  background: var(--bg-2);
}
.redirect-card .spinner {
  width: 32px;
  height: 32px;
  margin: 0 auto 24px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: redirect-spin 0.9s linear infinite;
}
@keyframes redirect-spin {
  to { transform: rotate(360deg); }
}
.redirect-title {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  font-weight: 500;
  margin: 0 0 12px;
  color: var(--text);
}
.redirect-text {
  color: var(--text-dim);
  margin: 0 0 24px;
}
.redirect-fallback {
  color: var(--text-mute);
  font-size: 0.9rem;
  margin: 0;
}
.redirect-fallback a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .redirect-card .spinner { animation: none; }
}

/* ===== donate_success receipt card =====
   Used on /donate/success to show a tidy breakdown of what just
   happened (DB row from webhook, or Stripe session info if webhook
   hasn't landed yet). */
.receipt {
  max-width: 560px;
  margin: 32px auto 0;
  padding: 24px;
  border: 1px solid var(--border);
  background: var(--bg-2);
  text-align: left;
}
.receipt__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.95rem;
}
.receipt__row:last-child { border-bottom: none; }
.receipt__label {
  color: var(--text-dim);
  flex-shrink: 0;
}
.receipt__value {
  color: var(--text);
  text-align: right;
  word-break: break-all;
}
.receipt__value--mono {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.85rem;
  color: var(--text-dim);
}
.diag-error {
  max-width: 560px;
  margin: 24px auto;
  padding: 16px;
  background: var(--bg-2);
  border: 1px solid #b04848;
  color: #f0a0a0;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.85rem;
  white-space: pre-wrap;
  word-break: break-word;
  text-align: left;
}
@media (max-width: 480px) {
  .receipt { padding: 16px; }
  .receipt__row { flex-direction: column; align-items: flex-start; gap: 4px; }
  .receipt__value { text-align: left; }
}

