/* TickTalk beta — minimal sign-up + dashboard styling.
   Same neutral palette as the rest of the internal tool. */

.beta-narrow {
  max-width: 640px;
  margin: 24px auto;
  padding: 0 24px;
}

.panel.small { padding: 14px 18px; }
.panel.small h3 { margin: 0 0 6px; font-size: 14px; }

label.block { display: block; margin: 8px 0 16px; }
label.block > span { display: block; font-weight: 600; margin-bottom: 4px; }
label.block > input[type="text"] {
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
}

fieldset.consent {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 14px 12px;
  margin: 12px 0 16px;
}
fieldset.consent legend {
  padding: 0 6px;
  font-weight: 600;
}
.checkbox {
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: 8px;
  margin: 8px 0;
  cursor: pointer;
  align-items: start;
}
.checkbox input { margin-top: 3px; }
.checkbox.optional span::before {
  content: "Optional · ";
  color: var(--muted);
  font-weight: 600;
}

/* Beta pages: form-submit + claim CTAs default to accent-filled pills.
 * This block overrides style.css's ink-default button (intentional). The
 * Phase E rewrite will rationalise both ladders into a single primary +
 * secondary + tertiary system.
 */
button {
  font: inherit;
  padding: 8px 16px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--accent);
  color: var(--panel);
  font-weight: 600;
  cursor: pointer;
}
button:hover { filter: brightness(0.95); }
button[disabled] { opacity: 0.45; cursor: progress; }
button.secondary {
  background: var(--panel);
  color: var(--ink);
  border-color: var(--rule);
  font-weight: 500;
}

.dash-next {
  border-left: 4px solid var(--accent);
  background: var(--info-bg);
  padding: 12px 14px;
  border-radius: 6px;
  margin: 12px 0;
}
.dash-next h3 { margin: 0 0 4px; font-size: 14px; }
.dash-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin: 12px 0;
}
.dash-stat {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  text-align: center;
}
.dash-stat .num { font-size: 24px; font-weight: 600; }
.dash-stat .label { font-size: 12px; color: var(--muted); }

/* --- Phase E: picker-first home -------------------------------------------- */

main.home-wide {
  max-width: 920px;
}

.hero-panel {
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 32px;
  margin-bottom: 20px;
}
.hero-panel h2.hero {
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 1.05;
  letter-spacing: -0.015em;
  font-weight: 400;
  margin: 0 0 6px;
}
.hero-panel .hero-meta { margin: 0 0 20px; font-size: 14px; }

.speaker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}

/* --- U8: photo-dominant character cards ---------------------------------- *
 * The portrait IS the card; the name sits underneath as a small caption.
 * Replaces the prior chip-with-monogram-circle layout. Monogram fallback
 * lives under the <img> so `img.onerror` reveals it without flashing the
 * broken-image icon. Staggered fade-in animation on initial load uses a
 * CSS custom property `--i` set per card by beta_home.js.
 * --------------------------------------------------------------------- */

.character-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
}

.character-card,
.character-card-skeleton {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 14px;
  overflow: hidden;
  text-decoration: none;
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease,
              border-color 0.15s ease;
  opacity: 0;
  animation: charCardFadeIn 0.32s ease-out both;
  animation-delay: calc(var(--i, 0) * 60ms);
}

.character-card-skeleton {
  cursor: default;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  color: var(--muted);
}

@keyframes charCardFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .character-card { animation-duration: 0.001ms; animation-delay: 0ms; }
}

.character-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 8px 24px rgba(197, 54, 58, 0.12);
}

.character-card .character-portrait {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--ink);
  overflow: hidden;
}

.character-card .character-monogram {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 64px;
  font-weight: 500;
  color: var(--paper);
  letter-spacing: -0.02em;
  line-height: 1;
}

.character-card .character-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.character-card .character-name {
  padding: 12px 14px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.2;
  text-align: center;
}

