:root {
  color-scheme: light;
  --bg: #f6f6fb;
  --panel: #ffffff;
  --panel-alt: #f0eefc;
  --border: #e3e1f0;
  --text: #1a1a2e;
  --muted: #6b7085;
  --accent: #a63cc4;
  --accent-strong: #8f2fab;
  --accent-contrast: #ffffff;
  --bubble-me: #a63cc4;
  --bubble-me-text: #ffffff;
  --bubble-them: #f0eefc;
  --bubble-them-text: #1a1a2e;
  --danger: #b42318;
  --danger-bg: #fdecea;
  --success: #1e7e34;
  --success-bg: #e6f4ea;
  --online-dot: #22c55e;
  --shadow: 0 4px 16px rgba(30, 20, 60, 0.08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    /* "Velvet Plum" - deep plum/purple, warmer and moodier than the old
       flat indigo, picked after comparing three candidates against real
       chat content. */
    --bg: #17121e;
    --panel: #221b2c;
    --panel-alt: #2c2338;
    --border: #3a2e49;
    --text: #f0eaf7;
    --muted: #a99bbd;
    --accent: #b83fd6;
    --accent-strong: #c95ee0;
    --accent-contrast: #ffffff;
    --bubble-me: #b83fd6;
    --bubble-me-text: #ffffff;
    --bubble-them: #2c2338;
    --bubble-them-text: #f0eaf7;
    --danger: #ff6b60;
    --danger-bg: #3a1f1f;
    --success: #4ade80;
    --success-bg: #1c3324;
    --online-dot: #34d399;
    --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #17121e;
  --panel: #221b2c;
  --panel-alt: #2c2338;
  --border: #3a2e49;
  --text: #f0eaf7;
  --muted: #a99bbd;
  --accent: #b83fd6;
  --accent-strong: #c95ee0;
  --accent-contrast: #ffffff;
  --bubble-me: #b83fd6;
  --bubble-me-text: #ffffff;
  --bubble-them: #2c2338;
  --bubble-them-text: #f0eaf7;
  --danger: #ff6b60;
  --danger-bg: #3a1f1f;
  --success: #4ade80;
  --success-bg: #1c3324;
  --online-dot: #34d399;
  --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}

* { box-sizing: border-box; }

/* Baseline for every text input/textarea/select in the app - previously
   only <input> had explicit styling via more specific rules like
   .auth-form input, so a plain <textarea> or <select> (e.g. the bio field,
   the feedback category picker) fell back to the browser's default
   white-background styling, which looks broken in dark mode. Those more
   specific rules still win where they exist; this is just the floor. */
input, textarea, select {
  font-family: inherit;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 16px; /* iOS auto-zoom guard, same reasoning as elsewhere */
}
textarea { width: 100%; resize: vertical; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
}

a { color: var(--accent); }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 10px 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}

.brand {
  font-weight: 700; letter-spacing: -0.01em; color: var(--text); text-decoration: none;
  display: inline-flex; align-items: center; gap: 8px; font-size: 1.05rem;
}
.brand-icon { width: 24px; height: 24px; flex-shrink: 0; }

.topbar nav { display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; }
.topbar nav a {
  color: var(--accent); text-decoration: none; font-size: 0.92rem;
  padding: 6px 2px; /* taller tap target without changing visual line-height */
}
.whoami { color: var(--muted); font-size: 0.9rem; }

.theme-toggle {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 20px;
  padding: 5px 12px;
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1.4;
}

.link-button {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  font-size: 1rem;
  padding: 0;
}

.inline-form { display: inline; }

.flashes { list-style: none; margin: 0; padding: 10px 20px; }
.flash { padding: 8px 12px; border-radius: 6px; margin-bottom: 6px; font-size: 0.9rem; }
.flash-error { background: var(--danger-bg); color: var(--danger); }
.flash-success { background: var(--success-bg); color: var(--success); }

main { padding: 20px; max-width: 1000px; margin: 0 auto; }

.site-footer {
  max-width: 1000px;
  margin: 0 auto;
  padding: 16px 20px 24px;
  font-size: 0.8rem;
  color: var(--muted);
  text-align: center;
}
.site-footer a { color: var(--muted); }

/* --- Connection status banner --- */
.connection-banner {
  max-width: 1000px;
  margin: 0 auto 12px;
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 0.85rem;
  background: var(--danger-bg);
  color: var(--danger);
  text-align: center;
}

