/* Catvu dashboard — dark theme, mobile-first responsive */

:root {
  --bg:           #0c0d10;
  --panel:        #15171c;
  --panel-2:      #1c1f26;
  --line:         #232831;
  --line-soft:    #1d2129;
  --text:         #e8eaef;
  --muted:        #8b919c;
  --accent:       #62d9ff;
  --accent-2:     #b885ff;
  --accent-strong:#2faee5;
  --error:        #ff7a8b;
  --success:      #4ad991;
  --warn:         #ffc857;
  --info:         #62d9ff;

  /* Tap target floor — Apple HIG minimum is 44pt, Material is 48dp.
   * We use 44 across the board for buttons + interactive controls. */
  --tap-min: 44px;
}

* { box-sizing: border-box; }

/* The HTML `hidden` attribute is `display: none`, but any later class
 * rule with `display: flex|grid|block` wins on specificity and shows
 * the element on page load before JS can run. Lock it down so the
 * attribute always wins — same fix tracker-pro uses. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               system-ui, sans-serif;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Prevent the rubber-band horizontal scroll iOS Safari does when
   * something subtly overflows. We size everything to fit, but this
   * is belt-and-braces. */
  overflow-x: hidden;
}

/* iOS notch / Android nav bar safe areas. */
body {
  padding-bottom: env(safe-area-inset-bottom);
}

header.page, body > header {
  text-align: center;
  padding: 28px 16px 8px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}

body > header h1 {
  margin: 0;
  font-size: clamp(28px, 7vw, 38px);
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  line-height: 1.1;
}

.logo-note {
  -webkit-text-fill-color: initial;
  background: none;
}

body > header .tag {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: clamp(12px, 3.4vw, 14px);
  padding: 0 8px;
}

main {
  max-width: 720px;
  margin: 0 auto;
  padding: 12px 16px;
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
}

footer {
  text-align: center;
  padding: 24px 16px calc(24px + env(safe-area-inset-bottom));
  color: var(--muted);
  font-size: 12px;
}

/* ── Cards ───────────────────────────────────────────────────────── */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px;
  margin-bottom: 12px;
}

@media (min-width: 540px) {
  .card { padding: 22px; }
}

.card h2 {
  margin: 0 0 6px;
  font-size: clamp(17px, 4.6vw, 19px);
}

.card h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

/* ── Layout helpers ──────────────────────────────────────────────── */
.row {
  display: flex;
  gap: 10px;
  align-items: center;
}
.row.between {
  justify-content: space-between;
  /* Allow wrapping on narrow screens so the right-side button
   * (Sign out / Cancel) drops below the heading instead of squishing. */
  flex-wrap: wrap;
}
.row.gap { gap: 8px; flex-wrap: wrap; margin-top: 12px; }

.stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.small { font-size: 12px; }

/* ── Forms ───────────────────────────────────────────────────────── */
label {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 6px;
}

input[type="text"], input:not([type]) {
  width: 100%;
  padding: 12px 13px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 8px;
  /* CRITICAL: 16px prevents iOS Safari from auto-zooming into the
   * page when the input gains focus. Smaller font sizes trigger the
   * accessibility zoom and the layout looks broken. */
  font-size: 16px;
  font-family: inherit;
  min-height: var(--tap-min);
  -webkit-appearance: none;
  appearance: none;
}

input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(98, 217, 255, 0.18);
}

button {
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: #0a1116;
  border: 0;
  padding: 12px 18px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  font-size: 15px;
  font-family: inherit;
  min-height: var(--tap-min);
  /* Stop iOS from adding its own tap highlight rectangle on top of
   * our :active feedback. */
  -webkit-tap-highlight-color: transparent;
  /* Stop double-tap zoom on iOS — buttons should feel like buttons. */
  touch-action: manipulation;
  transition: transform 80ms ease-out, filter 120ms ease-out;
}

button:hover { filter: brightness(1.08); }
button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
  filter: grayscale(0.6);
}

/* Tap/click feedback — every button does a quick scale-down so the
 * user knows the click registered, even when the action is async. */
button:not(:disabled):active {
  transform: scale(0.97);
  filter: brightness(0.95);
}

