/* === Flash Messages === */
.flash,
.flash-alert,
.flash-notice {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  font-size: 0.875rem;
  line-height: 1.5;
}

.flash-alert {
  background: rgba(239, 68, 68, 0.15);
  color: #fca5a5;
  border: 1px solid rgba(239, 68, 68, 0.3);
}

.flash-notice {
  background: rgba(124, 58, 237, 0.15);
  color: var(--color-accent);
  border: 1px solid rgba(124, 58, 237, 0.3);
}

/* The application layout draws the flash above the page's own header, so the
   region is on every page. :has() keeps the spacing off the pages with nothing
   to say, which would otherwise all gain a gap at the top. The clearance is
   what a fixed header costs, declared once in base.css; a page without one
   pays the plain 1rem. */
.flash-region:has(.flash) {
  padding-top: var(--fixed-header-clearance, 1rem);
}

.flash-upgrade {
  background: rgba(245, 158, 11, 0.1);
  color: var(--color-amber);
  border: 1px solid rgba(245, 158, 11, 0.25);
}
.flash-upgrade__link {
  color: var(--color-amber);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* A brief, self-dismissing confirmation (clipboard_controller.js's "Copied!"),
   as opposed to the flash above: that is read once, on the page a redirect
   lands on; this fires in place, on whatever page is already open. Lives here,
   not a page-local stylesheet, because both the app (a campaign's share card)
   and a public page (a Lines & Veils deck's share and edit links) use it, and
   this is the one stylesheet both asset sets load. */
.toast {
  position: fixed;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%) translateY(1rem);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 1.25rem;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  color: var(--color-text);
  font-size: 0.875rem;
  font-weight: 500;
  opacity: 0;
  z-index: 100;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.toast svg {
  color: #22c55e;
  flex-shrink: 0;
}

.toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ==============================
   Landing Page
   ============================== */
.landing {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  position: relative;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* Glass Navigation */
.landing-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
  background: rgba(21, 23, 32, 0.8);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid rgba(124, 58, 237, 0.12);
}

.nav-logo {
  height: 36px;
  width: auto;
  filter: drop-shadow(0 2px 8px rgba(124, 58, 237, 0.2));
}

.landing-wordmark {
  font-family: "Space Grotesk", sans-serif;
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -0.04em;
  color: #fff;
  text-transform: uppercase;
}

.landing-nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.nav-link {
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
  transition: color 0.2s;
  padding: 0.375rem 0.5rem;
  border-radius: var(--radius);
}

.nav-link:hover {
  color: #fff;
  text-decoration: none;
  background: rgba(124, 58, 237, 0.1);
}

/* Hero */
.landing-hero {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8rem 0 6rem;
  min-height: 90vh;
}

/* Reuses .landing-wordmark; overrides only hero-specific layout/size. */
.hero-wordmark {
  display: block;
  font-size: 1.5rem;
  margin-bottom: 1.25rem;
}

.hero-badge {
  display: inline-block;
  padding: 0.375rem 1.25rem;
  border-radius: 9999px;
  border: 1px solid rgba(124, 58, 237, 0.2);
  background: rgba(124, 58, 237, 0.06);
  color: var(--color-accent);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.25em;
  margin-bottom: 2.5rem;
}

.landing-hero h1 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(2.75rem, 7vw, 5.5rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 0.95;
  margin-bottom: 1.5rem;
  color: #fff;
}

.text-gradient {
  background: linear-gradient(135deg, #7C3AED 0%, #D2BBFF 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.text-danger {
  color: var(--color-danger);
}

.hero-subtitle {
  font-size: 1.25rem;
  color: var(--color-text-muted);
  max-width: 580px;
  margin: 0 auto 3rem;
  line-height: 1.7;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
}

.btn-hero {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #7C3AED 0%, #a78bfa 100%);
  color: #fff;
  font-family: "Space Grotesk", sans-serif;
  font-weight: 700;
  font-size: 1.125rem;
  padding: 1rem 2.5rem;
  border-radius: var(--radius-lg);
  border: none;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 8px 32px rgba(124, 58, 237, 0.25);
  transition: transform 0.15s, box-shadow 0.15s;
}

.btn-hero:hover {
  transform: scale(1.04);
  box-shadow: 0 12px 40px rgba(124, 58, 237, 0.35);
  text-decoration: none;
}

.btn-hero:active {
  transform: scale(0.97);
}

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #fff;
  font-family: "Space Grotesk", sans-serif;
  font-weight: 600;
  font-size: 1.125rem;
  padding: 1rem 2.5rem;
  border-radius: var(--radius-lg);
  border: 1px solid rgba(149, 141, 161, 0.25);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.2s, border-color 0.2s;
}

.btn-ghost:hover {
  background: var(--color-surface);
  border-color: rgba(149, 141, 161, 0.4);
  text-decoration: none;
}

/* Problem / Solution section */
.landing-problem {
  padding: 6rem 0;
  background: var(--color-surface);
}

.problem-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  align-items: center;
}

.problem-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.problem-card {
  padding: var(--card-pad);
  border-radius: 1.25rem;
}

.problem-card--bad {
  background: color-mix(in srgb, var(--color-surface-raised) 70%, var(--color-bg));
  border: 1px solid rgba(239, 68, 68, 0.12);
  transform: rotate(-2deg);
}

.problem-card--good {
  background: var(--color-surface-hover);
  border: 1px solid rgba(124, 58, 237, 0.3);
  transform: rotate(1deg) translateY(1rem);
  box-shadow: 0 8px 32px rgba(124, 58, 237, 0.08);
}

.problem-label {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 0.75rem;
}

.problem-label--bad { color: #f87171; }
.problem-label--good { color: #a78bfa; }

.problem-card p {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  font-style: italic;
  line-height: 1.6;
}

.problem-card .problem-scheduled {
  font-size: 0.875rem;
  color: var(--color-success);
  font-weight: 600;
  font-style: normal;
  line-height: 1.6;
  margin: 0;
}

.problem-copy h2 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(2rem, 4vw, 3.25rem);
  font-weight: 700;
  color: #fff;
  margin-bottom: 1.25rem;
  line-height: 1.1;
}

.problem-copy > p {
  color: var(--color-text-muted);
  font-size: 1.125rem;
  line-height: 1.7;
  margin-bottom: 2rem;
}

.check-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.check-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  font-size: 1rem;
  color: var(--color-text);
}

.check-icon {
  width: 1.375rem;
  height: 1.375rem;
  color: var(--color-success);
  flex-shrink: 0;
  margin-top: 0.125rem;
}

/* Bento Features */
.landing-bento {
  padding: 8rem 0 1.25rem;
}

.bento-header {
  text-align: center;
  margin-bottom: 4rem;
}

.bento-header h2 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(2rem, 4.5vw, 3.5rem);
  font-weight: 700;
  color: #fff;
  font-style: italic;
  margin-bottom: 1rem;
}

.bento-rule {
  width: 5rem;
  height: 3px;
  background: var(--color-primary);
  margin: 0 auto;
  border-radius: 9999px;
}

.bento-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}

.bento-card {
  background: var(--color-surface);
  border: 1px solid rgba(46, 51, 71, 0.6);
  border-radius: 1.5rem;
  padding: 2.5rem;
  overflow: hidden;
  min-width: 0;
  transition: border-color 0.25s;
}

.bento-card:hover {
  border-color: rgba(124, 58, 237, 0.3);
}

.bento-card--wide,
.bento-card--full {
  grid-column: span 2;
}

.bento-icon {
  width: 2.75rem;
  height: 2.75rem;
  color: var(--color-primary);
  margin-bottom: 1.25rem;
}

.bento-card h3 {
  font-family: "Space Grotesk", sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 0.75rem;
}

.bento-card p {
  color: var(--color-text-muted);
  font-size: 1rem;
  line-height: 1.65;
  max-width: 480px;
}

/* Bento mock UI */
.bento-mock {
  margin-top: 2rem;
  background: var(--color-surface-raised);
  border: 1px solid rgba(46, 51, 71, 0.4);
  padding: 1.25rem;
  border-radius: var(--radius-lg);
}

.bento-mock-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: 1rem;
}

.bento-mock-highlight {
  color: var(--color-success);
}

.bento-mock-slots {
  display: flex;
  gap: 0.5rem;
}

.bento-mock-slot {
  flex: 1;
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(78, 234, 194, 0.08);
  border: 1px solid rgba(78, 234, 194, 0.2);
  border-radius: var(--radius);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--color-success);
  text-transform: uppercase;
}

/* Bento mini calendar */
.bento-cal {
  margin-top: 1.5rem;
  background: var(--color-surface-raised);
  border: 1px solid rgba(46, 51, 71, 0.4);
  border-radius: var(--radius-lg);
  padding: 1rem;
  transform: rotate(-2deg) scale(0.9);
  transform-origin: center top;
  margin-left: auto;
  margin-right: auto;
  max-height: 11rem; /* clip after ~2 date rows for visual effect */
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 85%);
  mask-image: linear-gradient(to bottom, #000 40%, transparent 85%);
}

