/* Fancall — deliberately plain. Neutral branding, nothing identifying anyone.
   Design system: tokens below; spacing rhythm is 8px inside a group, 16px
   between groups, 32px + hairline between sections. One filled primary button
   per screen; red appears ONLY when something actually failed. */
:root {
  /* spacing */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  /* radii */
  --r: 12px; --r-sm: 8px; --r-pill: 999px;
  /* type */
  --fs-xs: .8rem; --fs-sm: .875rem; --fs-md: 1.05rem; --fs-lg: 1.35rem;
  /* color */
  --bg: #14141a; --surface: #1d1d25; --surface2: #2a2a33; --line: #2c2c36;
  --text: #eee; --text2: #bbb; --text3: #999;
  --accent: #3b5bdb; --link: #8fa8ff;
  --ok: #7ddc9a; --warn: #ffc478; --err: #ff8b98; --danger: #b02a37;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: -apple-system, system-ui, sans-serif;
  background: var(--bg); color: var(--text);
  display: flex; flex-direction: column; align-items: center;
}
.card {
  width: 100%; max-width: 420px; padding: var(--s5) 20px; margin-top: 4vh;
  padding-bottom: calc(var(--s5) + env(safe-area-inset-bottom));
}
h1 { font-size: var(--fs-lg); margin-bottom: var(--s4); font-weight: 600; }
/* Header row: page title left, a quiet utility link (Settings) right. */
.toprow { display: flex; justify-content: space-between; align-items: center; }
.toprow a {
  font-size: var(--fs-sm); color: var(--link); text-decoration: none;
  display: inline-flex; align-items: center; min-height: 44px; padding-left: var(--s3);
}
p { line-height: 1.45; color: var(--text2); margin-bottom: var(--s3); }

/* Buttons. Hierarchy: one filled primary per screen; secondary for the normal
   alternative; quiet for navigation; quiet+danger for destructive text-actions
   (Cancel, Decline, Log out); filled danger only inside a call (End). */
button, a.btn {
  font-size: 1rem; font-weight: 600; padding: 12px 18px; border: 0; border-radius: var(--r);
  background: var(--accent); color: #fff; cursor: pointer; width: 100%; margin-top: var(--s2);
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
}
button.secondary, a.btn.secondary { background: var(--surface2); font-weight: 500; }
button.quiet, a.btn.quiet {
  background: none; border: 1px solid var(--line); color: var(--link); font-weight: 500;
}
button.quiet.danger, a.btn.quiet.danger { color: var(--err); background: none; border: 1px solid var(--line); }
button.danger { background: var(--danger); }
button.armed, a.btn.armed { background: #7a1e28; color: #fff; outline: 2px solid var(--err); border: 0; }
button:disabled { background: var(--surface2); color: var(--text3); opacity: 1; cursor: default; }
.btnrow { display: flex; gap: var(--s2); } .btnrow > * { flex: 1; margin: 0; }

input[type=text], input[type=number], input[type=url], input[type=email], input[type=password] {
  width: 100%; padding: 12px; font-size: 1rem; border-radius: var(--r);
  border: 1px solid #333; background: var(--surface); color: var(--text); margin-top: var(--s2);
  min-height: 48px;
}
textarea {
  width: 100%; padding: 12px; font-size: 1rem; border-radius: var(--r);
  border: 1px solid #333; background: var(--surface); color: var(--text); margin-top: var(--s2);
  font-family: inherit; resize: vertical;
}
.durations { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }
.durations button { margin: 0; background: var(--surface2); font-weight: 500; }
.durations button.sel { background: var(--accent); font-weight: 600; }
.linkbox {
  background: var(--surface); border: 1px solid #333; border-radius: var(--r);
  padding: var(--s3); word-break: break-all; font-size: .95rem; margin: var(--s3) 0 0;
  cursor: pointer;
}

/* Notices: one job each. Base = quiet hint. warn = heads-up, nothing broken.
   error = an action actually failed. ok = success. */
.notice { font-size: var(--fs-sm); color: var(--text3); line-height: 1.5; }
.notice.error { color: var(--err); }
.notice.ok { color: var(--ok); }
.notice.warn { color: var(--warn); }
/* Legal / recording / no-payment text: always visible, calm, set apart. */
.fineprint {
  font-size: var(--fs-sm); color: var(--text3); line-height: 1.5;
  border-left: 2px solid var(--line); padding-left: var(--s3); margin: var(--s4) 0;
}
.fineprint a { color: var(--link); }
.fineprint p { color: inherit; font-size: inherit; line-height: inherit; margin-bottom: 6px; }
.fineprint p:last-child { margin-bottom: 0; }

/* Spacing utilities — instead of inline style="margin-top:…" */
.mt2 { margin-top: var(--s2); } .mt3 { margin-top: var(--s3); }
.mt4 { margin-top: var(--s4); } .mt5 { margin-top: var(--s5); }

/* Back navigation: always a top-left quiet link above the title. */
.backlink {
  display: inline-flex; align-items: center; min-height: 44px; padding-right: var(--s3);
  color: var(--link); text-decoration: none; font-size: var(--fs-sm);
}
/* A standalone link that acts like a row: no underline, full tap height. */
a.rowlink {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--link); text-decoration: none; font-size: var(--fs-sm);
}
/* Her page link on home: URL left, Copy right, one comfortable row. */
.pagelink { display: flex; align-items: center; gap: var(--s2); font-size: var(--fs-sm); }
.pagelink .pageurl {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text2);
}
.pagelink a {
  color: var(--link); text-decoration: none; flex: none;
  display: inline-flex; align-items: center; min-height: 44px; padding-left: var(--s3);
}