/* Loading state — spinner on the left, dimmed appearance. */
button.is-loading {
  opacity: 0.85;
  cursor: wait;
  position: relative;
  padding-left: 34px;
}
button.is-loading::before {
  content: '';
  position: absolute;
  left: 12px;
  top: 50%;
  width: 12px;
  height: 12px;
  margin-top: -6px;
  border: 2px solid rgba(0, 0, 0, 0.25);
  border-top-color: #0a1116;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

button.primary { /* alias */ }

button.link {
  background: transparent;
  color: var(--muted);
  font-weight: 500;
  padding: 8px 10px;
  min-height: var(--tap-min);
}
button.link:hover { color: var(--text); }

button.small {
  padding: 9px 14px;
  font-size: 14px;
  /* Small buttons still need a usable tap target — don't shrink the
   * height, just tighten horizontal padding. */
  min-height: 40px;
}

button.danger { color: var(--error); }
button.danger:hover { color: #ffadb7; }

code {
  font-family: 'SF Mono', Consolas, 'Cascadia Code', monospace;
  font-size: 13px;
  background: var(--panel-2);
  padding: 2px 6px;
  border-radius: 4px;
  color: var(--accent);
  word-break: break-all;
}

pre {
  background: var(--bg);
  border: 1px solid var(--line);
  padding: 14px;
  border-radius: 8px;
  font-size: 13px;
  overflow-x: auto;
}

.muted { color: var(--muted); }

.error {
  background: rgba(255, 122, 139, 0.08);
  border: 1px solid rgba(255, 122, 139, 0.4);
  color: var(--error);
  padding: 10px 13px;
  border-radius: 8px;
  font-size: 13px;
  margin-top: 10px;
  /* Long error messages wrap rather than overflow the card. */
  word-wrap: break-word;
}

.success {
  color: var(--success);
  font-weight: 500;
}

.banner {
  background: rgba(98, 217, 255, 0.07);
  border: 1px solid rgba(98, 217, 255, 0.25);
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 13px;
  margin: 10px 0 16px;
  word-wrap: break-word;
}

/* ── Friend-gate banner (must accept bot's friend request) ──────── */
.friend-gate {
  background:
    linear-gradient(135deg, rgba(255, 200, 87, 0.10), rgba(255, 200, 87, 0.04));
  border: 1px solid rgba(255, 200, 87, 0.35);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 10px 0 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.friend-gate-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.friend-gate-icon {
  font-size: 28px;
  line-height: 1;
  flex: 0 0 auto;
  filter: drop-shadow(0 0 6px rgba(255, 200, 87, 0.4));
}
.friend-gate-text {
  flex: 1;
  min-width: 0;
}
.friend-gate-text h3 {
  margin: 0 0 4px;
  font-size: 15px;
  color: var(--warn);
}
.friend-gate-text p {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}
.friend-gate-text strong {
  color: var(--accent);
}
.friend-gate-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
#friend-gate-status {
  margin: 0;
  font-size: 12px;
  color: var(--muted);
}
.xs { font-size: 11px; }

/* Friend-confirm — brief success message after gate flips. */
.friend-confirm {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(74, 217, 145, 0.10);
  border: 1px solid rgba(74, 217, 145, 0.30);
  color: var(--success);
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  margin: 10px 0 16px;
}
.friend-confirm > span:first-child {
  font-weight: 700;
  font-size: 16px;
}

/* Mod-grant tip on the public-room slot card. */
.slot-card .hint {
  font-size: 12px;
  color: var(--muted);
  background: rgba(98, 217, 255, 0.05);
  border-left: 2px solid rgba(98, 217, 255, 0.3);
  border-radius: 4px;
  padding: 8px 10px;
  margin: 0 0 6px;
  line-height: 1.45;
}
.slot-card .hint strong { color: var(--accent); }

/* ── Slot grid (dashboard) ───────────────────────────────────────── */
.slot-grid {
  display: grid;
  /* Mobile-first: single column. */
  grid-template-columns: 1fr;
  gap: 12px;
  margin-top: 16px;
}

@media (min-width: 540px) {
  .slot-grid { grid-template-columns: 1fr 1fr; }
}

.slot-card {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.slot-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}

.slot-count {
  background: var(--bg);
  border: 1px solid var(--line);
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 13px;
  color: var(--accent);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.slot-card button { margin-top: auto; }

/* ── Room cards ──────────────────────────────────────────────────── */
.room-card .np {
  margin-top: 10px;
  font-size: 14px;
  word-wrap: break-word;
}

.room-card h3 {
  /* Long room names should wrap, not overflow horizontally and steal
   * space from the status badge. */
  word-wrap: break-word;
  word-break: break-word;
  /* Cap the visible width so the badge has room — but the wrap kicks
   * in below this anyway. */
  max-width: 100%;
}

.room-card header {
  /* On really narrow screens, drop the badge below the title rather
   * than letting the title get squished. */
  flex-wrap: wrap;
  gap: 8px;
}

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.badge-ok   { background: rgba(74, 217, 145, 0.15); color: var(--success); }
.badge-warn { background: rgba(255, 200, 87, 0.15); color: var(--warn); }
.badge-info { background: rgba(98, 217, 255, 0.15); color: var(--info); }
.badge-err  { background: rgba(255, 122, 139, 0.15); color: var(--error); }

.stream-url-details {
  margin-top: 10px;
}
.stream-url-details summary {
  cursor: pointer;
  user-select: none;
  padding: 6px 0;
  min-height: 32px;
  display: flex;
  align-items: center;
}

.stream-url-box {
  /* On narrow screens, stack the URL above the Copy button so neither
   * gets clipped. The wizard's done step puts a long URL here. */
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
  margin-top: 8px;
  padding: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.stream-url-box code {
  flex: 1;
  word-break: break-all;
  background: transparent;
  padding: 6px 0;
  font-size: 12px;
  /* Allow text selection so users can select-and-copy manually
   * even when the JS Copy button doesn't work. */
  user-select: all;
  -webkit-user-select: all;
}
.stream-url-box button {
  align-self: flex-end;
  /* Don't span the full card width — looks weird on tablets. */
  min-width: 80px;
}

@media (min-width: 540px) {
  .stream-url-box {
    flex-direction: row;
    align-items: center;
  }
  .stream-url-box code { padding: 0; }
}

/* ── Wizard ──────────────────────────────────────────────────────── */
ol.steps {
  list-style: none;
  margin: 14px 0 18px;
  padding: 6px;
  display: grid;
  /* Tighter min on mobile so 3 short labels fit one row when possible. */
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 6px;
  background: var(--panel-2);
  border-radius: 10px;
}

ol.steps .step {
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  /* Truncate over-long step labels with an ellipsis instead of
   * forcing the row to grow. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

ol.steps .step.active {
  background: linear-gradient(135deg, rgba(98, 217, 255, 0.18), rgba(184, 133, 255, 0.16));
  color: var(--text);
  font-weight: 600;
}

ol.steps .step.done {
  color: var(--success);
}

.wizard-step {
  padding: 14px 0 4px;
}
.wizard-step p:first-child { margin-top: 0; }
.wizard-step p {
  word-wrap: break-word;
}
.wizard-step button {
  /* Wizard primary buttons span the full card width on mobile —
   * that's the most reachable tap area. On desktop they relax. */
  width: 100%;
  max-width: 360px;
  display: block;
  margin-top: 4px;
}
.wizard-step button.link, .wizard-step button.small {
  width: auto;
  display: inline-block;
  margin-top: 8px;
}

@media (min-width: 540px) {
  .wizard-step button {
    width: auto;
    display: inline-block;
    min-width: 160px;
  }
}

.poll-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0;
  color: var(--muted);
  font-size: 14px;
  /* Spinner + text wrapping; keep the spinner glued to the start of
   * its line on really narrow screens. */
  flex-wrap: wrap;
}

.spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }


/* ── Marketing landing (login screen) ─────────────────────────────
   Design rules:
   - Reuses the dashboard's blue accent (--accent / --accent-2)
   - Wide layout on desktop: hero is 2-column (copy + signup card),
     features are 3-column, pricing is 2-up, FAQ is 2-column.
   - Stacks cleanly on mobile.
   - No "center column on a vast empty page" feel.
*/

.lp {
  /* Wider than the dashboard — landing page wants to use the screen. */
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px;
}

/* When the marketing screen is visible, let main expand wider too. */
main:has(.lp:not([hidden])) {
  max-width: 1080px;
  padding: 12px 0; /* outer padding moves to .lp itself */
}

/* ── Hero: 2-column on desktop, stacked on mobile ────────────────── */
.lp-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  padding: 48px 0 56px;
  align-items: center;
}

@media (min-width: 880px) {
  .lp-hero {
    grid-template-columns: 1.1fr 0.9fr;
    gap: 56px;
    padding: 40px 0 72px;
  }
}

/* Mobile-only: the kitty image is a faded background behind the hero
 * copy + signup card. The image needs to bleed edge-to-edge of the
 * viewport (not stop at the .lp content padding), so we break the
 * background out using `100vw` positioning relative to the hero block.
 *
 * No `mask-image` — it creates a stacking context that breaks touch
 * scrolling on iOS Safari. We fade with a stronger gradient instead.
 *
 * Desktop also gets the kitty, but anchored inside the right-column
 * area only (the signup card's column) so it doesn't compete with the
 * hero copy on the left. */
@media (max-width: 879px) {
  .lp-hero {
    position: relative;
    padding: 36px 0 52px;
  }

  .lp-hero::before {
    content: '';
    position: absolute;
    /* Break out of the .lp padding so the image hits the viewport
     * edges. -24px matches the .lp side padding. */
    left: -24px;
    right: -24px;
    top: 0;
    bottom: 0;
    background-image:
      /* Top → bottom dark fade. Stronger near the headline area
       * (top + bottom) so text always has a dark backing; image
       * peeks through in the middle. */
      linear-gradient(180deg,
        rgba(12, 13, 16, 0.95) 0%,
        rgba(12, 13, 16, 0.75) 30%,
        rgba(12, 13, 16, 0.65) 55%,
        rgba(12, 13, 16, 0.95) 100%),
      url('kitty.jpg');
    background-size: cover;
    background-position: center 20%;
    background-repeat: no-repeat;
    /* Behind text but not negative — negative z-index can leak out of
     * the parent stacking context. */
    z-index: 0;
    pointer-events: none; /* never intercept taps/scrolls */
  }

  .lp-hero-left,
  .lp-hero-right {
    position: relative;
    z-index: 1;
  }

  /* Frosted-glass signup card so the kitty image shows through but
   * text stays crisp. Heavier blur compensates for the lower opacity
   * — without it the photo behind would distract from the input.
   *
   * Specificity-bumped (.lp .lp-signup) so this wins against the
   * later-in-file base .lp-signup rule. */
  .lp .lp-signup {
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    background: rgba(21, 23, 28, 0.55);
    border-color: rgba(98, 217, 255, 0.28);
    /* Subtle outer glow so the card lifts off the photo background */
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
  }

  /* The input inside the glass card needs to stay readable. Slightly
   * less transparent than the card itself. */
  .lp .lp-signup .lp-form input {
    background: rgba(12, 13, 16, 0.7);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
  }
}

/* ── Desktop: cat behind the right column only (where signup card sits) ── */
@media (min-width: 880px) {
  .lp-hero {
    position: relative;
    overflow: hidden; /* contain the soft glow on the image */
    border-radius: 16px;
    isolation: isolate;
  }
  .lp-hero::before {
    content: '';
    position: absolute;
    /* Right ~50% of the hero, lined up behind the signup card */
    top: 0;
    bottom: 0;
    right: 0;
    width: 55%;
    background-image:
      /* Stronger fade on the LEFT side of the image so it dissolves
       * into the page bg next to the headline copy column */
      linear-gradient(90deg,
        rgba(12, 13, 16, 1) 0%,
        rgba(12, 13, 16, 0.6) 30%,
        rgba(12, 13, 16, 0.25) 70%,
        rgba(12, 13, 16, 0.55) 100%),
      url('kitty.jpg');
    background-size: cover;
    background-position: center 30%;
    background-repeat: no-repeat;
    z-index: 0;
    pointer-events: none;
    /* Subtle rounded inner edge */
    border-radius: 16px;
  }
  .lp-hero-left,
  .lp-hero-right {
    position: relative;
    z-index: 1;
  }
  /* Glass card on desktop too, but a touch more opaque so the form is
   * extra-readable against the busier club image */
  .lp .lp-signup {
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    background: rgba(21, 23, 28, 0.72);
    border-color: rgba(98, 217, 255, 0.28);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
  }
}

.lp-eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
}