.bento-cal-header {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: 0.75rem;
  text-align: center;
}

.bento-cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.125rem;
  margin-bottom: 0.25rem;
}

.bento-cal-label {
  text-align: center;
  font-size: 0.5625rem;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: 0.25rem 0;
}

.bento-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.125rem;
}

.bento-cal-day {
  position: relative;
  text-align: center;
  font-size: 0.625rem;
  font-weight: 500;
  color: var(--color-text-muted);
  padding: 0.375rem 0;
  border-radius: var(--radius);
}

.bento-cal-day--empty {
  visibility: hidden;
}

.bento-cal-day--session {
  background: rgba(124, 58, 237, 0.15);
  color: var(--color-accent);
  font-weight: 700;
  border: 1px solid rgba(124, 58, 237, 0.3);
}

.bento-cal-dot {
  position: absolute;
  bottom: 0.125rem;
  left: 50%;
  transform: translateX(-50%);
  width: 0.25rem;
  height: 0.25rem;
  border-radius: 50%;
  background: var(--color-success);
}

/* Bento split layout */
.bento-split {
  display: flex;
  gap: 3rem;
  align-items: center;
}

.bento-split-copy {
  flex: 1;
}

.bento-split-cards {
  flex: 1;
  display: flex;
  gap: 1rem;
}

.bento-notif {
  padding: 1.5rem;
  border-radius: 1rem;
  background: var(--color-surface-hover);
  min-width: 180px;
}

.bento-notif--pending {
  /* Removed opacity to preserve child text contrast */
}

.bento-notif-label {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 0.375rem;
}

.bento-notif-label--active { color: var(--color-success); }
.bento-notif-label--pending { color: #a78bfa; }

.bento-notif--active {
  border: 1px solid rgba(78, 234, 194, 0.2);
}

.bento-notif--pending {
  border: 1px solid rgba(124, 58, 237, 0.2);
}

.bento-notif-text {
  font-size: 0.875rem;
  font-weight: 700;
  color: #fff;
}

/* Bento Discord chat mock */
.bento-discord-chat {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}

.bento-discord-msg {
  background: rgba(88, 101, 242, 0.06);
  border: 1px solid rgba(88, 101, 242, 0.15);
  border-radius: 0.75rem;
  padding: 1rem 1.25rem;
}

.bento-discord-msg--escalated {
  border-color: rgba(250, 168, 26, 0.25);
  background: rgba(250, 168, 26, 0.06);
}

/* Discord's lighter dark-mode blurple. Brand #5865f2 as text was 3.3:1 on the
   escalated message tint, under the 4.5:1 non-large text needs; this is 6.1:1.
   Borders keep the brand value. So does the BOT badge, whose white text on an
   opaque #5865f2 fill is 4.61:1: a pass, but with little room to darken it. */
.bento-discord-bot {
  font-size: 0.75rem;
  font-weight: 700;
  color: #949cf7;
}

.bento-discord-badge {
  display: inline-block;
  font-size: 0.5rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: #5865f2;
  color: #fff;
  padding: 0.1rem 0.3rem;
  border-radius: 0.2rem;
  margin-left: 0.375rem;
  vertical-align: middle;
  position: relative;
  top: -0.5px;
}

.bento-discord-channel {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  color: var(--color-text-muted);
  margin-bottom: 0.5rem;
  letter-spacing: 0.02em;
}

.bento-discord-msg p {
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  margin-top: 0.375rem;
  max-width: none;
}

.bento-discord-msg p strong {
  color: #a78bfa;
  font-weight: 600;
}

.bento-discord-msg--escalated p strong {
  color: #faa81a;
}

/* Social Proof */
.landing-proof {
  padding: 0;
}

.proof-card {
  background: var(--color-surface);
  border: 1px solid rgba(46, 51, 71, 0.6);
  border-radius: 1.5rem;
  padding: 3rem 2.5rem;
  transition: border-color 0.25s;
}

.proof-card:hover {
  border-color: rgba(124, 58, 237, 0.3);
}

.proof-label {
  text-align: center;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3em;
  color: var(--color-text);
  margin-bottom: 2.5rem;
}

.proof-logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 2rem 3.5rem;
  opacity: 0.35;
  filter: grayscale(1);
  transition: opacity 0.5s, filter 0.5s;
}

.proof-logos:hover {
  opacity: 0.7;
  filter: grayscale(0);
}

.proof-logos span {
  font-family: "Space Grotesk", sans-serif;
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: #fff;
  text-transform: uppercase;
}

.proof-logos span.proof-more {
  font-weight: 500;
  font-style: italic;
  color: #9ca0ab;
  font-size: 1rem;
  text-transform: none;
  letter-spacing: 0;
}

/* Final CTA */
.landing-cta {
  position: relative;
  padding: 10rem 0;
  overflow: hidden;
}

.cta-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, rgba(124, 58, 237, 0.08) 0%, transparent 70%);
  pointer-events: none;
}

.landing-cta-inner {
  position: relative;
  z-index: 1;
  text-align: center;
}

.landing-cta h2 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(2.5rem, 6vw, 5rem);
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.04em;
  margin-bottom: 1rem;
}

.landing-cta p {
  color: var(--color-text-muted);
  font-size: 1.25rem;
  margin-bottom: 3rem;
  max-width: 540px;
  margin-left: auto;
  margin-right: auto;
}

.btn-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  color: var(--color-bg);
  font-family: "Space Grotesk", sans-serif;
  font-weight: 800;
  font-size: 1.25rem;
  padding: 1.25rem 3rem;
  border-radius: 9999px;
  border: none;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 16px 48px rgba(124, 58, 237, 0.2);
  transition: background 0.2s, transform 0.15s;
}

.btn-cta:hover {
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  transform: scale(1.03);
}

.btn-cta:active {
  transform: scale(0.97);
}

.cta-fine {
  display: block;
  margin-top: 1.5rem;
  font-size: 0.625rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--color-text-muted);
}

/* Footer */
.landing-footer {
  padding: 3rem 0;
  margin-top: auto;
  border-top: 1px solid rgba(124, 58, 237, 0.1);
  background: rgba(12, 14, 22, 0.6);
}

.landing-footer-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.footer-brand p {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-muted);
}

