/* ── Reset & base ───────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:        #faf6ef;
  --ink:       #2b2620;
  --muted:     #8c6f4a;
  --hairline:  #e0d6c2;
  --accent:    #b0502f;
  --accent-hov:#963f22;
  --disabled-text:   #b3a488;
  --disabled-border: #d8cbb2;
  --danger:    #b0502f;
  --success:   #4a7c59;
  --radius:    2px;
  --sans:      -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif:     Georgia, 'Times New Roman', serif;
}

html { font-size: 16px; }

body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  line-height: 1.6;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hov); }

/* ── Section labels ────────────────────────────────────────────────────── */
.section-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
}

/* ── Nav ────────────────────────────────────────────────────────────────── */
nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .75rem 1.5rem;
  border-bottom: 0.5px solid var(--hairline);
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 100;
}

.nav-brand {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -.02em;
  color: var(--ink);
  display: flex;
  align-items: center;
}

.nav-logo {
  height: 28px;
  width: auto;
}

.wordmark-logo {
  display: block;
  width: 100px;
  height: auto;
  margin: 0 auto 1rem;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.nav-links a {
  color: var(--muted);
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.nav-links a:hover { color: var(--ink); }

/* Deliberately not styled like the nav links: it is a statement of fact, not
   somewhere to go. Italic serif marks it as the app talking about you rather than
   another destination, and it must not read as a sixth tab. */
.nav-identity {
  font-family: var(--serif);
  font-style: italic;
  font-size: .82rem;
  color: var(--muted);
  white-space: nowrap;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Signed in but unable to confirm as whom. Accent rather than muted, because an
   unanswered "which account is this" is worth noticing on a shared device. */
.nav-identity.is-unknown { color: var(--accent); font-style: normal; font-size: .75rem; }

/* ── Main ───────────────────────────────────────────────────────────────── */
#app {
  max-width: 680px;
  margin: 0 auto;
  padding: 2rem 1.25rem;
}

/* ── Page ───────────────────────────────────────────────────────────────── */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}

.page h2 {
  font-family: var(--serif);
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 1rem;
  color: var(--ink);
}

.page h3 {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  margin: 1.5rem 0 .75rem;
}

/* ── Auth ───────────────────────────────────────────────────────────────── */
.auth-wrap {
  max-width: 400px;
  margin: 3rem auto 0;
  text-align: center;
}

.wordmark {
  font-family: var(--serif);
  font-size: 2.5rem;
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--ink);
  margin-bottom: .5rem;
}

.tagline {
  font-family: var(--serif);
  font-style: italic;
  color: var(--muted);
  margin-bottom: 2rem;
  font-size: 1rem;
  line-height: 1.5;
}

.landing-headline {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: .75rem;
  line-height: 1.3;
}

.landing-body {
  font-family: var(--serif);
  font-size: .95rem;
  color: var(--ink);
  line-height: 1.7;
  margin-bottom: .75rem;
}

.landing-italic {
  font-family: var(--serif);
  font-style: italic;
  font-size: .9rem;
  color: var(--muted);
  line-height: 1.5;
  margin-bottom: 2rem;
}

.about-link {
  margin-top: 1.5rem;
  text-align: center;
  font-size: .8rem;
}

.about-link a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 0.5px solid var(--hairline);
  padding-bottom: 1px;
  transition: color .15s;
}

.about-link a:hover { color: var(--accent); }

.tabs {
  display: flex;
  border-bottom: 0.5px solid var(--hairline);
  margin-bottom: 1.5rem;
}

.tab {
  flex: 1;
  padding: .6rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: .8rem;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  text-transform: uppercase;
  letter-spacing: .04em;
  transition: color .15s, border-color .15s;
}