.lp-eyebrow-dark { color: var(--muted); }

/* Premium gold accent — used inline for the "premium" word in the
 * hero eyebrow. Solid gold so it stays visible at small eyebrow size;
 * no filter (drop-shadow filters clip text glyphs in some browsers). */
.lp-eyebrow .gold {
  color: #f4c542;
  font-weight: 800;
  text-shadow:
    0 0 6px rgba(244, 197, 66, 0.35),
    0 0 14px rgba(244, 197, 66, 0.18);
}

.lp-h1 {
  margin: 0 0 18px;
  font-size: clamp(30px, 5.6vw, 54px);
  line-height: 1.1;
  letter-spacing: -0.022em;
  font-weight: 800;
  color: var(--text);
}

.lp-h1 .hl {
  /* Subtle highlight under "THE one" — keeps the brand blue, no
     gradient text spam */
  background: linear-gradient(180deg, transparent 62%, rgba(98, 217, 255, 0.28) 62%);
  padding: 0 4px;
  white-space: nowrap;
}

.lp-sub {
  margin: 0 0 22px;
  font-size: clamp(15px, 2.1vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  max-width: 560px;
}

.lp-source-highlight {
  color: var(--success);
  font-weight: 800;
  text-shadow: 0 0 12px rgba(74, 217, 145, 0.2);
}

.lp-source-highlight span {
  color: var(--accent);
  text-shadow: 0 0 12px rgba(98, 217, 255, 0.25);
}

.lp-checks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 540px;
}