.footer-brand .app-footer-version {
  font-size: 0.5625rem;
  color: #8a8e9a;
  margin-top: 0.125rem;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.footer-links a {
  color: var(--color-text-muted);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  text-decoration: underline;
  text-decoration-color: rgba(124, 58, 237, 0.4);
  transition: color 0.2s;
}

.footer-links a:hover {
  color: #fff;
}

/* Landing responsive */
@media (max-width: 768px) {
  .landing-header {
    padding: 0.75rem 1rem;
  }

  .landing-wordmark {
    font-size: 1.125rem;
  }

  .nav-link {
    display: none;
  }

  .landing-hero {
    padding: 7rem 0 4rem;
    min-height: auto;
  }

  .hero-actions {
    flex-direction: column;
  }

  .hero-actions .btn-hero,
  .hero-actions .btn-ghost {
    width: 100%;
  }

  .problem-grid {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .problem-cards {
    grid-template-columns: 1fr 1fr;
  }

  .bento-grid {
    grid-template-columns: 1fr;
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
  }

  .bento-card {
    padding: 1.25rem;
  }

  .bento-card h3 {
    font-size: 1.25rem;
  }

  .bento-card p {
    font-size: 0.9375rem;
  }

  .bento-mock {
    margin-top: 1.25rem;
    padding: 1rem;
  }

  .bento-mock-slots {
    flex-wrap: wrap;
  }

  .bento-mock-slot {
    min-width: 0;
    font-size: 0.625rem;
    height: 2.5rem;
  }

  .bento-card--wide,
  .bento-card--full {
    grid-column: span 1;
  }

  .bento-split {
    flex-direction: column;
  }

  .bento-split-cards {
    width: 100%;
  }

  .bento-notif {
    min-width: 0;
  }

  .bento-cal {
    transform: rotate(-2deg) scale(0.85);
  }

  .proof-logos {
    gap: 1.25rem 2rem;
  }

  .proof-logos span {
    font-size: 1rem;
  }

  .landing-cta {
    padding: 6rem 0;
  }

  .landing-footer-inner {
    flex-direction: column;
    text-align: center;
  }

  .footer-links {
    justify-content: center;
  }
}

/* App Footer (authenticated pages) */
.app-footer {
  padding: 2rem 0;
  margin-top: auto;
  border-top: 1px solid var(--color-border);
  text-align: center;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

.app-footer-links a {
  color: var(--color-text-muted);
  text-decoration: underline;
}

.app-footer-links a:hover {
  color: var(--color-text);
}

.app-footer-version {
  font-size: 0.7rem;
  color: #9ca0ab;
  margin-top: 0.25rem;
}

/* ── Subscription plan cards ─────────────────────── */
.plan-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  margin-bottom: 1.5rem;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 640px) {
  .plan-grid { grid-template-columns: 1fr; }
}

.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(124, 58, 237, 0.15);
  border-radius: 1.25rem;
  padding: 2rem var(--card-pad);
  text-align: center;
  background: linear-gradient(165deg, rgba(124, 58, 237, 0.06) 0%, var(--color-surface) 60%);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition: border-color 0.25s, transform 0.25s, box-shadow 0.25s;
}

.plan-card--current {
  border-color: rgba(78, 234, 194, 0.4);
  box-shadow: 0 2px 12px rgba(78, 234, 194, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.plan-card:hover {
  border-color: rgba(124, 58, 237, 0.35);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(124, 58, 237, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.plan-badge {
  position: absolute;
  top: -0.625rem;
  right: -0.25rem;
  background: linear-gradient(135deg, #7C3AED, #a78bfa);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
}

.plan-card h2,
.plan-card h3 {
  font-family: "Space Grotesk", sans-serif;
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--color-success);
  margin-bottom: 0.5rem;
}

.plan-price {
  font-family: "Space Grotesk", sans-serif;
  font-weight: 700;
  font-size: 1.75rem;
  color: #fff;
  margin-bottom: 0.25rem;
}

.plan-price-annual {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  margin-bottom: 1rem;
}

.tier-features {
  list-style: none;
  padding: 0;
  margin: 0.75rem 0 0;
  text-align: left;
}

.tier-features li {
  position: relative;
  padding-left: 1.75rem;
  margin-bottom: 0.5rem;
  font-size: 0.875rem;
  color: var(--color-text-secondary, #c4c4c4);
  line-height: 1.4;
}

.tier-features li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.1em;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: rgba(78, 234, 194, 0.15);
  border: 1px solid rgba(78, 234, 194, 0.3);
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 8.5L7 11L11.5 5.5' stroke='%234EEAC2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 14px 14px;
  background-position: center;
  background-repeat: no-repeat;
}

/* Pricing Page */
.pricing-content {
  padding: 8rem 0 4rem;
}

.pricing-heading {
  text-align: center;
  margin-bottom: 3rem;
}

.pricing-heading h1 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #fff;
  margin-bottom: 1.25rem;
}

.pricing-subtitle {
  color: var(--color-text-muted);
  font-size: 1.0625rem;
  line-height: 1.7;
  max-width: 560px;
  margin: 0 auto;
}

.pricing-note {
  text-align: center;
  color: var(--color-text-muted);
  font-size: 0.875rem;
  margin-top: 2rem;
}

/* Colour alone does not set a link apart from muted text (1.07:1). */
.pricing-note a {
  text-decoration: underline;
}

/* Legal Pages (Terms, Privacy) */
.legal-content {
  padding: 5rem 0 3rem;
  line-height: 1.7;
}

.legal-content h1 {
  font-size: 2rem;
  margin-bottom: 0.25rem;
}

.legal-effective {
  color: var(--color-text-muted);
  font-size: 0.875rem;
  margin-bottom: 2rem;
}

.legal-content h2 {
  font-size: 1.25rem;
  margin-top: 2rem;
  margin-bottom: 0.75rem;
}

.legal-content h3 {
  font-size: 1.05rem;
  margin-top: 1.25rem;
  margin-bottom: 0.5rem;
}

.legal-content p,
.legal-content ul {
  margin-bottom: 1rem;
  color: var(--color-text-secondary, var(--color-text));
}

.legal-content ul {
  padding-left: 1.5rem;
}

.legal-content li {
  margin-bottom: 0.35rem;
}

/* :where adds no specificity, so a .btn inside legal or help copy keeps its own
   colours instead of accent text on an accent background. */
.legal-content a:where(:not(.btn)) {
  color: var(--color-accent);
  text-decoration: underline;
}

/* Support Form */
.support-subtitle {
  color: var(--color-text-muted);
  margin-bottom: 2rem;
}

.support-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.support-submit {
  align-self: flex-start;
  margin-top: 0.5rem;
}

/* ==============================
   Login Page
   ============================== */
.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.login-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2.5rem;
  width: 100%;
  max-width: 420px;
  box-shadow: var(--shadow);
}

.login-header {
  text-align: center;
  margin-bottom: 2rem;
}

.login-header .logo {
  display: inline-flex;
  justify-content: center;
  margin-bottom: 0.75rem;
}

.login-header h1 {
  font-size: 1.125rem;
  font-weight: 400;
  color: var(--color-text-muted);
}
.login-header .guild-icon {
  border-radius: 50%;
  margin-bottom: 0.5rem;
}

/* OAuth Buttons */
.oauth-buttons {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.oauth-buttons form {
  display: block;
  width: 100%;
}

.btn-oauth {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
  font-weight: 500;
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  font-family: inherit;
}

.btn-oauth svg {
  flex-shrink: 0;
}

.btn-oauth:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-text-muted);
}

.btn-google:hover {
  border-color: #4285f4;
}

.btn-apple:hover {
  border-color: #fff;
}

.btn-discord:hover {
  border-color: #5865f2;
}

.login-footer-text {
  text-align: center;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: 1.5rem;
}
.login-footer-text a {
  text-decoration: underline;
}

/* The Discord sign-in button, the game-system badge and the invite page
   moved here from campaigns.css, which public pages do not load. */
.btn-discord {
  background: #5865F2;
  color: #fff;
  border-color: #5865F2;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.btn-discord:hover {
  background: #4752C4;
  border-color: #4752C4;
  color: #fff;
}

.btn-oauth.btn-discord {
  background: var(--color-bg);
  color: var(--color-text);
  border-color: var(--color-border);
  gap: 0.625rem;
}

.btn-oauth.btn-discord:hover {
  background: var(--color-surface-hover);
  border-color: #5865f2;
  color: var(--color-text);
}

.campaign-system-badge {
  display: inline-block;
  font-size: 0.8125rem;
  color: var(--color-accent);
  background: rgba(124, 58, 237, 0.15);
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  overflow-wrap: anywhere;
}

/* === Invite Page === */
.invite-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.invite-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2.5rem;
  width: 100%;
  max-width: 480px;
  box-shadow: var(--shadow);
}

.invite-header {
  text-align: center;
  margin-bottom: 2rem;
}

.invite-header .logo {
  display: block;
  margin-bottom: 1rem;
  font-size: 1.75rem;
}

.invite-header h1 {
  font-size: 1.125rem;
  font-weight: 400;
  color: var(--color-text-muted);
}

.invite-campaign-card {
  background: rgba(124, 58, 237, 0.08);
  border: 1px solid rgba(124, 58, 237, 0.4);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1.75rem;
}

.invite-campaign-card h2 {
  font-size: 1.25rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  overflow-wrap: anywhere;
}

.invite-campaign-card .campaign-system-badge {
  display: inline-block;
  margin-bottom: 0.875rem;
}

.invite-description {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  margin-bottom: 0;
  overflow-wrap: anywhere;
}

.invite-card-divider {
  border: none;
  border-top: 1px solid rgba(124, 58, 237, 0.25);
  margin: 0.875rem 0;
}

.invite-card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}

.invite-meta {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

.invite-gm {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

.invite-join-btn {
  width: 100%;
  margin-bottom: 1rem;
}

.invite-restricted {
  text-align: center;
  padding: 1rem;
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: var(--radius);
}

.invite-restricted-msg {
  color: var(--color-text);
  font-size: 0.9375rem;
  margin: 0;
}

.invite-signin-prompt {
  text-align: center;
  margin-bottom: 1rem;
  color: var(--color-text-muted);
}

.invite-expiry {
  text-align: center;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: 1.5rem;
}

/* ==============================
   Dashboard
   ============================== */
.app-header {
  padding: 0.75rem 0;
  background: linear-gradient(
    180deg,
    rgba(124, 58, 237, 0.06) 0%,
    rgba(15, 17, 23, 0.95) 100%
  );
  border-bottom: 1px solid rgba(124, 58, 237, 0.12);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  position: sticky;
  top: 0;
  z-index: 100;
}

/* app_header_controller adds this when the header would cover more than a
   quarter of the viewport (large text wraps it to several rows). It scrolls
   away with the page instead of pinning that much of the screen. */
.app-header--static {
  position: static;
}

.app-header .container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.app-nav {
  position: relative;
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

/* ── Top-level nav link (e.g. My Availability) ──────── */
.app-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.625rem;
  border-radius: var(--radius);
  color: var(--color-text-muted);
  font-size: 0.875rem;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s, background 0.15s;
}

.app-nav__link:hover,
.app-nav__link:focus-visible {
  color: var(--color-text);
  background: var(--color-surface-hover);
}

.app-nav__link-icon {
  flex-shrink: 0;
  opacity: 0.8;
}

/* Icon-only on narrow screens; the link keeps its aria-label for the name. */
@media (max-width: 600px) {
  .app-nav__link-label {
    display: none;
  }
}

/* ── Trial CTA (inline, next to avatar) ─────────────── */
/* Wraps so that, with no room beside the days text (a phone's large-text
   setting doubles the root size), the Upgrade button drops under it instead
   of pushing the whole page sideways. With room, nothing wraps and there is no
   row gap, so the pill is pixel-identical to before. */
.trial-cta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 8px;
  border: 1px solid var(--color-border);
  border-radius: 9999px;
  overflow: hidden;
}

.trial-cta__days {
  padding: 0.3125rem 0.75rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  background: var(--color-surface);
  white-space: nowrap;
}

/* Dark on amber, matching .btn-amber. White on this orange was 3.18:1 at 12px
   bold, under the 4.5:1 that non-large text needs; this pair is 8.1:1. */
.trial-cta__btn {
  max-width: 100%;
  padding: 0.3125rem 0.875rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: #1a1a1a;
  background: var(--color-amber);
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.15s;
}

.trial-cta__btn:hover {
  background: color-mix(in srgb, var(--color-amber) 85%, #000);
}

/* On a phone the banner (about 198px) cannot sit beside the logo, the icon and
   the user menu: together they ran to 435px in a 375px viewport. It takes a
   row of its own under them instead, so the wording stays as it is. The nav
   wraps; the banner is a full-width item ordered last, which is the line
   break. */
@media (max-width: 600px) {
  .app-header .container:has(.trial-cta) {
    align-items: flex-start;
  }

  .app-nav:has(.trial-cta) {
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 0.5rem;
  }

  .trial-cta {
    order: 1;
    flex: 0 0 100%;
  }

  .trial-cta__days {
    flex: 1;
  }

  /* The second row makes the sticky header about 102px tall, not 65px. This
     is the first-paint value; app_header_controller replaces it with the
     measured height. */
  html:has(.trial-cta) {
    --app-header-height: 103px;
  }
}

.tier-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.125rem 0.5rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-success);
  background: rgba(78, 234, 194, 0.1);
  border: 1px solid rgba(78, 234, 194, 0.4);
  border-radius: 9999px;
  line-height: 1.4;
}