.tab.active {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.auth-form { text-align: left; }

/* ── Forms ──────────────────────────────────────────────────────────────── */
label {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  font-size: .85rem;
  color: var(--muted);
  margin-bottom: 1rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: var(--sans);
  font-size: .9rem;
  padding: .6rem .8rem;
  width: 100%;
  transition: border-color .15s;
}

input::placeholder, textarea::placeholder {
  color: var(--disabled-text);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
}

input:disabled, select:disabled, textarea:disabled {
  border-color: var(--disabled-border);
  color: var(--disabled-text);
}

textarea { resize: vertical; }

.char-count {
  font-size: .75rem;
  color: var(--muted);
  text-align: right;
}

.fine-print {
  font-family: var(--serif);
  font-style: italic;
  font-size: .78rem;
  color: var(--muted);
  margin-bottom: 1rem;
  line-height: 1.5;
}

.forgot-link {
  font-family: var(--serif);
  font-style: italic;
  font-size: .8rem;
  text-align: center;
  margin-top: .75rem;
}

.forgot-link a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 0.5px solid var(--hairline);
  padding-bottom: 1px;
  transition: color .15s;
}

.forgot-link a:hover { color: var(--accent); }

.subhead {
  color: var(--muted);
  font-size: .9rem;
  margin-bottom: 1.25rem;
  line-height: 1.5;
}

/* ── Checkboxes & radios ───────────────────────────────────────────────── */
.checkbox-label,
.radio-label {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: .5rem;
  font-size: .9rem;
  color: var(--ink);
  cursor: pointer;
  margin-bottom: .35rem;
}

.checkbox-label input[type="checkbox"],
.radio-label input[type="radio"] {
  width: auto;
  accent-color: var(--accent);
}

fieldset {
  border: none;
  padding: 0;
  margin-bottom: 1rem;
}

fieldset legend {
  font-size: .85rem;
  color: var(--muted);
  margin-bottom: .5rem;
}