.speaker-card,
.speaker-card-skeleton {
  display: grid;
  grid-template-columns: 56px 1fr;
  grid-template-rows: auto auto auto;
  column-gap: 14px;
  row-gap: 2px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 16px;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease;
  cursor: pointer;
}
.speaker-card-skeleton {
  color: var(--muted);
  text-align: center;
  align-items: center;
  display: flex;
  justify-content: center;
  cursor: default;
}
.speaker-card:hover {
  border-color: var(--accent);
  background: var(--accent-quiet);
  transform: translateY(-1px);
}
.speaker-card .speaker-mark {
  grid-row: 1 / 4;
  grid-column: 1;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
/* U3: portrait sits on top of the monogram; img.onerror removes it →
 * monogram visible underneath. No broken-image icon ever shows. */
.speaker-card .speaker-portrait {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
.speaker-card .speaker-monogram { line-height: 1; }
/* U3: chip badges between the name and the count meta line. */
.speaker-card .speaker-card-flags {
  grid-row: 2;
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
  margin-bottom: 2px;
}
.speaker-card-badge {
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--info-bg);
  color: var(--ink-soft);
  border: 1px solid var(--info-border);
}
.speaker-card-badge-cartoon {
  background: var(--warn-bg);
  color: var(--gold);
  border-color: var(--warn-border);
}
/* If chips render, push the meta line + cta one row down — the grid has
 * three flexible rows so this lands cleanly under the chips. */
.speaker-card:has(.speaker-card-flags) .speaker-meta { grid-row: 3; }
.speaker-card:has(.speaker-card-flags) .speaker-cta { grid-row: 4; }
.speaker-card .speaker-name {
  grid-row: 1;
  grid-column: 2;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.15;
}
.speaker-card .speaker-meta {
  grid-row: 2;
  grid-column: 2;
  font-size: 13px;
}
.speaker-card .speaker-cta {
  grid-row: 3;
  grid-column: 2;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  margin-top: 6px;
}

.rate-callout {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-left: 4px solid var(--gold);
  background: var(--warn-bg);
  padding: 14px 18px;
}
.rate-callout-body h3 { margin: 0 0 4px; font-size: 14px; }
.rate-callout-body .meta { margin: 0; }
.rate-callout .pill {
  background: var(--accent);
  color: var(--panel);
  border-color: var(--accent);
}

.dash-stats.four-up {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 768px) {
  .speaker-grid { grid-template-columns: 1fr; }
  .dash-stats.four-up { grid-template-columns: repeat(2, 1fr); }
  .hero-panel h2.hero { font-size: 32px; }
  .rate-callout { flex-direction: column; align-items: flex-start; }
}

/* ======================================================================
 * Signup page (/beta) — two-pane layout
 *
 * Left pane: dual-column vertical character marquee + tiny brand mark.
 * Right pane: focused signup card (username + privacy + Start).
 *
 * Everything is scoped under body.beta-signup-page so it can't leak into
 * the other beta surfaces (which still use .panel / .beta-narrow above).
 * ====================================================================== */

body.beta-signup-page {
  margin: 0;
  /* Lock to one viewport — no scroll. `dvh` (dynamic viewport height) accounts
   * for mobile browser chrome correctly; falls back to `vh` for older agents. */
  height: 100vh;
  height: 100dvh;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--paper);
  background-image:
    radial-gradient(ellipse 60% 50% at 0% 0%, rgba(197, 54, 58, 0.08), transparent 60%),
    radial-gradient(ellipse 50% 40% at 100% 100%, rgba(164, 124, 58, 0.06), transparent 70%);
  overflow: hidden;
}
body.beta-signup-page a { color: inherit; text-decoration: none; }
body.beta-signup-page img { display: block; max-width: 100%; }

.signup-split {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  height: 100%;
  gap: 0;
}

/* --- Left pane: gallery ------------------------------------------------ */

.signup-gallery {
  position: relative;
  padding: clamp(24px, 2.5vw, 40px) clamp(28px, 3.5vw, 56px) clamp(28px, 3vw, 44px);
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 2vw, 28px);
  overflow: hidden;
  border-right: 1px solid var(--rule);
  background: var(--paper);
  min-height: 0;     /* allow the marquee column to actually fill remaining */
}

.signup-brand {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  align-self: flex-start;
}
.signup-brand:hover { color: var(--accent); }

.gallery-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  padding: 6px 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--panel);
}
.gallery-eyebrow-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(197, 54, 58, 0.5);
  animation: galleryDotPulse 1.8s ease-in-out infinite;
}
@keyframes galleryDotPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(197, 54, 58, 0.45); }
  50%      { box-shadow: 0 0 0 6px rgba(197, 54, 58, 0); }
}

.gallery-marquees {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  min-height: 0;
  /* fade edges so the loop reads as endless */
  mask-image: linear-gradient(180deg, transparent 0%, black 8%, black 92%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, black 8%, black 92%, transparent 100%);
}

.gallery-col {
  position: relative;
  overflow: hidden;
}
.gallery-track {
  display: flex;
  flex-direction: column;
  gap: 22px;
  /* Two identical halves; shift by exactly -50% for seamless wrap. */
}
.gallery-col-up   .gallery-track { animation: galleryUp   48s linear infinite; }
.gallery-col-down .gallery-track { animation: galleryDown 56s linear infinite; }
@keyframes galleryUp {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}
@keyframes galleryDown {
  from { transform: translateY(-50%); }
  to   { transform: translateY(0); }
}
.gallery-col:hover .gallery-track { animation-play-state: paused; }

.gallery-tile {
  flex: 0 0 auto;
  position: relative;
  display: block;
  border-radius: 18px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: var(--accent-quiet);
  box-shadow: 0 6px 18px rgba(26, 24, 20, 0.08);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.gallery-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(60%) contrast(0.96);
  transition: filter 0.4s ease, transform 0.4s ease;
}
.gallery-tile b {
  position: absolute;
  left: 12px;
  bottom: 10px;
  right: 12px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  color: var(--paper);
  letter-spacing: 0.01em;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
  /* gradient bottom-fade behind the name so it stays legible regardless of
   * portrait colours */
  padding: 22px 0 0;
  background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.55) 90%);
  border-bottom-left-radius: 18px;
  border-bottom-right-radius: 18px;
}
.gallery-tile:hover img {
  filter: grayscale(0%) contrast(1);
  transform: scale(1.03);
}