.tier-pill--trial {
  color: var(--color-text-muted);
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.15);
}

/* ── Nav avatar ─────────────────────────────────────── */
.nav-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.nav-avatar--placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ── User dropdown menu ────────────────────────────── */
/* The menu hangs from the trigger, not the nav: a trial account's nav is two
   rows tall on a phone, and the nav's bottom edge is under the banner. */
.user-menu {
  position: relative;
  display: flex;
}

.user-menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.375rem 0.75rem;
  color: var(--color-text-muted);
  font-size: 0.875rem;
  font-family: inherit;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.user-menu-trigger:hover,
.user-menu-trigger:focus-visible {
  color: var(--color-text);
  border-color: var(--color-text-muted);
}

.user-menu-caret {
  opacity: 0.5;
  transition: transform 0.15s;
}

.user-menu-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  min-width: 10rem;
  overflow: hidden;
}

.user-menu-item {
  display: block;
  width: 100%;
  padding: 0.5rem 0.875rem;
  background: none;
  border: none;
  color: var(--color-text);
  font-size: 0.8125rem;
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.1s;
}

.user-menu-item:hover {
  background: var(--color-surface-hover);
}

.user-menu-item--danger {
  color: #ef4444;
}

.user-menu-item--danger:hover {
  background: rgba(239, 68, 68, 0.1);
}

.user-menu-dropdown form {
  display: block;
}

.dashboard {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.dashboard-content {
  flex: 1;
  padding: 3rem 0;
}

.dashboard-content h1 {
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 0;
}

.dashboard-content p {
  color: var(--color-text-muted);
}

.dashboard-heading {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
}

/* Phone: the title takes the whole line and the button drops below it at full
   width, so neither wraps to two lines. */
@media (max-width: 480px) {
  .dashboard-heading {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }

  .dashboard-heading .btn {
    width: 100%;
  }
}

/* Campaign role filter (pill-shaped segmented control on dashboard) */
.campaign-role-filter {
  display: flex;
  justify-content: center;
  margin-bottom: 1.5rem;
}

.campaign-role-filter__control {
  display: inline-flex;
  background: var(--color-surface-raised);
  border-radius: 999px;
  padding: 0.25rem;
  gap: 0.125rem;
}

.campaign-role-filter__control .segment-btn {
  flex: 0 0 auto;
  border-radius: 999px;
  padding: 0.4375rem 1rem;
  font-size: 0.8125rem;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}

.campaign-role-filter__control .segment-btn + .segment-btn {
  border-left: none;
}

.campaign-role-filter__control .segment-btn[aria-pressed="true"] {
  box-shadow: 0 1px 4px color-mix(in srgb, var(--color-primary) 40%, transparent);
}

/* Campaign Cards */
.campaign-list {
  display: grid;
  gap: 1rem;
}

.campaign-card {
  display: block;
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--card-pad);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.campaign-card:hover {
  border-color: var(--color-primary);
  background: var(--color-surface-hover);
  text-decoration: none;
}

/* A request still waiting on the GM: nothing to open, so no hover. */
.campaign-card--pending:hover {
  border-color: var(--color-border);
  background: var(--color-surface);
}

/* Its own grid, so it needs its own gap above whatever follows it. */
.campaign-list--pending {
  margin-bottom: 1rem;
}

/* The sentence is the card's last line; the description's bottom margin would
   leave it with more room below than above. */
.campaign-card--pending .campaign-card-desc {
  margin-bottom: 0;
}

.campaign-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.campaign-card-title {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-wrap: wrap;
  min-width: 0;
}

.campaign-card-name {
  font-size: 1.125rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.campaign-card-system {
  display: inline-block;
  font-size: 0.75rem;
  color: var(--color-accent);
  background: rgba(124, 58, 237, 0.15);
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  min-width: 0;
}

.campaign-card-status {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.1875rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  flex-shrink: 0;
}

.campaign-card-status--paused,
.campaign-card-status--pending,
.campaign-card-status--onboarding {
  background: rgba(245, 158, 11, 0.15);
  color: var(--color-amber);
}

.campaign-card-status--archived {
  background: rgba(156, 163, 175, 0.12);
  color: var(--color-text-muted);
}

.campaign-card-pills {
  display: flex;
  gap: 0.375rem;
  flex-shrink: 0;
  align-items: center;
}

.campaign-card-scheduling-pill--green {
  background: color-mix(in srgb, var(--color-success) 15%, transparent);
  color: var(--color-success);
}

.campaign-card-scheduling-pill--auto {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  background: color-mix(in srgb, var(--color-auto) 12%, transparent);
  color: var(--color-auto);
}

.campaign-card-scheduling-pill--amber {
  background: color-mix(in srgb, var(--color-amber) 15%, transparent);
  color: var(--color-amber);
}

.campaign-card-scheduling-pill--muted {
  background: rgba(156, 163, 175, 0.12);
  color: var(--color-text-muted);
}

.campaign-card-desc {
  color: var(--color-text-muted);
  font-size: 0.875rem;
  margin-bottom: 1rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.campaign-card-action-needed {
  margin-bottom: 0.5rem;
}

.campaign-card-action-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  background: color-mix(in srgb, var(--color-amber) 15%, transparent);
  color: var(--color-amber);
}

/* Pending requests badge on campaign show header */
.pending-requests-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.55rem;
  border-radius: 4px;
  background: color-mix(in srgb, var(--color-amber) 15%, transparent);
  color: var(--color-amber);
  animation: pending-pulse 2s ease-in-out infinite;
}

.pending-requests-badge svg {
  flex-shrink: 0;
}

@keyframes pending-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

.campaign-card-stats {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}

.campaign-stat {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.campaign-stat-label {
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.campaign-stat-value {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text);
}

.campaign-stat-value--empty {
  color: var(--color-text-muted);
  font-style: italic;
}

.campaign-card-role {
  position: absolute;
  bottom: 0;
  right: 0;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-top: 1px solid var(--color-border);
  border-left: 1px solid var(--color-border);
  border-top-left-radius: 8px;
  border-bottom-right-radius: 11px;
  padding: 0.3rem 0.75rem 0.375rem;
  transition: border-color 0.15s ease;
}

.campaign-card-role--gm {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}

.campaign-card-role--player {
  color: var(--color-text-muted);
  background: color-mix(in srgb, var(--color-text-muted) 12%, transparent);
}

.campaign-card:hover .campaign-card-role {
  border-color: var(--color-primary);
}

.campaign-day-chips {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.campaign-day-chip {
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 0.125rem 0.375rem;
  border-radius: 4px;
}

.campaign-day-chip--preferred {
  background: rgba(124, 58, 237, 0.2);
  color: var(--color-accent);
}

.campaign-day-chip--if-need-be {
  background: rgba(124, 58, 237, 0.07);
  color: var(--color-text-muted);
}

/* Empty State */
.empty-state {
  text-align: center;
  padding: 4rem 2rem;
  background: var(--color-surface);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

.empty-state h2 {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.empty-state p {
  color: var(--color-text-muted);
  margin-bottom: 1.5rem;
  max-width: 400px;
  margin-left: auto;
  margin-right: auto;
}

/* ==============================
   Campaign Pages
   ============================== */
.campaign-page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.campaign-page > main {
  flex: 1;
}

.container-narrow {
  max-width: 768px;
}

.container-pricing {
  max-width: 1060px;
}

/* Forms */
.campaign-form-content {
  padding: 3rem 0;
}

.campaign-form-content h1 {
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 2rem;
}

.campaign-form {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.form-row-pair {
  display: flex;
  gap: 0.75rem;
}

.form-row-pair-item {
  min-width: 0;
}

.form-row-pair-item:first-child {
  flex: 3;
}

.form-row-pair-item:last-child {
  flex: 2;
}

.form-row-pair-item .form-input {
  width: 100%;
  box-sizing: border-box;
}

.form-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text);
}

.form-required {
  color: var(--color-danger);
  margin-left: 0.125rem;
}

.form-hint {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  margin-bottom: 0.25rem;
}

/* Onboarding intro block — new campaigns only */
.form-intro {
  border-left: 2px solid var(--color-accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: rgba(167, 139, 250, 0.06);
  padding: 0.875rem 1rem 0.875rem 1.125rem;
  margin-bottom: 1.75rem;
}

.form-intro-heading {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-accent);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 0.625rem;
}

.form-intro-steps {
  list-style: none;
  padding: 0;
  margin: 0 0 0.625rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.form-intro-step {
  font-size: 0.875rem;
  color: var(--color-text);
  line-height: 1.45;
  padding-left: 1.125rem;
  position: relative;
}

.form-intro-step::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--color-accent);
  font-size: 0.75rem;
  line-height: 1.65;
}

.form-intro-note {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  line-height: 1.55;
  margin: 0;
}

.form-error {
  font-size: 0.8125rem;
  color: #fca5a5;
  margin-top: 0.375rem;
}

.form-input {
  width: 100%;
  box-sizing: border-box;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.625rem 0.75rem;
  font-size: 0.9375rem;
  color: var(--color-text);
  font-family: inherit;
  line-height: 1.5;
  transition: border-color 0.15s ease;
}

.form-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2);
}

.form-input-locked {
  opacity: 0.55;
  cursor: not-allowed;
}

.form-input-locked:focus {
  border-color: var(--color-border);
  box-shadow: none;
}

.form-select {
  width: 100%;
  box-sizing: border-box;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.625rem 2.25rem 0.625rem 0.75rem;
  font-size: 0.9375rem;
  color: var(--color-text);
  font-family: inherit;
  line-height: 1.5;
  transition: border-color 0.15s ease;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.625rem center;
  cursor: pointer;
}

.form-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2);
}