.req-note { font-size: .75rem; }
.attracted-to-fieldset { margin-bottom: 1rem; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn-primary {
  display: inline-block;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: .65rem 1.25rem;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  cursor: pointer;
  transition: background .15s, color .15s;
  width: 100%;
}

.btn-primary:hover { background: var(--accent); color: #fff; }
.btn-primary:disabled {
  border-color: var(--disabled-border);
  color: var(--disabled-text);
  cursor: not-allowed;
  background: transparent;
}

.btn-ghost {
  background: none;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  color: var(--muted);
  padding: .4rem .8rem;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  transition: border-color .15s, color .15s;
}

.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }

.btn-danger {
  background: none;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: var(--radius);
  padding: .35rem .75rem;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  transition: background .15s;
}

.btn-danger:hover { background: var(--accent); color: #fff; }

.btn-reply {
  background: none;
  border: 1px solid var(--hairline);
  color: var(--muted);
  border-radius: var(--radius);
  padding: .3rem .7rem;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  transition: border-color .15s, color .15s;
}

.btn-reply:hover { border-color: var(--accent); color: var(--accent); }

/* ── Cards / Posts ─────────────────────────────────────────────────────── */
.card-list { display: flex; flex-direction: column; gap: 0; }

.post-card {
  background: transparent;
  border: none;
  border-bottom: 0.5px solid var(--hairline);
  border-radius: 0;
  padding: 1.25rem 0;
}

.post-card:first-child { padding-top: 0; }

.post-card.draft {
  border: 1px dashed var(--disabled-border);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: .75rem;
  border-bottom-width: 1px;
}

.post-badges {
  display: flex;
  gap: .75rem;
  margin-bottom: .35rem;
}

.badge {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  background: none;
  padding: 0;
  border-radius: 0;
}

.badge-archive { color: var(--accent); }
.badge-friend  { color: var(--muted); }

.post-meta {
  display: flex;
  gap: .75rem;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: .6rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.post-venue {
  font-weight: 600;
  color: var(--muted);
}

.post-body {
  font-family: var(--serif);
  font-size: .95rem;
  line-height: 1.7;
  color: var(--ink);
  margin-bottom: .75rem;
}

.post-actions {
  display: flex;
  gap: .5rem;
  align-items: center;
}

/* Small and quiet: changing the day is an adjustment, not an action to be drawn
   toward. Sits beside the badge it edits. */
.reschedule-input {
  width: auto;
  font-size: .75rem;
  padding: .2rem .4rem;
  color: var(--muted);
}

.post-pending-badge {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  background: none;
  padding: 0;
  margin-left: .5rem;
}

/* ── Feed filters ──────────────────────────────────────────────────────── */
.feed-filters {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.feed-filters select {
  width: auto;
  font-size: .85rem;
  padding: .4rem .7rem;
}

.filter-chips {
  display: flex;
  gap: .75rem;
  align-items: center;
}

.chip {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  padding: 0;
  transition: color .15s;
}

.chip:hover { color: var(--ink); }
.chip.active { color: var(--accent); }

/* ── Type toggle (composer) ────────────────────────────────────────────── */
.type-toggle {
  display: flex;
  gap: .75rem;
  margin-bottom: 1.25rem;
}

.type-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  padding: .3rem 0;
  border-bottom: 2px solid transparent;
  transition: color .15s, border-color .15s;
}

.type-btn:hover { color: var(--ink); }
.type-btn.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Seeking fieldset ──────────────────────────────────────────────────── */
.seeking-fieldset { margin-bottom: 1rem; }

.seeking-fieldset legend {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  margin-bottom: .5rem;
}

/* ── Chat ───────────────────────────────────────────────────────────────── */
/* No height here. It used to be calc(100vh - 120px), which forced the row to fill
   the viewport; .message-pane stretched to match and .messages took the slack, so a
   three-message thread rendered a near-full-screen empty box with the input stranded
   at the bottom of the page. Height now comes from content, bounded on .messages.

   align-items: flex-start stops the two columns stretching to each other's height —
   without it a long thread list would drag an empty message pane down with it. */
.chat-page {
  display: flex;
  gap: 1.5rem;
  align-items: flex-start;
}

.thread-list {
  /* 220px truncated venue names to "Omnivo…", and the venue is the field that tells
     one thread from another. Widened until the ones in the seed data fit. */
  width: 260px;
  flex-shrink: 0;
}

.thread-list h2 { font-size: 1rem; margin-bottom: .75rem; }

.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--hairline);
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  flex-shrink: 0;
  overflow: hidden;
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }

#chat-with { display: flex; align-items: center; gap: .5rem; }

.thread-item {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  background: transparent;
  border: none;
  border-bottom: 0.5px solid var(--hairline);
  border-radius: 0;
  padding: .7rem 0;
  cursor: pointer;
  font-size: .875rem;
  transition: color .15s;
}

.thread-item:hover .thread-venue { color: var(--accent); }
.thread-item.active .thread-venue { color: var(--accent); }

/* Threads are per-post, so the person's name is the one field that does NOT tell two
   rows apart. The venue leads because a place names a moment better than a time does;
   the post excerpt sits under it; the last message reads smallest. */
.thread-main {
  flex: 1;
  min-width: 0;          /* without this a long excerpt refuses to ellipsis */
  display: flex;
  flex-direction: column;
  gap: .15rem;
}

.thread-top { display: flex; align-items: baseline; gap: .4rem; }

.thread-venue {
  font-weight: 600;
  font-size: .85rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color .15s;
}

.thread-name {
  font-size: .78rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.thread-when {
  margin-left: auto;
  flex-shrink: 0;
  font-size: .7rem;
  color: var(--muted);
  white-space: nowrap;
}

.thread-excerpt {
  font-family: var(--serif);
  font-style: italic;
  font-size: .8rem;
  line-height: 1.35;
  color: var(--muted);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.thread-preview {
  font-size: .76rem;
  color: var(--muted);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A post that can no longer be shown is stated, not blanked. */
.thread-venue.is-missing,
.thread-excerpt.is-missing { color: var(--muted); font-weight: 400; }

/* ── Unread ─────────────────────────────────────────────────────────────────
   A dot and never a count, in accent rather than red: this is "something is here
   for you", not a warning, and a number would report how many people wrote to you
   to anyone who can see the screen. */
.unread-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: .3rem;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
}

/* The same mark on the row it belongs to, so three threads from one person can be
   told apart by which is new. */
.thread-item.is-unread .thread-venue { font-weight: 700; color: var(--ink); }

/* A sibling of the venue rather than a pseudo-element inside it. The venue clips to
   an ellipsis, and anything inside it is clipped too — which hid the mark on exactly
   the rows with the longest venue names. flex-shrink: 0 keeps it from being squeezed
   out by the same pressure. */
.thread-unread-dot {
  display: none;
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.thread-item.is-unread .thread-unread-dot { display: block; }

/* A thread you have blocked. Dimmed, not hidden: the history is yours and blocking
   someone is not a reason to delete your own record of it. */
.thread-item.is-blocked { opacity: .6; }

/* Says who you are on the one screen that no longer lets you change it.
   The name reads at body weight; the permanence sits under it as a footnote, because
   it is context for the fact rather than half of it. */
.profile-identity { margin-bottom: 1.25rem; }

.profile-username-line {
  font-size: .95rem;
  color: var(--muted);
}

.profile-username-line #profile-username {
  font-weight: 600;
  color: var(--ink);
}

.profile-username-note {
  font-size: .75rem;
  color: var(--muted);
  opacity: .8;
  margin-top: .15rem;
}

.thread-blocked-flag {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  border: 1px solid currentColor;
  border-radius: 3px;
  padding: 0 .3em;
  margin-left: .4em;
}

/* Sits where the composer would be, because the composer is hidden rather than
   disabled — a disabled textarea still invites you to type into it. */
.thread-blocked {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5rem;
  padding: .75rem;
}

.message-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: transparent;
  border: 0.5px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
}

.message-pane-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .75rem 1rem;
  border-bottom: 0.5px solid var(--hairline);
  font-weight: 600;
  font-size: .9rem;
}

/* The post the thread grew out of, pinned above the message history.
   Outside the scroll container rather than position: sticky, so it cannot scroll away
   and nothing overlaps the messages beneath it. The hairline is the same rule the
   pane header uses, so the pane reads as three stacked bands. */
.thread-post {
  flex-shrink: 0;
  padding: .7rem 1rem;
  border-bottom: 0.5px solid var(--hairline);
}

.thread-post-meta {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin-bottom: .2rem;
}

.thread-post-venue {
  font-size: .8rem;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.thread-post-when {
  font-size: .72rem;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Serif italic, like the excerpt on the thread row: this is the app quoting the
   moment back at you, not another message in the conversation.

   Clamped to three lines. A post can run to 500 characters, and the pane is bounded,
   so an unclamped header would eat the message list on exactly the short threads this
   app is mostly made of. The ticket's open question was whether to collapse this on
   scroll; a fixed ceiling answers the height problem without adding a control. */
.thread-post-body {
  font-family: var(--serif);
  font-style: italic;
  font-size: .85rem;
  line-height: 1.4;
  color: var(--muted);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* A post that is no longer there. Italic serif is kept, because this is still the app
   speaking about the moment rather than reporting an error — it just says the moment
   is gone. One step lighter than a real excerpt so the absence reads as quieter than
   the thing it replaces, rather than as another quote.

   Not var(--muted): .thread-post-body already sets that, so it would restyle nothing
   and this class would go on doing no work. */
.thread-post.is-missing .thread-post-body { color: var(--disabled-text); }

/* The only sized box in the pane: everything else wraps it snugly.

   flex: 0 1 auto rather than flex: 1 — growing to fill the parent is exactly what
   produced the empty screen. It takes the height its messages need, between a floor
   and a ceiling.

   The floor is deliberately low. Threads here are mostly "was that you?" / "yes", and
   5rem is almost exactly two bubbles plus their gap — so the common case fills the box
   with no dead space, while a single message still gets a box that reads as a
   conversation rather than a stray line.

   The ceiling is declared twice on purpose. 55vh lands first for browsers without
   dynamic viewport units; vh is the LAYOUT viewport, which does not shrink when a
   phone keyboard opens, so it is set conservatively to leave room for one. Browsers
   that understand dvh take the second and get 60vh of the ACTUAL visible area,
   re-measured when the keyboard appears. Do not collapse these into one line.

   The min() in the second declaration is not decoration, and measurement is what
   found it. 60dvh caps THIS box, but the pane also carries its own header, the pinned
   post block and the send row — about 240px — plus the nav and page padding above it.
   So a plain 60dvh ceiling made the pane total roughly 60dvh + 21rem, which overflowed
   a keyboard-shortened viewport and clipped the Send button: measured at 741px against
   a 713px viewport on desktop, and clipped at every phone size. Subtracting the
   surrounding chrome makes the whole pane fit
   instead. It only binds on short viewports; on a desktop the 60dvh term still wins,
   so nothing changes there. */
.messages {
  flex: 0 1 auto;
  min-height: 5rem;
  max-height: 55vh;
  max-height: min(60dvh, calc(100dvh - 21rem));
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.msg-bubble {
  max-width: 75%;
  padding: .5rem .85rem;
  border-radius: 16px;
  font-family: var(--serif);
  font-size: .9rem;
  line-height: 1.4;
}

.msg-bubble.sent {
  align-self: flex-end;
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.msg-bubble.received {
  align-self: flex-start;
  background: var(--hairline);
  color: var(--ink);
  border-bottom-left-radius: 4px;
}

.msg-tip {
  font-family: var(--serif);
  font-style: italic;
  font-size: .85rem;
  color: var(--muted);
  text-align: center;
  padding: 2rem 1rem;
}

/* The textarea and Send sit on ONE row, and that is load-bearing on a phone rather
   than a layout preference. When the keyboard opens the browser scrolls the focused
   element into view — so if Send shares a line with the textarea it is dragged into
   view with it and cannot end up behind the keyboard. If it wrapped to its own line
   below, nothing would guarantee that line was visible. No flex-wrap, and Send does
   not shrink. */
#form-message {
  display: flex;
  gap: .5rem;
  padding: .75rem;
  border-top: 0.5px solid var(--hairline);
  flex-wrap: nowrap;
  scroll-margin-bottom: 1rem;
}

#form-message textarea { margin-bottom: 0; min-width: 0; }
#form-message .btn-primary { width: auto; white-space: nowrap; flex-shrink: 0; }

/* ── Profile ────────────────────────────────────────────────────────────── */
.profile-photo {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: .5rem;
  border: 1px solid var(--hairline);
}

hr {
  border: none;
  border-top: 0.5px solid var(--hairline);
  margin: 1.75rem 0;
}

.venue-checkbox-list { display: flex; flex-direction: column; gap: .5rem; }

.venue-checkbox-item {
  /* Holds a stacked name+address body, same as the pickers. */
  align-items: center;
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: .9rem;
  color: var(--ink);
  cursor: pointer;
}

.venue-checkbox-item input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent);
}

.private-stats p { font-size: .95rem; color: var(--ink); }

/* ── Membership ────────────────────────────────────────────────────────── */
#membership-tier {
  font-family: var(--serif);
  font-size: 1rem;
  color: var(--ink);
  margin-bottom: .25rem;
}

#membership-desc {
  font-family: var(--serif);
  font-style: italic;
  font-size: .85rem;
  color: var(--muted);
  line-height: 1.5;
  margin-bottom: .5rem;
}

#post-usage {
  font-size: .85rem;
  color: var(--muted);
  margin-bottom: .75rem;
}