/* Shared footer: the legal links, once per page, roomy enough to tap. */
.foot {
  margin-top: var(--s6); padding-top: var(--s3); border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--text3);
}
.foot a {
  color: var(--link); text-decoration: none; display: inline-block;
  padding: 12px 14px 12px 0;
}

/* A bounded card that groups related controls (home's page block). */
.boxed {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: var(--s4);
}

/* Settings page: plain sections divided by a rule, no nested screens. */
.settinghead {
  font-size: var(--fs-md); font-weight: 600; margin: var(--s6) 0 var(--s1); padding-top: var(--s4);
  border-top: 1px solid var(--line);
}
.handlerow { display: flex; align-items: center; gap: 6px; }
.handlerow input { flex: 1; }
.handleprefix { color: var(--text3); font-size: .95rem; white-space: nowrap; }

/* Her public page (fancall.gg/<handle>) */
.blurb { color: var(--text2); white-space: pre-wrap; overflow-wrap: break-word; }

/* Her links: chips on the public page and under the fan's chat,
   and the label+url editor rows on /settings. */
.linkchips { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s3) 0 var(--s1); }
.linkchip {
  display: inline-flex; align-items: center; padding: 10px 16px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid #3a3a46; color: var(--link);
  text-decoration: none; font-size: .9rem; min-height: 44px;
}
.linkline { display: flex; gap: 6px; margin-top: var(--s2); }
.linkline .linkurl { flex: 1; min-width: 0; }
.linkline .linkdel {
  flex: none; width: 48px; min-height: 48px; margin: 0; padding: 0;
  background: none; border: 1px solid var(--line); color: var(--text3); font-weight: 400;
}
button.linkadd { margin-top: var(--s2); }