.lp-checks li {
  position: relative;
  padding-left: 24px;
  font-size: 14.5px;
  color: var(--text);
  line-height: 1.5;
}

.lp-checks li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent);
  font-weight: 800;
}

/* Sign-up card — sticky on DESKTOP ONLY (sticky + photo bg confuses
 * iOS scroll). On mobile it scrolls naturally with the rest of the
 * hero column. */
.lp-signup {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 28px 24px;
}

@media (min-width: 880px) {
  .lp-signup {
    position: sticky;
    top: 24px;
  }
}

.lp-signup-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 8px;
}

.lp-signup-num {
  font-size: clamp(36px, 5vw, 44px);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  line-height: 1;
}

.lp-signup-unit {
  font-size: 16px;
  color: var(--muted);
  font-weight: 600;
}

.lp-signup-meta {
  margin: 0 0 18px;
  font-size: 13px;
  color: var(--muted);
}

.lp-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lp-form label {
  margin: 0;
}

.lp-form input {
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 12px 14px;
  font-size: 16px; /* prevent iOS zoom */
  border-radius: 9px;
  width: 100%;
}

.lp-form input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(98, 217, 255, 0.18);
}

.lp-form button {
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: #0a1116;
  border: 0;
  padding: 13px 16px;
  border-radius: 9px;
  font-weight: 700;
  font-size: 15px;
  cursor: pointer;
  margin-top: 4px;
}