#upgrade-btn { width: auto; }

/* ── Signup notes ──────────────────────────────────────────────────────── */
.signup-note {
  font-family: var(--serif);
  font-style: italic;
  font-size: .8rem;
  color: var(--muted);
  line-height: 1.5;
  margin-top: .75rem;
  text-align: center;
}

/* ── Onboarding ────────────────────────────────────────────────────────── */
.onboarding-headline {
  font-family: var(--serif);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: .75rem;
  text-align: center;
}

.venue-search-input {
  margin-bottom: 1rem;
}

.onboarding-venue-list {
  max-height: 320px;
  overflow-y: auto;
  margin-bottom: 1.25rem;
  border-top: 0.5px solid var(--hairline);
}

.onboarding-venue-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .65rem 0;
  border-bottom: 0.5px solid var(--hairline);
  cursor: pointer;
  font-size: .9rem;
  color: var(--ink);
}

.onboarding-venue-row input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent);
  flex-shrink: 0;
}

/* ── One venue row body, three wrappers ──────────────────────────────────────
   The name and the location stack; the activity signal sits to the right. The address
   is on its own line because right-aligned and nowrap it was either truncated to
   uselessness or crowding out the name — and telling two branches of a chain apart is
   exactly the case where the distinguishing part is at the END of the string. */