/* Call requests: the list on home, and the setup chat on both sides. */
.reqhead { font-size: 1rem; margin: 0 0 var(--s2); }
.reqrow {
  display: block; width: 100%; text-align: left; margin: 0 0 var(--s2);
  background: #1d3a1f; border: 1px solid #2f5c33; border-radius: var(--r);
  padding: var(--s3); padding-right: 96px; position: relative; cursor: pointer;
  font-weight: 400; min-height: 48px;
}
/* The whole row is tappable, but this little pill is what says so. */
.reqrow .reqgo {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-size: .85rem; font-weight: 600; color: #d9f2dc;
  background: #2f5c33; border-radius: var(--r-sm); padding: 8px 12px;
}
.reqrow .reqname { display: block; font-weight: 600; }
.reqrow .reqmeta {
  display: block; font-size: var(--fs-xs); color: #9fc7a5; font-weight: 400;
  margin-top: 2px; white-space: pre-wrap; overflow-wrap: break-word;
}
.chat {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r);
  height: 260px; overflow-y: auto; padding: 10px; margin: var(--s3) 0 var(--s2);
  display: flex; flex-direction: column; gap: 6px;
}
.bubble {
  max-width: 85%; padding: 8px 12px; border-radius: 14px; font-size: .95rem;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.bubble.me { align-self: flex-end; background: var(--accent); color: #fff; }
.bubble.them { align-self: flex-start; background: #2a2a34; color: var(--text); }
.bubble.sys {
  align-self: center; background: none; color: var(--text3); font-size: var(--fs-xs);
  text-align: center;
}
.bubble.typing { display: inline-flex; align-items: center; gap: 4px; padding: 11px 13px; }
.bubble.typing .dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--text3);
  animation: typingdot 1.2s infinite ease-in-out;
}
.bubble.typing .dot:nth-child(2) { animation-delay: .2s; }
.bubble.typing .dot:nth-child(3) { animation-delay: .4s; }
@keyframes typingdot {
  0%, 60%, 100% { opacity: .35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}
/* The unread badge for "What's new" — a red circle with a "!", no number,
   no words. The ! lives in CSS so the pages stay markup-light. */
.newdot {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 50%;
  background: #e5484d; color: #fff; font-size: 12px; font-weight: 700;
  line-height: 1; margin-left: 7px; vertical-align: -3px;
}
.newdot::before { content: '!'; }
.newdot.lead { margin-left: 0; margin-right: 8px; }
.asknote {
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--r); padding: 10px 12px; margin: var(--s2) 0 var(--s3);
  white-space: pre-wrap; overflow-wrap: break-word;
}
.chatrow { display: flex; gap: var(--s2); }
.chatrow input { flex: 1; margin-top: 0; }
.chatrow button { width: auto; margin: 0; padding: 12px 16px; }
.callsetup { border-top: 1px solid var(--line); margin-top: var(--s4); padding-top: var(--s1); }

/* Phone alerts. One state showing at a time; the rest are .hidden. */
.pushbox {
  background: var(--surface); border: 1px solid #333; border-radius: var(--r);
  padding: 14px; margin-top: var(--s4);
}
.pushbox button { margin: var(--s1) 0 0; }
.steps { margin: var(--s2) 0 0; padding-left: 20px; font-size: var(--fs-sm); color: var(--text2); }
.steps li { margin-bottom: 6px; }
a.authlink { color: var(--link); }
.hidden { display: none !important; }

/* Legal pages (/terms, /privacy, /report) — long-form reading, wider and calmer. */
.card.legal { max-width: 640px; }
.legal h2 {
  font-size: 1.02rem; font-weight: 600; color: #e6e6ee;
  margin: 26px 0 10px; padding-top: 18px; border-top: 1px solid #26262f;
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; }
.legal p { margin-bottom: 12px; }
.legal ul { margin: 0 0 14px 20px; }
.legal li { line-height: 1.45; color: var(--text2); margin-bottom: 7px; }
.legal strong { color: #e6e6ee; }

/* Date-of-birth row on signup */
.dobrow { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--s2); }
.dobrow select, .dobrow input {
  width: 100%; padding: 12px; font-size: 1rem; border-radius: var(--r);
  border: 1px solid #333; background: var(--surface); color: var(--text); margin-top: var(--s2);
  font-family: inherit; min-height: 48px;
}
.fieldlabel { font-size: var(--fs-sm); color: var(--text2); font-weight: 600; margin: var(--s4) 0 0; display: block; }
.fieldhint { font-size: var(--fs-sm); color: var(--text3); margin: 2px 0 0; }

/* Idea box on the creator page, and the ideas board at /ideas */
.ideabox { margin-top: var(--s6); border-top: 1px solid var(--line); padding-top: var(--s4); }
.ideabox h2 { font-size: 1rem; font-weight: 600; margin-bottom: var(--s2); }
.tabs { display: flex; gap: var(--s2); margin-bottom: var(--s4); }
.tabs button { margin: 0; background: var(--surface2); font-weight: 500; }
.tabs button.sel { background: var(--accent); font-weight: 600; }
.idea {
  display: flex; gap: var(--s3); align-items: flex-start;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 12px 14px; margin-bottom: 10px;
}
.idea .body { flex: 1; min-width: 0; }
.idea .text { line-height: 1.45; white-space: pre-wrap; overflow-wrap: break-word; }
.idea .meta { font-size: var(--fs-xs); color: #8b8b96; margin-top: 6px; }
.idea .meta a { margin-left: var(--s2); }
.idea .reply {
  margin-top: var(--s2); padding: 8px 10px; background: #191922; border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0; font-size: .87rem; color: #c6c6d0; white-space: pre-wrap;
}
.vote {
  flex: none; width: 58px; margin: 0; padding: 8px 0; background: var(--surface2);
  border-radius: var(--r); text-align: center; line-height: 1.25; font-size: .78rem;
  font-weight: 500; min-height: 48px; display: block;
}
.vote.on { background: var(--accent); }
.vote .n { display: block; font-size: 1.1rem; font-weight: 600; }
.tag { font-size: .7rem; padding: 2px 7px; border-radius: var(--r-pill); background: var(--line); color: #b9b9c4; margin-left: 6px; }
.linkrow { font-size: var(--fs-sm); color: var(--text3); margin-bottom: 14px; }

/* Camera preview boxes (creator self-check, guest waiting room, join preview) */
.previewbox, #preview video {
  width: 100%; border-radius: var(--r); background: #000; margin: var(--s3) 0;
  min-height: 200px; max-height: 45vh; object-fit: cover; display: block;
}
/* The join screen caps its preview lower so preview + ticks + Join share one screen. */
.previewbox.short, #preview video { max-height: 30vh; min-height: 160px; }

/* Self-views mirror like a real mirror (front camera only — JS removes the
   class when the rear camera is on, so text in shot reads correctly). */
video.mirror { transform: scaleX(-1); }

/* In-call layout */
#callView { position: fixed; inset: 0; background: #000; }
#remoteVideo { width: 100%; height: 100%; object-fit: cover; background: #000; }
#localVideo {
  position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 12px;
  width: 26vw; max-width: 140px;
  border-radius: var(--r); border: 1px solid #444; background: #111;
}
#timer {
  position: absolute; top: calc(12px + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,.65); padding: 8px 18px; border-radius: var(--r-pill);
  font-size: 1.5rem; font-variant-numeric: tabular-nums; font-weight: 600;
}
/* The guest's name on the creator's call screen (top-left, out of the timer's way) */
#guestNameTag {
  position: absolute; top: calc(16px + env(safe-area-inset-top)); left: 12px;
  background: rgba(0,0,0,.5); padding: 8px 14px; border-radius: var(--r-pill);
  font-size: .9rem; color: #eee; max-width: 34vw;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#timer.low { background: rgba(176,42,55,.85); }