.lp-form button:hover { filter: brightness(1.08); }

.lp-signup-foot {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}

/* ── Generic section structure ───────────────────────────────────── */
.lp-section {
  padding: 56px 0;
  border-top: 1px solid var(--line);
}

.lp-section-head {
  margin-bottom: 28px;
  max-width: 720px;
}

.lp-section-head.lp-center {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.lp-h2 {
  margin: 6px 0 0;
  font-size: clamp(24px, 4vw, 34px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  font-weight: 800;
  color: var(--text);
}

.lp-body {
  margin: 14px 0 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted);
  max-width: 540px;
}

.lp-caption {
  margin: 18px 0 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.55;
}

.lp-caption.lp-center {
  text-align: center;
}

.lp-caption code,
.lp-body code {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--accent);
  padding: 1px 5px;
  font-size: 0.92em;
  border-radius: 3px;
}

/* ── Split section (text left, visual right) ─────────────────────── */
.lp-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
}

@media (min-width: 880px) {
  .lp-split {
    grid-template-columns: 1fr 1fr;
    gap: 64px;
  }
}

/* ── Chat-bubble mock ────────────────────────────────────────────── */
.chat-mock {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 100%;
}

.chat-mock .msg {
  font-size: 13.5px;
  line-height: 1.45;
  padding: 9px 13px;
  border-radius: 10px;
  align-self: flex-start;
  max-width: 88%;
  word-wrap: break-word;
}

.chat-mock .msg .who {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-bottom: 2px;
  opacity: 0.75;
}

.chat-mock .msg.user {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--line);
}

.chat-mock .msg.user .who { color: var(--accent-2); }

.chat-mock .msg.bot {
  background: rgba(98, 217, 255, 0.08);
  color: var(--text);
  border: 1px solid rgba(98, 217, 255, 0.25);
  align-self: flex-end;
}

.chat-mock .msg.bot .who { color: var(--accent); }