.venue-row-main {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  flex: 1;
  /* Without this a flex child refuses to shrink below its content width and the
     ellipsis below never engages — the row just pushes the aside off instead. */
  min-width: 0;
}

.venue-row-name {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.venue-row-address {
  font-size: .75rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.venue-row-aside {
  font-size: .75rem;
  color: var(--muted);
  text-align: right;
  white-space: nowrap;
  flex-shrink: 0;
  align-self: center;
  /* Empty for a quiet venue and for every Google result. Nothing reserves space for it,
     so the name and address get the whole row when there is no signal to show. */
}

.feed-banner {
  font-family: var(--serif);
  font-style: italic;
  font-size: .85rem;
  color: var(--muted);
  padding: .75rem 0;
  border-bottom: 0.5px solid var(--hairline);
  margin-bottom: .75rem;
  line-height: 1.5;
}

.feed-banner a { color: var(--accent); }

/* ── Misc ───────────────────────────────────────────────────────────────── */
.loading { color: var(--muted); font-size: .9rem; padding: 1rem 0; }
.empty   { color: var(--muted); font-size: .9rem; padding: 1rem 0; font-family: var(--serif); font-style: italic; }

.form-error {
  color: var(--accent);
  font-size: .85rem;
  margin-top: .5rem;
}

.form-success {
  color: var(--success);
  font-size: .85rem;
  margin-top: .5rem;
}

/* Show/hide toggle on a password field. The input keeps its normal appearance
   through the swap because input[type="text"] and input[type="password"] share one
   rule above — only the type changes, nothing reflows. */
.password-field { position: relative; display: block; }
.password-field input { padding-right: 4rem; }

.password-toggle {
  position: absolute;
  right: .35rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: 0;
  padding: .3rem .5rem;
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
}
.password-toggle:hover { color: var(--accent); }
.password-toggle:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* Inline availability hint under the signup username field. Sits tight to the
   input it describes rather than at form level like .form-error/.form-success. */
.field-hint {
  font-size: .8rem;
  margin: -.5rem 0 .75rem;
  color: var(--muted);
}
.field-hint.is-available { color: var(--success); }
.field-hint.is-taken     { color: var(--accent); }

.hidden { display: none !important; }

/* Site footer. Quiet by design — these are links people need to be able to find,
   not links the product wants them to click. Sits below #app on every view. */
#site-footer {
  max-width: 680px;
  margin: 0 auto;
  padding: 2rem 1.25rem 2.5rem;
  text-align: center;
  border-top: 0.5px solid var(--hairline);
}

#site-footer a {
  font-family: var(--serif);
  font-style: italic;
  font-size: .8rem;
  color: var(--muted);
  margin: 0 .5rem;
}