.form-select option {
  background: var(--color-surface);
  color: var(--color-text);
}

.form-input::placeholder {
  color: var(--color-text-muted);
}

.form-textarea {
  resize: vertical;
  min-height: 80px;
}

.form-input--short {
  width: 6rem;
}

.form-group--inline {
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
}

/* Party quorum — segmented toggle + stepper drawer */
.quorum-widget {
  display: inline-flex;
  flex-direction: column;
  align-self: flex-start;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  overflow: hidden;
  margin-top: 0.5rem;
}

.segment-control {
  display: flex;
}

.segment-btn {
  flex: 1;
  padding: 0.4375rem 1.125rem;
  background: transparent;
  border: none;
  color: var(--color-text-muted);
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 500;
  text-align: center;
  transition: background 0.15s, color 0.15s;
}

.segment-btn + .segment-btn {
  border-left: 1px solid var(--color-border);
}

/* Every .segment-btn carries aria-pressed, and the highlight reads it, so what is
   highlighted is always what screen readers announce as selected. */
.segment-btn[aria-pressed="true"] {
  background: var(--color-primary);
  color: #fff;
}

.segment-btn:hover:not([aria-pressed="true"]) {
  background: var(--color-surface-raised);
  color: var(--color-text);
}

/* Animated drawer */
.segment-drawer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.2s ease;
}

.segment-drawer.is-open {
  grid-template-rows: 1fr;
}

.segment-drawer-inner {
  overflow: hidden;
}

/* Custom stepper (shared by quorum drawer + cadence widget) */
.stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
}

/* Separator line only when stepper is inside the quorum drawer (not time drawers) */
[data-campaign-form-target="minPlayersDetail"] .stepper {
  border-top: 1px solid var(--color-border);
}

.stepper-btn {
  width: 1.875rem;
  height: 1.875rem;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: 0.375rem;
  color: var(--color-text);
  cursor: pointer;
  font-size: 1.125rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
  user-select: none;
}

.stepper-btn:hover {
  background: var(--color-border);
}

.stepper-btn:active {
  transform: scale(0.92);
}

/* At the end of its range. Left clickable so it still reads as a control,
   rather than disabled, which gives no hint why it stopped. */
.stepper-btn--spent {
  opacity: 0.35;
}

.stepper-display {
  min-width: 1.25rem;
  text-align: center;
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
}

/* Cadence widget — segmented mode toggle + stepper row (mirrors quorum-widget pattern) */
.cadence-widget {
  display: inline-flex;
  flex-direction: column;
  align-self: flex-start;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  overflow: hidden;
  margin-top: 0.5rem;
}

.cadence-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.625rem;
  padding: 0.4375rem 0.875rem;
}

.cadence-flex-options {
  padding: 0.25rem 0.875rem;
}

.cadence-label {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.cadence-period-select {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.3125rem 2rem 0.3125rem 0.625rem;
  font-size: 0.9375rem;
  color: var(--color-text);
  font-family: inherit;
  line-height: 1.5;
  transition: border-color 0.15s ease;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
  cursor: pointer;
}

.cadence-period-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2);
}

.cadence-period-select option {
  background: var(--color-surface);
  color: var(--color-text);
}

/* Drift option drawer — slides in below cadence widget for every_n_weeks mode */
.cadence-drift-wrap {
  margin-top: 0.125rem;
}

/* Side-by-side radio row */
.cadence-drift-options {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.5rem 0 0.375rem;
}

.cadence-drift-label {
  font-size: 0.875rem;
  color: var(--color-text-muted);
  margin-right: 0.25rem;
}

.cadence-radio-hint {
  margin-top: 0.125rem;
}

/* Locked start-date display (edit form) */
.form-static-value {
  font-size: 1rem;
  color: var(--color-text);
  margin: 0.25rem 0 0;
}

/* Date picker widget — custom button triggers hidden native input */
.date-picker-widget {
  position: relative;
  display: inline-block;
  margin-top: 0.375rem;
}

.date-picker-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.date-picker-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5625rem 0.875rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
  text-align: left;
}

.date-picker-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-text);
}

.date-picker-btn--has-value {
  color: var(--color-text);
}

/* Day Chips */
.day-legend {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin-bottom: 0.5rem;
}

.day-legend-customize {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.day-legend-item {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.day-legend-chip {
  min-width: 1.5rem !important;
  padding: 0.125rem 0.375rem !important;
  font-size: 0.6875rem !important;
  pointer-events: none;
}

.day-chips {
  display: flex;
  gap: 0.375rem;
  align-items: flex-start;
}

.day-chip-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
}

.day-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  background: none;
  border: none;
  padding: 0;
}

.day-chip-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: unset;
  padding: 0.5rem 0.25rem;
  font-size: 0.8125rem;
  font-weight: 500;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text-muted);
  transition: all 0.15s ease;
  position: relative;
  overflow: hidden;
}

.day-chip:hover .day-chip-label {
  border-color: var(--color-text-muted);
}

/* Preferred — full colour */
.day-chip--preferred .day-chip-label {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* If need be — dimmed tint */
.day-chip--if-need-be .day-chip-label {
  background: rgba(124, 58, 237, 0.25);
  border-color: rgba(124, 58, 237, 0.55);
  color: var(--color-text-muted);
}

/* Never — diagonal slash */
.day-chip--never .day-chip-label::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom right,
    transparent calc(50% - 0.75px),
    var(--color-border) calc(50% - 0.75px),
    var(--color-border) calc(50% + 0.75px),
    transparent calc(50% + 0.75px)
  );
}

/* ── Play Times (unified with Days to Play) ────────────────────────────────── */

/* Per-chip time drawer content */
.day-time-content {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.375rem 0.125rem 0.125rem;
}

.form-input--time-chip {
  width: 100%;
  padding: 0.25rem 0.125rem;
  font-size: 0.75rem;
  text-align: center;
  color-scheme: dark;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text);
  font-family: inherit;
}

.form-input--time-chip:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2);
}

/* Spaces the session window rows from the Priority setting below them. Holds
   only the hidden day_time_slots field, so the margin is all that shows. */
.day-times-footer {
  margin-top: 0.5rem;
}