/* ── Feature grid: 3 columns on desktop ─────────────────────────── */
.lp-features {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 600px) {
  .lp-features { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 880px) {
  .lp-features { grid-template-columns: repeat(3, 1fr); }
}

.lp-feature {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 22px;
}

.lp-feature-emoji {
  font-size: 24px;
  margin-bottom: 10px;
  line-height: 1;
}

.lp-feature h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}

.lp-feature p {
  margin: 0;
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.55;
}

.lp-feature p code {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--accent);
  padding: 1px 5px;
  font-size: 0.9em;
  border-radius: 3px;
}

/* ── Value stack ─────────────────────────────────────────────────── */
.lp-stack {
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: var(--panel);
  max-width: 720px;
  margin: 0 auto;
}

.lp-stack-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  gap: 16px;
}

.lp-stack-row:last-child { border-bottom: 0; }

.lp-stack-row > span:first-child {
  color: var(--text);
  flex: 1;
  min-width: 0;
}

.lp-stack-row > span:last-child {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-weight: 600;
}

.lp-stack-total {
  background: var(--panel-2);
  border-top: 2px solid var(--line);
}

.lp-stack-total > span {
  color: var(--muted) !important;
  text-decoration: line-through;
  text-decoration-color: rgba(98, 217, 255, 0.4);
  font-weight: 600 !important;
}

.lp-stack-pay {
  background: rgba(98, 217, 255, 0.06);
}

.lp-stack-pay > span {
  color: var(--accent) !important;
  font-size: 17px !important;
  font-weight: 800 !important;
}

/* ── Guarantee — full-width banner ──────────────────────────────── */
.lp-guarantee {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 56px 0;
  border-top: 1px solid var(--line);
}

.lp-guarantee-num {
  flex-shrink: 0;
  font-size: clamp(70px, 12vw, 130px);
  font-weight: 900;
  line-height: 0.9;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-feature-settings: "tnum";
}

.lp-guarantee-body h3 {
  margin: 0 0 8px;
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--text);
}

.lp-guarantee-body p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
  max-width: 640px;
}

@media (max-width: 540px) {
  .lp-guarantee {
    flex-direction: column;
    gap: 12px;
    text-align: center;
  }
  .lp-guarantee-num { line-height: 1; }
  .lp-guarantee-body p { margin: 0 auto; }
}

/* ── Pricing cards ───────────────────────────────────────────────── */
.lp-pricing {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  max-width: 720px;
  margin: 0 auto;
}

@media (min-width: 600px) {
  .lp-pricing { grid-template-columns: 1fr 1fr; }
}

.lp-pricing-card {
  background: var(--panel);
  border: 1.5px solid var(--line);
  border-radius: 14px;
  padding: 28px 24px;
  position: relative;
  display: flex;
  flex-direction: column;
}

.lp-pricing-best {
  border-color: var(--accent);
  background: linear-gradient(180deg, rgba(98, 217, 255, 0.06), var(--panel) 80%);
}

.lp-pricing-tag {
  position: absolute;
  top: -10px;
  right: 18px;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #0a1116;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
}

.lp-pricing-name {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

.lp-pricing-num {
  font-size: clamp(36px, 4.5vw, 44px);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  line-height: 1;
}

.lp-pricing-num span {
  font-size: 0.4em;
  font-weight: 600;
  color: var(--muted);
  margin-left: 4px;
}

.lp-pricing-meta {
  margin: 14px 0 22px;
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
  flex: 1;
}

.lp-pricing-cta {
  display: block;
  width: 100%;
  text-align: center;
  background: var(--panel-2);
  color: var(--text);
  padding: 13px;
  border-radius: 10px;
  font-weight: 700;
  border: 1px solid var(--line);
  font-size: 14px;
  cursor: pointer;
}

.lp-pricing-best .lp-pricing-cta {
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: #0a1116;
  border-color: transparent;
}

.lp-pricing-cta:hover { filter: brightness(1.08); }

/* ── FAQ — 2-column on desktop ──────────────────────────────────── */
.lp-faq-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  max-width: 920px;
  margin: 0 auto;
}

@media (min-width: 800px) {
  .lp-faq-grid {
    grid-template-columns: 1fr 1fr;
    gap: 0 32px;
  }
}

.lp-faq-grid details {
  border-bottom: 1px solid var(--line);
  padding: 16px 0;
}

.lp-faq-grid summary {
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  position: relative;
  padding-right: 30px;
}