/* Stagger column offset so the right-going-down column starts mid-cycle —
 * adds visual rhythm rather than two perfectly mirrored tracks. */
.gallery-col-down .gallery-track { padding-top: 120px; }

/* --- Right pane: signup ----------------------------------------------- */

.signup-pane {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(24px, 3vw, 56px) clamp(28px, 4vw, 64px);
  background: var(--paper);
  position: relative;
  overflow: hidden;
  min-height: 0;
}
/* subtle warm wash to differentiate the form pane from the gallery */
.signup-pane::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 60% at 30% 40%, rgba(197, 54, 58, 0.05), transparent 60%);
  pointer-events: none;
}

.signup-card {
  position: relative;
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 1.8vw, 22px);
}

.signup-headline {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(34px, 4.4vw, 64px);
  letter-spacing: -0.03em;
  line-height: 0.96;
  margin: 0;
  color: var(--ink);
}
.signup-headline em {
  font-style: italic;
  color: var(--accent);
  font-variation-settings: "wght" 600, "SOFT" 100, "WONK" 1;
}

.signup-sub {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.1vw, 17px);
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.5;
  max-width: 44ch;
}

.signup-form {
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.4vw, 18px);
  margin-top: 4px;
}

.signup-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.signup-field-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.signup-field input {
  width: 100%;
  font-family: var(--font-body);
  font-size: 16px;            /* >=16px prevents iOS auto-zoom on focus */
  padding: 13px 14px;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--panel);
  color: var(--ink);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.signup-field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px rgba(197, 54, 58, 0.15);
}
.signup-field input::placeholder { color: var(--muted); opacity: 0.7; }

.signup-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.45;
  cursor: pointer;
}
.signup-consent input[type="checkbox"] {
  margin-top: 2px;
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
}
.signup-consent a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

.signup-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: 999px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(197, 54, 58, 0.25);
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.signup-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 36px rgba(197, 54, 58, 0.35);
}
.signup-btn:disabled {
  opacity: 0.6;
  cursor: progress;
  transform: none;
  box-shadow: 0 10px 28px rgba(197, 54, 58, 0.2);
}
.signup-btn-arrow { transition: transform 0.18s ease; }
.signup-btn:hover:not(:disabled) .signup-btn-arrow { transform: translateX(4px); }

.signup-status {
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px;
  min-height: 18px;
}
.signup-status.err { color: var(--err-border); }
.signup-status.ok  { color: var(--ok-border); }

.signup-fine {
  margin: 6px 0 0;
  font-family: var(--font-body);
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.55;
  letter-spacing: 0.005em;
}

/* --- Invite-token (hidden by default; JS reveals on ?t=…) -------------- */

.invite-pane {
  position: fixed;
  inset: 0;
  background: rgba(26, 24, 20, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 80;
  padding: 24px;
}
.invite-pane[hidden] { display: none; }

.invite-card {
  width: 100%;
  max-width: 420px;
  background: var(--panel);
  border-radius: 18px;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}
.invite-headline {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink);
}
.invite-card .rebind-toggle {
  margin-top: 6px;
  color: var(--muted);
}

/* --- Responsive collapse -------------------------------------------- */

/* Horizontal split holds through tablet landscape. Only mobile portrait
 * (≤700px) stacks. Even when stacked, height is still 100dvh — we just
 * give the gallery a fixed share so the form pane is guaranteed to fit. */
@media (max-width: 700px) {
  .signup-split {
    grid-template-columns: 1fr;
    /* 38vh gallery / 62vh form — form pane always reaches the user without
     * scrolling, gallery still shows ~3 portrait tiles. */
    grid-template-rows: 38dvh 62dvh;
    grid-template-rows: 38vh 62vh;
  }
  .signup-gallery {
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    padding: 18px 20px 16px;
    gap: 14px;
  }
  .gallery-marquees { gap: 12px; }
  .gallery-track { gap: 12px; }
  .gallery-tile b { font-size: 12px; left: 10px; bottom: 8px; right: 10px; }
  .signup-brand { font-size: 22px; }

  .signup-pane { padding: 24px 22px 28px; }
  .signup-card { gap: 14px; }
  .signup-headline { font-size: clamp(32px, 8vw, 44px); }
  .signup-sub { font-size: 14px; }
  .signup-fine { font-size: 11px; }
  .signup-btn { padding: 13px 22px; font-size: 15px; }
}

/* Very narrow phones: drop to a single marquee column so portraits stay
 * usefully sized */
@media (max-width: 380px) {
  .gallery-marquees { grid-template-columns: 1fr; }
  .gallery-col-down { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .gallery-track { animation: none; }
  .gallery-eyebrow-dot { animation: none; }
  .signup-btn:hover { transform: none; }
  .gallery-tile:hover img { transform: none; }
}