.time-slot-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.time-slot-label {
  min-width: 4.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

.form-input--time {
  width: 7.5rem;
  padding: 0.4375rem 0.625rem;
  font-size: 0.875rem;
  color-scheme: dark;
  text-align: center;
}

.form-input--time::-webkit-datetime-edit,
.form-input--time-chip::-webkit-datetime-edit {
  text-align: center;
}

.time-flex-sep {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

/* Compact stepper (used for ± controls and per-chip duration) */
.stepper--compact {
  gap: 0.25rem;
  padding: 0;
}

.stepper--compact .stepper-btn {
  width: 1.5rem;
  height: 1.5rem;
  font-size: 0.875rem;
}

.stepper--compact .stepper-display {
  min-width: 2.5rem;
  font-size: 0.8125rem;
}

/* Small stepper variant (per-chip duration in narrow columns) */
.stepper-btn--sm {
  width: 1.375rem;
  height: 1.375rem;
  font-size: 0.75rem;
  padding: 0;
}

.stepper-display--sm {
  min-width: 2rem;
  font-size: 0.75rem;
  text-align: center;
}

/* Fixed width for duration displays so the +/− buttons don't shift position.
   Sized to fit the longest possible output ("7h 45m"). */
.stepper-display--duration       { width: 4.5rem; }
.stepper-display--sm.stepper-display--duration { width: 3.5rem; }

/* Flex options rows in footer (checkbox + conditional ± stepper) */
.times-flex-options {
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0.125rem 0;
}

/* Horizontal slide wrapper for flex steppers */
.flex-stepper-wrap {
  display: grid;
  grid-template-columns: 0fr;
  overflow: hidden;
  transition: grid-template-columns 200ms ease;
}

.flex-stepper-wrap.is-open {
  grid-template-columns: 1fr;
}

.flex-stepper-inner {
  overflow: hidden;
  display: flex;
  align-items: center;
  padding-left: 0.5rem;
  opacity: 0;
  transition: opacity 150ms ease 50ms;
}

.flex-stepper-wrap.is-open .flex-stepper-inner {
  opacity: 1;
}

/* ── Custom checkbox ── */
input[type="checkbox"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 1.125rem;
  height: 1.125rem;
  min-width: 1.125rem;
  border: 2px solid var(--color-text-muted);
  border-radius: 4px;
  background: var(--color-bg);
  cursor: pointer;
  position: relative;
  vertical-align: middle;
  margin-top: -0.1em;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

input[type="checkbox"]:checked {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
}

input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.5rem;
  height: 0.3rem;
  border: solid #fff;
  border-width: 0 0 2px 2px;
  transform: translate(-50%, -60%) rotate(-45deg);
}

input[type="checkbox"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.3);
}

input[type="checkbox"]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.form-checkbox {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  cursor: pointer;
}

.form-checkbox input[type="checkbox"] {
  align-self: flex-start;
  margin-top: 0.1875em;
}

/* ── Custom radio ── */
input[type="radio"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 1.125rem;
  height: 1.125rem;
  min-width: 1.125rem;
  border: 2px solid var(--color-text-muted);
  border-radius: 50%;
  background: var(--color-bg);
  cursor: pointer;
  position: relative;
  vertical-align: middle;
  margin-top: -0.1em;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

input[type="radio"]:checked {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
}

input[type="radio"]:checked::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.5rem;
  height: 0.5rem;
  background: #fff;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

input[type="radio"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.3);
}

input[type="radio"]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Checkbox (skip holidays) */
.form-check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}

.form-check-input {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0;
}

.form-check-label {
  font-size: 0.9375rem;
  color: var(--color-text);
}

.form-check-input:disabled ~ .form-check-label {
  opacity: 0.4;
  cursor: not-allowed;
}

.form-check:has(.form-check-input:disabled) {
  cursor: not-allowed;
  opacity: 0.4;
}


/* ── Help Center ─────────────────────────────────────────────── */
/* Prose styling comes from .legal-content, which the help views also carry. */
.help-hero {
  margin-bottom: 2.5rem;
}

.help-hero-subtitle {
  color: var(--color-text-muted);
  margin-bottom: 1.5rem;
}

.help-search {
  position: relative;
}

.help-search-icon {
  position: absolute;
  left: 0.85rem;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--color-text-muted);
  pointer-events: none;
}

.help-search-input {
  padding-left: 2.5rem;
}

.help-empty {
  padding: 2rem;
}

.help-category {
  margin-bottom: 2.5rem;
}

.help-category-title {
  font-size: 1.25rem;
  margin-bottom: 0.25rem;
}