.lp-faq-grid summary::-webkit-details-marker { display: none; }

.lp-faq-grid summary::after {
  content: '+';
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 22px;
  color: var(--muted);
  font-weight: 400;
}

.lp-faq-grid details[open] summary::after { content: '–'; }

.lp-faq-grid details p {
  margin: 12px 0 4px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
}

.lp-faq-grid details p code {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--accent);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 0.92em;
}



/* ── DJ / club aesthetic + scroll animations ─────────────────────────
 *
 * Layered ON TOP of the existing landing page. Adds:
 *   - Top scroll-progress bar (neon gradient, follows page scroll)
 *   - Animated equalizer bars in the hero (subtle, brand presence)
 *   - Scroll-reveal: sections fade + lift in as you scroll to them
 *   - Neon glow on H1, signup card, pricing best card
 *   - Mascot-grade glow ring around the kitty bg on mobile
 *   - Subtle pulse on the price number
 *   - Animated conic-gradient border on the "best" pricing card
 *
 * Respects prefers-reduced-motion. */

/* ── 1. Top scroll progress bar (the DJ deck slider feel) ─────────── */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: transparent;
  z-index: 1000;
  pointer-events: none;
}
.scroll-progress::before {
  content: '';
  display: block;
  height: 100%;
  width: var(--scroll-pct, 0%);
  background: linear-gradient(90deg,
    var(--accent) 0%,
    var(--accent-2) 50%,
    var(--accent) 100%);
  background-size: 200% 100%;
  box-shadow: 0 0 12px rgba(98, 217, 255, 0.6);
  transition: width 80ms linear;
  animation: progress-shimmer 3s linear infinite;
}
@keyframes progress-shimmer {
  to { background-position: -200% 0; }
}

/* ── 2. Hero equalizer bars — subtle bottom-edge accent.
 *     Sits at the very bottom of the hero (12px tall), behind the
 *     content z-index. Doesn't compete with the cat image since we
 *     anchor it to the lower 12px only. */
.lp-hero::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 12px;
  background:
    repeating-linear-gradient(
      90deg,
      transparent 0,
      transparent 4px,
      rgba(98, 217, 255, 0.45) 4px,
      rgba(98, 217, 255, 0.45) 5px,
      transparent 5px,
      transparent 10px,
      rgba(184, 133, 255, 0.45) 10px,
      rgba(184, 133, 255, 0.45) 11px,
      transparent 11px,
      transparent 16px
    );
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, black 100%);
          mask-image: linear-gradient(180deg, transparent 0%, black 100%);
  opacity: 0.55;
  pointer-events: none;
  z-index: 0;
  animation: eq-pulse 1.8s ease-in-out infinite;
  transform-origin: bottom;
}

@keyframes eq-pulse {
  0%, 100% { transform: scaleY(0.6); opacity: 0.4; }
  50%      { transform: scaleY(1);   opacity: 0.7; }
}

/* Hide the EQ bars on the very smallest screens — they compete with the
 * cat photo for visual attention there. */
@media (max-width: 540px) {
  .lp-hero::after { display: none; }
}

/* ── 3. Scroll-reveal: each major section starts hidden + offset, then
 *     fades & lifts when JS adds the .in-view class. */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.reveal.in-view {
  opacity: 1;
  transform: none;
}