.cookie-banner {
  position: fixed;
  left: 16px; right: 16px; bottom: 16px;
  max-width: 640px; margin: 0 auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  box-shadow: var(--shadow);
  z-index: 1500;
}
.cookie-banner h3 { margin: 0 0 8px; font-size: 0.95rem; }
.cookie-banner p { margin: 0 0 10px; font-size: 0.83rem; color: var(--muted); line-height: 1.5; }
.cookie-banner p a { color: var(--accent); }

.policy-page { max-width: 560px; text-align: left; align-items: stretch; }
.policy-page h3 { font-size: 0.95rem; margin: 18px 0 6px; }
.policy-page p, .policy-page li { font-size: 0.88rem; color: var(--text); line-height: 1.55; }
.policy-page ul { margin: 6px 0; padding-left: 20px; }
.policy-notice {
  background: var(--panel-alt); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; font-size: 0.83rem; color: var(--muted); line-height: 1.5;
}
.cookie-banner-buttons { display: flex; gap: 10px; justify-content: flex-end; }
.cookie-banner-buttons button { padding: 8px 16px; border: none; border-radius: 8px; font-size: 0.88rem; cursor: pointer; }

/* --- Layout --- */
.chat-layout {
  display: flex;
  gap: 16px;
  height: calc(100vh - 140px);
  /* dvh accounts for mobile browsers' collapsing/expanding address bar -
     100vh on phones is measured against the *largest* possible viewport,
     so content ends up hidden behind the toolbar until dvh support kicks
     in. Repeated as a second declaration (not a fallback value in one
     line) since a browser that doesn't understand dvh ignores the whole
     declaration and keeps the vh one above. */
  height: calc(100dvh - 140px);
  min-height: 400px;
}

.user-list {
  width: 260px;
  flex-shrink: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px;
  overflow-y: auto;
  box-shadow: var(--shadow);
}

.user-list h2 { font-size: 0.85rem; margin: 0; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.section-heading-secondary { margin: 16px 0 10px !important; padding-top: 12px; border-top: 1px solid var(--border); }
#recently-active-users li.recently-active { opacity: 0.7; }
#recently-active-users li.recently-active:hover { opacity: 1; }

.user-list-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 8px; }
.user-list-header .link-button { font-size: 0.78rem; white-space: nowrap; }

/* --- Sidebar tabs: Directory (who's reachable now) vs Chats (everyone
   already messaged, regardless of current status) - see chat.js/chat.py
   for why these are two genuinely different lists, not just a filter. --- */
.sidebar-tabs { display: flex; gap: 4px; margin-bottom: 10px; }
.sidebar-tab {
  flex: 1;
  padding: 8px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.sidebar-tab:hover { background: var(--panel-alt); }
.sidebar-tab.active { background: var(--accent); color: var(--accent-contrast); }

#chats-list { list-style: none; margin: 0; padding: 0; }
.chat-entry {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  min-height: 44px;
  border-radius: 10px;
  cursor: pointer;
}
.chat-entry:hover { background: var(--panel-alt); }
.chat-entry.active { background: var(--accent); color: var(--accent-contrast); }
.chat-entry-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.chat-entry-name-row { display: flex; align-items: center; gap: 6px; }
.chat-entry-preview {
  font-size: 0.8rem;
  color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-entry.active .chat-entry-preview { color: var(--accent-contrast); opacity: 0.85; }

.network-panel-overlay {
  position: fixed; inset: 0;
  background: rgba(10, 10, 20, 0.55);
  align-items: center; justify-content: center;
  z-index: 1800; padding: 20px;
}
/* Same specificity as the browser's built-in [hidden]{display:none}, and
   this stylesheet loads after the UA one - so a bare `display: flex` above
   would always win, leaving an invisible full-page overlay silently
   swallowing every click even while "hidden". Scoping display to :not(
   [hidden]) lets the built-in rule through when the attribute is set. */
.network-panel-overlay:not([hidden]) { display: flex; }
.network-panel {
  background: var(--panel);
  border-radius: 14px;
  box-shadow: var(--shadow);
  width: 100%; max-width: 520px;
  max-height: 80vh;
  padding: 20px;
  display: flex; flex-direction: column; gap: 4px;
}
.network-panel-header { display: flex; align-items: center; justify-content: space-between; }
.network-panel-header h2 { margin: 0; font-size: 1.05rem; }

.feedback-panel { max-width: 420px; }
.feedback-panel form { display: flex; flex-direction: column; }
.feedback-panel select, .feedback-panel textarea { width: 100%; }
.feedback-category-field { margin-bottom: 10px; }
.feedback-category-label { display: block; font-size: 0.85rem; margin-bottom: 4px; }
.feedback-submit { margin-top: 10px; }
.network-panel-body { display: flex; gap: 20px; overflow-y: auto; margin-top: 8px; }
.network-column { flex: 1; min-width: 0; }
.network-column h3 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 0 0 8px; }
.network-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.network-list li {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 8px; cursor: pointer; font-size: 0.9rem;
}
.network-list li:hover { background: var(--panel-alt); }
.network-empty { color: var(--muted); font-size: 0.85rem; font-style: italic; }

#online-users, #recently-active-users { list-style: none; margin: 0; padding: 0; }
#online-users li, #recently-active-users li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  min-height: 44px; /* comfortable touch target on a phone */
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.95rem;
}
#online-users li:hover, #recently-active-users li:hover { background: var(--panel-alt); }
#online-users li.active, #recently-active-users li.active { background: var(--accent); color: var(--accent-contrast); }
#online-users li.active .user-name, #recently-active-users li.active .user-name { color: var(--accent-contrast); }