#callStatus {
  position: absolute; top: calc(64px + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,.5); padding: 4px 12px; border-radius: var(--r-sm);
  font-size: .85rem; color: #ccc; white-space: nowrap;
}
.controls {
  position: absolute; bottom: calc(16px + env(safe-area-inset-bottom)); left: 0; right: 0;
  display: flex; justify-content: center; align-items: stretch; gap: var(--s2); padding: 0 10px;
}
.controls button {
  flex: 1; max-width: 110px; min-width: 0; min-height: 44px; margin: 0;
  padding: 10px 4px; font-size: .85rem; font-weight: 500; line-height: 1.15;
}
/* Kick sits beside End; the red text keeps them from reading as one pair. */
.controls #kickBtn { color: var(--err); }

/* Tick boxes — CONSENT ONLY (18+, terms). Settings-style on/off controls use
   label.switch instead. The label must have exactly TWO children — the box and
   one <span> holding all the text. Loose text and links directly inside a flex
   label each become their own column, which reads as broken. Always wrap the words. */
label.agree { display: flex; gap: 10px; align-items: flex-start; margin: var(--s3) 0; color: #ccc; font-size: .95rem; }
label.agree input { width: 22px; height: 22px; flex: none; margin-top: 1px; accent-color: var(--accent); }
label.agree span { flex: 1; line-height: 1.4; }
label.agree a { white-space: nowrap; color: var(--link); }

/* On/off switch — for settings that are true/false, never for consent.
   The input stays a real checkbox (same ids, .checked, .onchange), only drawn
   as a pill. Text on the left, switch on the right. */
label.switch { display: flex; align-items: center; gap: var(--s3); min-height: 48px; cursor: pointer; }
label.switch .swtext { flex: 1; font-weight: 600; line-height: 1.35; }
label.switch .swsub { display: block; font-weight: 400; font-size: var(--fs-sm); color: var(--text3); margin-top: 1px; }
label.switch input {
  appearance: none; -webkit-appearance: none; flex: none; width: 50px; height: 30px;
  border-radius: var(--r-pill); background: var(--surface2); position: relative;
  transition: background .15s; margin: 0; cursor: pointer;
}
label.switch input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px;
  border-radius: 50%; background: #fff; transition: transform .15s;
}
label.switch input:checked { background: var(--accent); }
label.switch input:checked::after { transform: translateX(20px); }

/* Expandable notes ("What's the trade-off?" etc.). Flex summaries drop the
   browser's ▶ marker, so we draw our own chevron. */
details.notice { margin: 2px 0 10px; }
details.notice summary { cursor: pointer; color: var(--link); min-height: 44px; display: flex; align-items: center; list-style: none; }
details.notice summary::-webkit-details-marker { display: none; }
details.notice summary::before { content: "▸"; margin-right: 8px; font-size: .8em; }
details.notice[open] summary::before { content: "▾"; }
details.notice p { font-size: var(--fs-sm); color: var(--text3); margin: var(--s2) 0 0; }

/* Hidden connection readout (tap the timer) */
#statsBox {
  position: absolute; top: calc(110px + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,.78); color: #b8e6b8; padding: 10px 14px; border-radius: var(--r);
  font-size: var(--fs-xs); line-height: 1.5; white-space: pre-line;
  font-variant-numeric: tabular-nums; max-width: 90vw;
}

/* End screen */
#endView {
  position: fixed; inset: 0; background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: var(--s5);
}
#endView .clock { font-size: 3rem; margin-bottom: var(--s3); }
#endView h1 { font-size: 1.6rem; }
#endView .brand { position: absolute; bottom: calc(24px + env(safe-area-inset-bottom)); color: #666; font-size: .85rem; }