/* Stagger child reveals inside grids (features + pricing + faq) */
.reveal-stagger > * {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 600ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal-stagger.in-view > * { opacity: 1; transform: none; }
.reveal-stagger.in-view > *:nth-child(1) { transition-delay: 0ms;   }
.reveal-stagger.in-view > *:nth-child(2) { transition-delay: 70ms;  }
.reveal-stagger.in-view > *:nth-child(3) { transition-delay: 140ms; }
.reveal-stagger.in-view > *:nth-child(4) { transition-delay: 210ms; }
.reveal-stagger.in-view > *:nth-child(5) { transition-delay: 280ms; }
.reveal-stagger.in-view > *:nth-child(6) { transition-delay: 350ms; }
.reveal-stagger.in-view > *:nth-child(7) { transition-delay: 420ms; }
.reveal-stagger.in-view > *:nth-child(8) { transition-delay: 490ms; }

/* ── 4. Neon glow on key elements ─────────────────────────────────── */
.lp-h1 .hl {
  /* Already had a highlighter underline — add a soft neon glow */
  box-shadow: 0 0 20px rgba(98, 217, 255, 0.25);
}

/* The signup card: animated cyan-to-purple border that slowly hue-rotates
 * — gives it that "live now" club door feel without being garish. */
.lp .lp-signup {
  position: relative;
  background-clip: padding-box;
}
.lp .lp-signup::before {
  content: '';
  position: absolute;
  inset: -1.5px;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(
    from var(--ang, 0turn),
    var(--accent),
    var(--accent-2),
    rgba(255, 199, 87, 0.6),
    var(--accent),
    var(--accent)
  );
  -webkit-mask:
    linear-gradient(black, black) content-box,
    linear-gradient(black, black);
          mask:
    linear-gradient(black, black) content-box,
    linear-gradient(black, black);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
  animation: spin-border 8s linear infinite;
  opacity: 0.7;
}
@property --ang {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0turn;
}
@keyframes spin-border {
  to { --ang: 1turn; }
}

/* Best pricing card: same glowing border + a subtle outer glow */
.lp-pricing-best {
  position: relative;
  box-shadow:
    0 0 0 1px rgba(98, 217, 255, 0.18),
    0 12px 48px -8px rgba(98, 217, 255, 0.18);
}

/* ── 5. Price number — slow heartbeat pulse so the eye lands on it ── */
.lp-signup-num {
  animation: price-pulse 2.6s ease-in-out infinite;
  text-shadow:
    0 0 14px rgba(98, 217, 255, 0.25);
}
@keyframes price-pulse {
  0%, 100% { text-shadow: 0 0 14px rgba(98, 217, 255, 0.25); }
  50%      { text-shadow: 0 0 22px rgba(98, 217, 255, 0.45); }
}

/* ── 6. Feature cards: lift on hover (desktop) for "I can press this" */
@media (hover: hover) {
  .lp-feature {
    transition: transform 240ms ease, border-color 240ms ease,
                box-shadow 240ms ease;
  }
  .lp-feature:hover {
    transform: translateY(-3px);
    border-color: rgba(98, 217, 255, 0.35);
    box-shadow: 0 12px 32px -12px rgba(98, 217, 255, 0.25);
  }
}

/* ── 7. Chat-mock entrance: bubbles "type in" sequentially ────────── */
.chat-mock.in-view .msg {
  animation: bubble-in 500ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.chat-mock.in-view .msg:nth-child(1)  { animation-delay: 0ms; }
.chat-mock.in-view .msg:nth-child(2)  { animation-delay: 200ms; }
.chat-mock.in-view .msg:nth-child(3)  { animation-delay: 400ms; }
.chat-mock.in-view .msg:nth-child(4)  { animation-delay: 600ms; }
.chat-mock.in-view .msg:nth-child(5)  { animation-delay: 800ms; }
.chat-mock.in-view .msg:nth-child(6)  { animation-delay: 1000ms; }
.chat-mock.in-view .msg:nth-child(7)  { animation-delay: 1200ms; }
.chat-mock.in-view .msg:nth-child(8)  { animation-delay: 1400ms; }
.chat-mock.in-view .msg:nth-child(9)  { animation-delay: 1600ms; }
.chat-mock.in-view .msg:nth-child(10) { animation-delay: 1800ms; }
.chat-mock .msg { opacity: 0; transform: translateY(8px); }
@keyframes bubble-in {
  to { opacity: 1; transform: none; }
}

/* ── 8. Mobile: glow ring around the kitty image so it pops ────────── */
@media (max-width: 879px) {
  .lp-hero::before {
    /* Existing rule sets background; we add a subtle inset accent
     * via box-shadow without overriding the earlier declarations.
     * The inset shadow makes the image feel like it's behind a lit
     * glass pane. */
    box-shadow:
      inset 0 0 80px rgba(98, 217, 255, 0.12),
      inset 0 0 200px rgba(184, 133, 255, 0.08);
  }
}

/* ── 9. Reduced-motion respect — kill ALL animations ───────────────── */
@media (prefers-reduced-motion: reduce) {
  .scroll-progress::before { animation: none !important; }
  .lp-hero::after { animation: none !important; opacity: 0.3; }
  .reveal,
  .reveal-stagger > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .lp .lp-signup::before { animation: none !important; }
  .lp-signup-num { animation: none !important; }
  .chat-mock .msg { opacity: 1 !important; transform: none !important; animation: none !important; }
}