.user-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.view-profile-link {
  font-size: 0.72rem;
  color: var(--accent);
  text-decoration: none;
  flex-shrink: 0;
  padding: 4px 2px; /* small extra tap target without disturbing layout */
}
#online-users li.active .view-profile-link, #recently-active-users li.active .view-profile-link { color: var(--accent-contrast); text-decoration: underline; }

.unread-badge {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}
#online-users li.active .unread-badge { background: var(--accent-contrast); }

/* Disclosed placeholder account marker - shared across the directory list,
   profile page, and chat header (see makeTestBadge() in chat.js and the
   .test-badge usage in profile_view.html) so it's the same unmistakable
   visual everywhere, never something someone could plausibly miss. */
.test-badge {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--muted);
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  flex-shrink: 0;
  text-transform: uppercase;
}
#online-users li.active .test-badge, #recently-active-users li.active .test-badge {
  color: var(--accent-contrast);
  border-color: var(--accent-contrast);
  background: transparent;
}

/* --- Avatars: deterministic color + initials, small online dot badge --- */
.avatar {
  position: relative;
  width: 34px; height: 34px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  flex-shrink: 0;
}
.avatar .status-dot {
  position: absolute;
  right: -1px; bottom: -1px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--online-dot);
  border: 2px solid var(--panel);
}
.avatar.small { width: 26px; height: 26px; font-size: 0.68rem; }
.avatar.avatar-image { overflow: hidden; }
.avatar.avatar-image img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }

#conversation-title a { color: inherit; text-decoration: underline; text-decoration-color: var(--border); }
#conversation-title a:hover { text-decoration-color: currentColor; }

.conversation {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

.conversation-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}

.back-button {
  display: none;
  background: none;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  color: var(--text);
  padding: 0 4px 0 0;
}

#conversation-title { margin: 0; font-size: 1rem; font-weight: 600; }
.typing-indicator { font-size: 0.78rem; color: var(--muted); font-style: italic; height: 1em; }

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.empty-state {
  margin: auto;
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
  padding: 20px;
}

/* --- Message groups: consecutive messages from the same sender within a
   short window collapse into one visual group with a single header --- */
.msg-group {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  max-width: 78%;
}
.msg-group.me { align-self: flex-end; flex-direction: row-reverse; }
.msg-group.them { align-self: flex-start; }

.msg-group .avatar { margin-top: auto; visibility: hidden; }
.msg-group.first-of-run .avatar { visibility: visible; }