.help-category-description {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

.help-article-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Outranks .legal-content a, which underlines prose links but not these cards. */
.legal-content .help-article-link {
  text-decoration: none;
}

.help-article-link {
  display: block;
  padding: 1rem 1.15rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.help-article-link:hover,
.help-article-link:focus-visible {
  background: var(--color-surface-hover);
  border-color: var(--color-primary);
}

.help-article-title {
  display: block;
  color: var(--color-text);
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.help-article-summary {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.help-support-cta,
.signup-cta {
  margin-top: 3rem;
  padding: var(--card-pad-roomy);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-align: center;
}

.help-support-cta h2 {
  font-size: 1.1rem;
  margin-bottom: 0.4rem;
}

.help-support-cta p {
  color: var(--color-text-muted);
  margin-bottom: 1.25rem;
}

/* Accent border so it does not read as the support CTA sitting above it. */
.signup-cta {
  border-color: var(--color-primary);
}

.signup-cta h2 {
  font-size: 1.1rem;
  margin-bottom: 1.25rem;
}

/* Article page */
.help-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.875rem;
  color: var(--color-text-muted);
  margin-bottom: 1.25rem;
}

.help-breadcrumb a {
  color: var(--color-accent);
  text-decoration: none;
}

.help-breadcrumb a:hover {
  text-decoration: underline;
}

.help-article h1 {
  font-size: 1.85rem;
  margin-bottom: 1.75rem;
}

.help-article-body ol {
  margin-bottom: 1rem;
  padding-left: 1.5rem;
}

.help-article-body ol li {
  margin-bottom: 0.35rem;
}

/* A generated screenshot (help_screenshot). The app is dark and so is this
   page, so the screenshot would melt into it without its ring. The width and
   height attributes reserve the space; height: auto keeps the ratio when the
   column is narrower than the image. */
.help-screenshot {
  margin: 1.25rem 0 1.75rem;
}

.help-screenshot img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.help-article-body code {
  padding: 0.1rem 0.35rem;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  font-size: 0.875em;
}

.help-table-scroll {
  overflow-x: auto;
  margin-bottom: 1rem;
}

/* The scroll-fade controller sets .is-more-right while columns are hidden past
   the right edge. A mask fades the last 24px into whatever sits behind the
   table, so it matches the card background in both themes. Off at the end of
   the scroll and whenever the table fits, which is every desktop width. */
.help-table-scroll.is-more-right {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
}

.help-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.help-table th,
.help-table td {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.help-table thead th {
  background: var(--color-surface-raised);
}

.help-table tbody th {
  color: var(--color-text-muted);
  font-weight: 500;
  white-space: nowrap;
}

/* ── Self-linking article headings ────────────────────────────── */
/* The heading text is a link to its own anchor, so a reader can copy the URL
   for the exact section that answered them. */
.help-article-body .help-heading-link {
  color: inherit;
  text-decoration: none;
}

.help-article-body .help-heading-link:hover {
  text-decoration: underline;
}

.help-related {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--color-border);
}

.help-related h2 {
  font-size: 1rem;
  margin-bottom: 0.75rem;
}

.help-related ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.help-related a {
  color: var(--color-accent);
}

/* ── Contextual help affordance ───────────────────────────────── */
/* A "?" next to a setting, linking to the article that explains it.
   Opens in a new tab so a reader mid-form keeps their draft and their place.

   The glyph is a fixed 14px everywhere (18px only beside an h1 page title),
   independent of the surrounding heading's own font-size: an h3 panel header
   and a form label get the same "?" as the h1 above them, instead of each
   scaling to its context. The link itself is a full 24x24 hit area (WCAG
   2.5.8) with negative vertical margins, so that box doesn't add to the
   height of the header or label line it sits in. */
.help-hint {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin: -5px 0 -5px 1px;
  vertical-align: middle;
  color: var(--color-text-muted);
  text-decoration: none;
  border-radius: 50%;
  transition: color 0.15s ease;
}

.help-hint:hover,
.help-hint:focus-visible {
  color: var(--color-accent);
}

/* No focus-ring rule here: .help-hint renders as a plain <a>, already
   covered by base.css's global a:focus-visible (same outline and offset).
   A component-local copy would be pure duplication, and silently drift
   from the shared ring if that one ever changes. */

.help-hint svg {
  display: block;
  width: 14px;
  height: 14px;
}

/* Beside an h1 page title only, a touch bigger to match its weight. The
   24px box pads an 18px glyph by only 3px a side here, narrower than the
   5px a side around the default 14px glyph, so the left margin grows to
   keep the same 6px visible gap after the title text. */
h1 .help-hint {
  margin: -3px 0 -3px 3px;
}

h1 .help-hint svg {
  width: 18px;
  height: 18px;
}

/* Keeps a label and its "?" together as one unit, so a flex sibling (an
   action button, a "+ Add") can't land between them the way it did in
   .panel-title--with-action, where the label text and the hint were each
   their own flex item and justify-content: space-between spread them apart.
   Deliberately no white-space: nowrap: the grouping alone keeps the hint
   glued right after the label text, and leaving ordinary wrapping on means
   a long label (translated text, 200% zoom) still reflows inside the panel
   instead of forcing it to overflow horizontally - measured: with nowrap,
   a large enough font pushed the whole panel wider than its column. */
.label-with-hint {
  display: inline-flex;
  align-items: center;
}

/* The hint is a direct child of a flex row that already spaces its items
   with `gap` (the availability legend): its own left margin would double
   up on that gap. Dropping the margin to 0 still leaves the VISIBLE glyph
   25px from the previous item (the flex gap's 20px, plus the 24px hit
   box's own 5px of padding around the 14px glyph): -5px pulls the box
   back by exactly that padding, landing the glyph itself one gap away,
   the same distance as every other legend item. */
.help-hint--flush {
  margin-left: -5px;
}

/* A hint inside running prose, paired with the short trailing phrase it
   explains (help_hint's block form): nowrap is what actually stops a
   browser from breaking a line before the hint's own atomic inline box,
   which happens even with no whitespace there at all. Keep the paired
   phrase short - the last word, or a whole link's text - never a full
   sentence, or the unbreakable span would overflow instead of wrapping. */
.help-hint-glue {
  white-space: nowrap;
}



/* Brief cue so a reader arriving from a "?" can see which section answered
   their question, rather than guessing where the page stopped. */
.help-article-body h2:target {
  animation: help-section-landed 2.4s ease-out;
  border-radius: var(--radius);
}

@keyframes help-section-landed {
  0%, 55% {
    background: rgba(var(--color-primary-rgb), 0.18);
    box-shadow: -0.75rem 0 0 rgba(var(--color-primary-rgb), 0.18);
  }
  100% {
    background: transparent;
    box-shadow: -0.75rem 0 0 transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .help-article-body h2:target {
    animation: none;
    background: rgba(var(--color-primary-rgb), 0.14);
    box-shadow: -0.75rem 0 0 rgba(var(--color-primary-rgb), 0.14);
  }

  .toast {
    transition: none;
  }
}



/* The heading itself takes focus after a fragment jump; that is a programmatic
   focus, not a keyboard one, so it should not draw a focus ring. */
.help-article-body h2:focus {
  outline: none;
}

.help-heading-symbol {
  display: inline-block;
  vertical-align: middle;
  width: 0.7em;
  height: 0.7em;
  margin-left: 0.4rem;
  color: var(--color-text-muted);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.help-article-body h2:hover .help-heading-symbol,
.help-heading-link:focus-visible .help-heading-symbol {
  opacity: 1;
}

/* Touch devices have no hover, so the affordance would never appear. */
@media (hover: none) {
  .help-heading-symbol {
    opacity: 1;
  }
}


/* ── Guides ──────────────────────────────────────────────────── */
/* Guide pages carry the help center's prose classes (.legal-content,
   .help-article-body, .help-related) and its self-linking headings, and
   .guide-page on <main> gives them their own look on top: Sourcebook, a
   well-set rulebook on the site's dark page, with Fraunces for display and
   Literata for reading (declared in base.css, preloaded only on guide pages).
   Every rule is scoped to .guide-page or to a class only guides use, so the
   help center and legal pages keep their look. .legal-content's element rules
   weigh (0,1,1), which is why a few rules here carry two classes. */
.guide-page {
  --guide-display: "Fraunces", Georgia, "Times New Roman", serif;
  --guide-text: "Literata", Georgia, "Times New Roman", serif;
  --guide-heading: #f3ecdf;
  --guide-body: #dcd6cb;
  --guide-soft: #b8b2c7;
  --guide-link: #c4b5fd;
  --guide-size-l: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  /* A d20 between two rules, as a background: centred, 220 by 24. */
  --guide-d20: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='24' viewBox='0 0 220 24' fill='none' stroke='%23a78bfa' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M0 12h86M134 12h86' stroke-opacity='.5'/%3E%3Cpath d='M110 2l9 5v10l-9 5-9-5V7z'/%3E%3Cpath d='M110 7l5 8h-10z'/%3E%3C/svg%3E") center top / 220px 24px no-repeat;
  --guide-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  position: relative;
}

/* Faint dice behind the top of the page. The layout's own .dice-bg needs its
   inline script, which a visitor's first page view blocks: the CSP nonce comes
   from a session they do not have yet. Search brings guides first visits. */
.guide-page::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 34rem;
  background: url("/assets/dice-pattern-d08514d2.webp") 0 0 / 425px 300px;
  opacity: 0.05;
  -webkit-mask-image: linear-gradient(#000 30%, transparent);
  mask-image: linear-gradient(#000 30%, transparent);
  pointer-events: none;
}

.guide-page > .container {
  position: relative;
}

/* About 70 characters a line at the body size. */
.guide-page .container-narrow {
  max-width: 728px;
}

.guide-page :is(h1, h2) {
  font-family: var(--guide-display);
  font-weight: 600;
  color: var(--guide-heading);
  text-wrap: balance;
}

.guide-page h1 {
  margin-bottom: 1rem;
  font-size: clamp(2.25rem, 1.4rem + 3vw, 3.625rem);
  line-height: 1.06;
  letter-spacing: -0.01em;
}

/* The guide's description, standing under its title. */
.guide-page .guide-dek {
  max-width: 34em;
  margin-bottom: 1rem;
  font-family: var(--guide-display);
  font-style: italic;
  font-size: clamp(1.1875rem, 1rem + 0.6vw, 1.375rem);
  line-height: 1.45;
  color: var(--guide-soft);
  text-wrap: pretty;
}

.guide-page .guide-published {
  margin-bottom: 0;
  font-family: "Space Grotesk", sans-serif;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}

/* The small capitals over the contents and over a script. */
.guide-page .guide-contents-label,
.guide-script figcaption {
  font-family: "Space Grotesk", sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.guide-page .guide-contents-label {
  margin-bottom: 0.85rem;
}

.guide-script figcaption {
  margin-bottom: 0.5rem;
}

/* "In this guide": the sections, read from the rendered article. */
.guide-contents {
  margin: 2.25rem 0 3rem;
  padding: 1.25rem 0 1.5rem;
  border-block: 4px double var(--color-border);
}

.guide-contents ol {
  margin: 0;
  padding-left: 2.25rem;
  columns: 2;
  column-gap: 2.5rem;
  list-style: upper-roman;
}

.guide-contents li {
  margin-bottom: 0.5rem;
  break-inside: avoid;
  font-family: var(--guide-display);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.35;
}

.guide-contents a {
  color: var(--guide-heading);
  text-decoration: none;
}

.guide-contents a:hover {
  text-decoration: underline;
}

/* Italic accent numerals: the contents, the sections, numbered lists, sources. */
.guide-contents li::marker,
.guide-body h2::before,
.guide-body ol > li::marker,
.guide-sources > li::marker {
  font-family: var(--guide-display);
  font-style: italic;
  font-weight: 400;
  color: var(--color-accent);
}

/* The article */
.guide-body {
  counter-reset: guide-section;
  font-family: var(--guide-text);
  font-size: 1.1875rem;
  line-height: 1.72;
  color: var(--guide-body);
}

.guide-body p,
.guide-body ul,
.guide-body ol {
  margin-bottom: 1.1em;
  color: inherit;
}

.guide-body strong {
  font-weight: 600;
  color: var(--guide-heading);
}

/* Prose links only; :where keeps the weight at (0,1,1), so the section
   headings' own links keep the help center's look, hover included. */
.guide-body a:where(:not(.help-heading-link)) {
  color: var(--guide-link);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
}

.guide-body a:where(:not(.help-heading-link)):hover {
  text-decoration-color: currentColor;
}

/* Every guide opens with a three-line drop cap, set on the baselines. */
.guide-body > p:first-child::first-letter {
  margin-right: 0.12em;
  font-family: var(--guide-display);
  font-weight: 600;
  color: var(--color-accent);
  -webkit-initial-letter: 3;
  initial-letter: 3;
}

/* Where initial-letter is missing (Firefox), a float stands in. */
@supports not ((initial-letter: 3) or (-webkit-initial-letter: 3)) {
  .guide-body > p:first-child::first-letter {
    float: left;
    margin: 0.06em 0.1em 0 0;
    font-size: 5.8em;
    line-height: 0.78;
  }
}

.guide-body h2 {
  counter-increment: guide-section;
  margin: 3rem 0 1rem;
  font-size: clamp(1.625rem, 1.25rem + 1.2vw, 2.125rem);
  line-height: 1.2;
}

.guide-body h2::before {
  content: counter(guide-section, upper-roman) ".";
  margin-right: 0.4em;
}

/* The d20 between the opening and the first section sits in the margin above
   the heading, not in its box, which the :target highlight repaints. */
.guide-body > h2:first-of-type {
  position: relative;
  margin-top: 6.5rem;
}

.guide-body > h2:first-of-type::after {
  content: "";
  position: absolute;
  inset: -4.5rem 0 auto;
  height: 24px;
  background: var(--guide-d20);
}

/* A string marker keeps a list a list to screen readers, which
   list-style: none would not in Safari. */
.guide-body ul {
  padding-left: 1.4rem;
  list-style-type: "\25C6";
}

.guide-body li {
  margin-bottom: 0.5em;
}

.guide-body ul > li {
  padding-left: 0.6rem;
}

.guide-body ul > li::marker {
  font-size: 0.7em;
  color: var(--color-accent);
}

.guide-body ol {
  padding-left: 1.75rem;
}

/* Two elements and a class, to meet .help-article-body ol li. */
.guide-body ol > li {
  margin-bottom: 0.5em;
  padding-left: 0.25rem;
}

/* A rulebook sidebar, for a short list a guide wants to stand apart. */
.guide-body .guide-sidebar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem 2rem;
  margin: 1.5rem 0 2rem;
  padding: 1.75rem 2rem;
  list-style: none;
  font-size: 1.0625rem;
  line-height: 1.6;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-top: 3px double var(--color-accent);
  border-radius: 6px;
}

.guide-body .guide-sidebar > li {
  margin: 0;
  padding: 0;
  color: #cfc9be;
}

.guide-body .guide-sidebar strong {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--guide-display);
  font-size: 1.25rem;
  line-height: 1.3;
}

/* A line a GM can paste into their group chat. */
.guide-script {
  position: relative;
  margin: 1.75rem 0 2rem;
  padding: 1.5rem 0 1.5rem 3.5rem;
  border-block: 1px solid var(--color-border);
}

.guide-script blockquote {
  margin: 0;
}

/* Decoration: the empty alt text keeps screen readers from announcing it. */
.guide-script blockquote::before {
  content: "\201C";
  content: "\201C" / "";
  position: absolute;
  top: 1.1rem;
  left: 0;
  font-family: var(--guide-display);
  font-weight: 600;
  font-size: 5rem;
  line-height: 1;
  color: var(--color-accent);
}

.guide-body .guide-script p {
  margin: 0;
  font-family: var(--guide-display);
  font-style: italic;
  font-size: var(--guide-size-l);
  line-height: 1.35;
  color: var(--guide-heading);
  text-wrap: balance;
}

/* After the article: sources, help links, the sign-up panel. */
.guide-page .help-related {
  margin-top: 3.5rem;
  font-family: var(--guide-text);
}

.guide-page .help-related h2 {
  margin-bottom: 1rem;
  font-size: 1.375rem;
}

.guide-page .help-related a {
  color: var(--guide-link);
}

/* The d20 again, closing the article before its sources. Every d20 is a
   pseudo-element: axe judges contrast past those (ignorePseudo in the guides
   audit), but not through an element's own background image. */
.guide-page .guide-sources-block {
  position: relative;
  margin-top: 4rem;
  padding-top: 4.5rem;
  border-top: 0;
}

.guide-page .guide-sources-block::before,
.guide-hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 24px;
  background: var(--guide-d20);
}

.guide-sources {
  margin: 0;
  padding-left: 2rem;
  line-height: 1.55;
}

.guide-page .guide-sources > li {
  margin-bottom: 0.75rem;
}

.guide-source-meta {
  font-style: italic;
  color: var(--color-text-muted);
}

/* The first line is the fallback for browsers without alt text on content. */
.guide-help-links a::after {
  content: "\2192";
  content: "\2192" / "";
  margin-left: 0.4em;
}

.guide-page .signup-cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-top: 4rem;
  padding: 3rem 2rem 3.25rem;
  border-color: var(--color-border);
}

.guide-page .signup-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("/assets/dice-pattern-d08514d2.webp") center / 425px 300px;
  opacity: 0.06;
}

/* margin-top: 0, or .legal-content h2's 2rem sits on top of the panel's padding. */
.guide-page .signup-cta h2 {
  margin-top: 0;
  margin-bottom: 1.5rem;
  font-size: var(--guide-size-l);
  line-height: 1.25;
}

.guide-page .guide-trademark {
  margin-top: 2rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
  text-align: center;
}

/* /guides: a table of contents. */
.guide-hero {
  position: relative;
  margin-bottom: 3rem;
  padding-top: 4rem;
  text-align: center;
}

.guide-hero h1 {
  font-size: clamp(2.75rem, 1.5rem + 4.5vw, 4.5rem);
  line-height: 1.04;
}

.guide-page .guide-hero-subtitle {
  max-width: 34em;
  margin: 0 auto;
  font-family: var(--guide-text);
  font-size: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);
  line-height: 1.6;
  color: var(--guide-soft);
  text-wrap: balance;
}

.guide-page .guide-list {
  margin: 0;
  padding-left: 0;
  list-style: none;
  border-block: 4px double var(--color-border);
}

.guide-page .guide-list > li {
  margin: 0;
}

.guide-list > li + li {
  border-top: 1px solid var(--color-border);
}

.guide-page .guide-list-link {
  position: relative;
  display: block;
  padding: 1.75rem 3.5rem 1.75rem 0;
  text-decoration: none;
}

.guide-list-link:focus-visible {
  outline-offset: 4px;
}

.guide-list-link::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0.25rem;
  width: 1.5rem;
  height: 1.5rem;
  background: var(--color-accent);
  -webkit-mask: var(--guide-arrow);
  mask: var(--guide-arrow);
  translate: 0 -50%;
  transition: translate 0.15s ease;
}