#site-footer a:hover { color: var(--accent); }

/* ── Responsive ─────────────────────────────────────────────────────────── */
/* Where the viewport is genuinely too short to hold everything -- a phone with the
   keyboard open has around 330px -- the pinned post gives up its body and keeps the
   venue and timing, and the message list gives up some of its floor. This is the
   condensed form the ticket asked about, triggered by available height rather than by
   scrolling: the trade only has to be made when the space really is not there, and
   being able to type and send outranks reading the excerpt again. */
@media (max-height: 520px) {
  .thread-post-body { -webkit-line-clamp: 1; }
  .thread-post { padding: .5rem 1rem; }
  .messages { min-height: 3rem; }
}

@media (max-width: 600px) {
  .chat-page { flex-direction: column; }
  .thread-list { width: 100%; }

  /* The nav does not fit a phone, and the identity is not the reason. Measured in a
     360px viewport: 386px wide without the identity, 487px with it. So it overflowed
     before the identity existed and the identity costs about 93px on top.
     This caps what the identity contributes; it does not pretend to fix the
     overflow, which needs a decision about five nav links on a 360px screen and is
     not something to slip into a chat change. The full name stays in the title
     attribute when the text truncates. */
  .nav-identity { max-width: 6rem; font-size: .75rem; }
  /* .message-pane had height: 60vh here — a FIXED height, so the empty-box problem
     was on the phone too, and worse: a fixed 60vh of layout viewport does not yield
     when the keyboard takes half the screen. The pane now sizes to content like the
     desktop case, and the ceiling on .messages is what bounds it. */
  .nav-links { gap: .75rem; }
  .page-header { flex-direction: column; align-items: flex-start; gap: .75rem; }
}