.msg-bubbles { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.msg-group.me .msg-bubbles { align-items: flex-end; }

.msg-meta { font-size: 0.72rem; color: var(--muted); margin-bottom: 2px; }
.msg-group.them .msg-meta { text-align: left; }
.msg-group.me .msg-meta { text-align: right; }

.msg {
  padding: 8px 12px;
  border-radius: 16px;
  font-size: 0.95rem;
  line-height: 1.35;
  word-break: break-word;
  max-width: 100%;
}
.msg img { max-width: 220px; border-radius: 10px; display: block; cursor: zoom-in; }
/* Photo-only bubble: no padding, image clipped to the bubble's own rounded
   corners (including the grouped-message corner overrides above) instead of
   carrying its own separate, slightly-mismatched radius. */
.msg.msg-photo { padding: 0; overflow: hidden; }
.msg.msg-photo img { max-width: 240px; border-radius: 0; display: block; }
/* Caption alongside an image inside a photo bubble - gets its own padded
   segment instead of the (now zero) bubble padding, so the image can still
   sit flush against the bubble's edges while the text stays readable. */
.msg.msg-photo .msg-caption { display: block; padding: 8px 12px; }

/* Casual deterrence against right-click/long-press/drag saving - not real
   protection (a screenshot or dev tools bypasses all of this trivially),
   just removes the one-tap "Save image" affordance most people would reach
   for first. See protectImage() in chat.js. */
.protected-image {
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

.msg-group.me .msg { background: var(--bubble-me); color: var(--bubble-me-text); border-bottom-right-radius: 4px; }
.msg-group.them .msg { background: var(--bubble-them); color: var(--bubble-them-text); border-bottom-left-radius: 4px; }
.msg-group.me .msg:not(:last-child) { border-bottom-right-radius: 16px; }
.msg-group.them .msg:not(:last-child) { border-bottom-left-radius: 16px; }

.msg.uploading { opacity: 0.6; }

.message-form {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border-top: 1px solid var(--border);
}

.message-form input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 20px;
  /* 16px exactly, not rem-based: iOS Safari auto-zooms the whole page on
     focusing any input under 16px, which is jarring in a chat box you're
     about to type in repeatedly. */
  font-size: 16px;
  background: var(--bg);
  color: var(--text);
}

.message-form button {
  padding: 10px 18px;
  min-height: 44px;
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 20px;
  cursor: pointer;
}
.message-form button:disabled { opacity: 0.5; cursor: not-allowed; }
.message-form button:not(:disabled):hover { background: var(--accent-strong); }

.file-label {
  cursor: pointer;
  font-size: 1.3rem;
  padding: 4px 6px;
}

/* --- Lightbox for click-to-enlarge photos --- */
.lightbox-overlay {
  position: fixed; inset: 0;
  background: rgba(10, 10, 20, 0.85);
  display: flex; align-items: center; justify-content: center;
  z-index: 2000;
  cursor: zoom-out;
  padding: 24px;
}
.lightbox-overlay img { max-width: 100%; max-height: 100%; border-radius: 8px; box-shadow: var(--shadow); }
.lightbox-close {
  position: absolute;
  top: 16px; right: 16px;
  width: 36px; height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.22); }

.auth-form {
  max-width: 360px;
  margin: 40px auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow);
}

.auth-form label { display: flex; flex-direction: column; gap: 4px; font-size: 0.9rem; }
.auth-form input {
  padding: 10px; border: 1px solid var(--border); border-radius: 6px;
  font-size: 16px; /* see the message-input comment above re: iOS auto-zoom */
  background: var(--bg); color: var(--text);
}
/* A browser/password-manager autofilled field ignores plain background/color
   rules entirely - Chrome and Safari force their own (often a pale yellow)
   background with dark text via an internal user-agent style that can only
   be beaten with this specific box-shadow trick, not background-color. In
   dark mode especially, that forced light background behind our light-on-
   dark text made a revealed password nearly unreadable - clicking "Show" on
   an autofilled field surfaced this even though the input worked fine when
   the person had typed the password in themselves. The huge inset shadow
   visually repaints the whole field in our own theme color; the absurdly
   long transition delay stops the browser's own fill-color animation from
   ever completing, which is the actual mechanism (there's no shorter,
   equally reliable way to suppress it that all these browsers respect). */
.auth-form input:-webkit-autofill,
.auth-form input:-webkit-autofill:hover,
.auth-form input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px var(--bg) inset;
  box-shadow: 0 0 0 1000px var(--bg) inset;
  transition: background-color 5000s ease-in-out 0s;
}

.password-field-wrapper { position: relative; display: flex; }
.password-field-wrapper input {
  flex: 1;
  /* Flex items default to min-width:auto, which for a text input means its
     HTML `size` attribute's intrinsic width acts as a floor - it overflows
     the flex container instead of shrinking to fit, which is exactly what
     made this render wider than (and misaligned with) the field above it. */
  min-width: 0;
  padding-right: 56px;
}
/* .auth-form button (below, and *after* this in the file) sets a solid
   full-width button style - same specificity trap as the
   network-panel-overlay bug earlier: equal specificity would still lose on
   source order since that rule comes later, so this needs to be MORE
   specific, not just reordered. */
.password-field-wrapper button.password-toggle {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  background: none; border: none; color: var(--accent);
  font-size: 0.8rem; cursor: pointer; padding: 6px 8px;
  min-height: 0; width: auto;
}
.auth-form button {
  padding: 12px;
  min-height: 44px;
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.95rem;
}
.auth-form button:hover { background: var(--accent-strong); }

.field-error { color: var(--danger); font-size: 0.8rem; margin: -6px 0 0; }
.field-hint { color: var(--muted); font-size: 0.82rem; margin: -4px 0 0; }