.guide-list-link:hover::after {
  translate: 0.25rem -50%;
}

.guide-list-title {
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--guide-display);
  font-weight: 600;
  font-size: var(--guide-size-l);
  line-height: 1.2;
  color: var(--guide-heading);
}

.guide-list-link:hover .guide-list-title {
  color: #fff;
}

.guide-list-summary {
  display: block;
  max-width: 36em;
  font-family: var(--guide-text);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--guide-soft);
}

.guide-list-meta {
  display: block;
  margin-top: 0.75rem;
  font-family: "Space Grotesk", sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .guide-list-link::after {
    transition: none;
  }
}

/* The tools page (pages/tools): a card for each free tool, in the guides' look.
   A grid that fits as many as there is room for, so one card is the width of
   the page and a second sits beside it (or under it, on a phone). */
.guide-page .tool-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.guide-page .tool-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 0;
  padding: var(--card-pad-roomy);
  border: 1px solid rgba(124, 58, 237, 0.25);
  border-radius: 1.25rem;
  /* A plain colour, not a gradient: the accessibility audit cannot judge text on a gradient. */
  background: var(--color-surface);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

/* The pill sits beside the heading, not inside it (held item 1, 2026-10-17):
   a sibling row, not inline text a screen reader would fold into the name. */
.tool-card__heading {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-wrap: wrap;
}

.guide-page .tool-card h2 {
  margin: 0;
  font-size: var(--guide-size-l);
  line-height: 1.2;
}

.guide-page .tool-card p {
  max-width: 36em;
  margin: 0;
  font-family: var(--guide-text);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--guide-soft);
}

/* At the foot of its card, so the buttons of cards side by side line up. */
.guide-page .tool-card .btn {
  margin-top: auto;
}

/* A tool that needs a word of context beyond its own description (Lines &
   Veils, part b): a small badge beside the title, and a muted note under
   the button for whoever this tool is not quite right for. */
.tool-card__pill {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: 9999px;
  vertical-align: middle;
}

/* Secondary to the card's own description (Design Lead, 2026-10-17): a
   hairline divider sets it apart rather than reading as a second paragraph
   of the pitch above it. The note is itself a <p>, so .guide-page .tool-card p
   (round 7) outranked a bare .tool-card__note on specificity alone (two
   classes vs. two classes plus the element) and won the cascade — round 8
   fix, 2026-10-17: repeat the element here so this one wins instead.
   No opacity (CI's accessibility audit, round 9, 2026-10-17): it dims a
   descendant link's own color along with the text, and the note's one link
   (Learn more) landed at 4.44:1 against the page background, under the
   4.5:1 axe requires — the hairline divider plus --guide-soft is secondary
   enough on its own, the link needs its full color to stay readable. */
.guide-page .tool-card p.tool-card__note {
  max-width: 36em;
  margin: 0.25rem 0 0;
  padding-top: 0.875rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-family: var(--guide-text);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--guide-soft);
}

@media (max-width: 640px) {
  .guide-body {
    font-size: 1.125rem;
  }

  .guide-contents ol {
    columns: 1;
  }

  .guide-body .guide-sidebar {
    grid-template-columns: minmax(0, 1fr);
    padding: 1.25rem;
  }

  .guide-script {
    padding-left: 2.5rem;
  }

  .guide-script blockquote::before {
    top: 1.35rem;
    font-size: 3.75rem;
  }

  .guide-page .guide-list-link {
    padding-right: 2.25rem;
  }
}