/* ── Create-post venue picker ────────────────────────────────────────────────
   The venue field stopped being a <select> when venues stopped being a fixed list.
   A dropdown can only offer rows that already exist, and every place someone finds
   through Google is one that does not yet. */
.venue-result-list {
  max-height: 240px;
  overflow-y: auto;
  border-top: 0.5px solid var(--hairline);
}

.venue-result-list:empty { border-top: none; }

.venue-result-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  padding: .65rem .2rem;
  border: none;
  border-bottom: 0.5px solid var(--hairline);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: .9rem;
  text-align: left;
  cursor: pointer;
}

.venue-result-row:hover { color: var(--accent); }

.venue-chosen {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  font-size: .9rem;
  color: var(--ink);
  padding: .6rem .8rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}

.venue-chosen-name { flex: 1; }

.venue-change-btn {
  border: none;
  background: transparent;
  padding: 0;
  color: var(--accent);
  font-family: var(--sans);
  font-size: .8rem;
  cursor: pointer;
  text-decoration: underline;
  flex-shrink: 0;
}

/* Profile: adding a place is its own control beneath the list of places you keep. */
.venue-add-heading {
  font-family: var(--sans);
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.25rem 0 .5rem;
}

/* A closure is a state, not a statistic, so it does not read like "4 recent notes". */
.venue-row-aside.is-closed {
  color: var(--ink);
  opacity: .55;
  font-variant: small-caps;
  letter-spacing: .04em;
}

/* Unavailable BEFORE the tap, not after it. A row that refuses once you have chosen it
   reads as a rejection; a row that never offered itself is just information. */
.venue-result-row:disabled {
  opacity: .45;
  cursor: default;
}
.venue-result-row:disabled:hover { color: var(--ink); }

.venue-closed-note {
  font-family: var(--serif);
  font-style: italic;
  font-size: .8rem;
  color: var(--muted);
  margin: .5rem 0 0;
}