.radio-field { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.radio-field legend { font-size: 0.9rem; padding: 0; margin-bottom: 2px; }
.radio-option { display: flex; align-items: center; gap: 6px; font-size: 0.9rem; font-weight: normal; }
.radio-option input { width: auto; }
/* ".auth-form label" (a class+element selector) outranks ".radio-option"
   (a single class) in specificity, so its flex-direction: column was
   silently winning over this rule's own flex layout for every radio label
   nested in a form with that class - harmless while both this and the
   parent fieldset agreed on "column", but broke as soon as
   .radio-field-horizontal made the fieldset row instead. ".radio-field
   .radio-option" outranks ".auth-form label" specifically to fix that. */
.radio-field .radio-option { flex-direction: row; }
/* Side-by-side instead of stacked - wrap allowed so a narrow phone screen
   drops extra options onto a second line instead of overflowing sideways. */
.radio-field-horizontal { flex-direction: row; flex-wrap: wrap; column-gap: 16px; }

.checkbox-option {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 0.9rem; font-weight: normal;
}
.checkbox-option input { width: auto; margin-top: 3px; }

.settings-divider { border: none; border-top: 1px solid var(--border); margin: 4px 0; }
.profile-form h3 { margin: 0; font-size: 0.95rem; }

.avatar-edit-row { display: flex; align-items: center; gap: 14px; }
.avatar-preview {
  width: 64px; height: 64px; border-radius: 50%;
  object-fit: cover; flex-shrink: 0;
  border: 1px solid var(--border);
}
.avatar-preview-empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-alt); color: var(--muted);
  font-size: 1.4rem; font-weight: 600;
}
.avatar-preview-large { width: 96px; height: 96px; margin: 0 auto; }

.file-input-label {
  display: inline-block; cursor: pointer;
  padding: 8px 14px; border-radius: 8px;
  background: var(--panel-alt); border: 1px solid var(--border);
  font-size: 0.88rem;
}
.file-input-label input { display: none; }

.profile-view { text-align: center; align-items: center; }
.profile-view h2 { margin: 10px 0 0; }
.follow-counts { color: var(--muted); font-size: 0.85rem; margin: 2px 0 8px; }
.profile-view form button {
  padding: 8px 20px; border: none; border-radius: 8px;
  font-size: 0.9rem; cursor: pointer; margin-bottom: 4px;
}
.profile-bio { color: var(--text); font-size: 0.95rem; white-space: pre-wrap; }

.profile-fields { display: flex; flex-direction: column; gap: 8px; width: 100%; margin: 4px 0; }
.profile-field { display: flex; justify-content: space-between; gap: 12px; font-size: 0.9rem; text-align: left; }
.profile-field dt { color: var(--muted); margin: 0; }
.profile-field dd { margin: 0; font-weight: 500; }

.age-check { text-align: center; }
.age-check-buttons { display: flex; gap: 12px; justify-content: center; margin-top: 10px; }
.age-check-buttons button {
  padding: 10px 20px;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  cursor: pointer;
}
button.age-yes { background: var(--accent); color: var(--accent-contrast); }
button.age-no { background: var(--panel-alt); color: var(--text); border: 1px solid var(--border) !important; }

.captcha-block { display: flex; align-items: center; gap: 10px; }
.captcha-block img { border: 1px solid var(--border); border-radius: 6px; }
.captcha-block a { font-size: 0.85rem; }

.toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  left: 20px;
  margin-left: auto; /* right-aligned when there's room; never overflows a narrow screen */
  background: var(--text);
  color: var(--bg);
  padding: 10px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  box-shadow: var(--shadow);
  z-index: 1000;
  max-width: 280px;
}

/* --- Error pages --- */
.error-page {
  max-width: 480px;
  margin: 60px auto;
  text-align: center;
}
.error-page .error-code { font-size: 3.5rem; font-weight: 700; color: var(--accent); margin: 0; }
.error-page p { color: var(--muted); }

@media (max-width: 640px) {
  main { padding: 10px; }
  .chat-layout { height: calc(100vh - 110px); }
  .chat-layout { height: calc(100dvh - 110px); }

  /* Mobile: show one pane at a time. .chat-layout gets .show-conversation
     toggled by JS when a conversation is opened; otherwise the list shows. */
  .user-list { width: 100%; }
  .chat-layout:not(.show-conversation) .conversation { display: none; }
  .chat-layout.show-conversation .user-list { display: none; }
  .back-button { display: inline-block; min-width: 32px; min-height: 32px; }

  /* The theme toggle's text label just adds clutter at this width - the
     icon alone is a clear enough affordance and frees up room for the
     nav to fit on one line more often. */
  .theme-toggle .toggle-label { display: none; }

  .msg-group { max-width: 88%; }
  main { max-width: 100%; }
}
