/* Lüba — warm, grown-up, café calm. Coral is the accent, not the wallpaper. */

/* ===================================================================
   [hidden] MEANS HIDDEN — 2026-09-19

   Sal, testing on a real phone, found three things on screen that the
   code believed were hidden: a "0 new messages" button, an "Undo", and
   "Thanks — we've got it. Someone will look."

   The hidden ATTRIBUTE is only display:none in the browser's own default
   stylesheet, which is the weakest thing in the cascade. Any rule of ours
   that sets display — .new-messages{display:block}, .space-toast,
   .mod-care — silently beats it, and an element the JS has carefully
   hidden sits there in plain view.

   This makes the attribute mean what everyone writing the JS assumed it
   meant. Two rules already patched this one class at a time
   (.intro-modal[hidden], .onboard-modal[hidden]); this covers the rest,
   and everything we write from here.
   =================================================================== */
[hidden] { display: none !important; }

:root {
  --coral: #FF6A52;
  --coral-ink: #D84A32;
  --coral-wash: #FFE9E3;

  --bg: #FAF7F2;
  --surface: #FFFFFF;
  --surface-sunk: #F3EEE6;
  /* Warm card — added 21 Sep. --surface is pure #FFFFFF, which sits on the
     warm paper of --bg like a sheet of office printer paper dropped on a
     table. Sal: "that background for that card, it's bright bright white
     against my regular background. Totally not right." This is the same
     family as the page, one step lighter. */
  --surface-card: #FFFCF8;

  --ink: #1F1B16;
  --ink-soft: #4A423A;
  --ink-muted: #7A7066;

  --line: #EAE5DD;
  --line-strong: #D9D2C5;

  --radius-lg: 14px;
  --radius: 10px;
  --radius-sm: 6px;

  --shadow-sm: 0 1px 2px rgba(31, 27, 22, 0.04);
  --shadow: 0 2px 8px rgba(31, 27, 22, 0.06);

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --serif: "Fraunces", Georgia, "Times New Roman", serif;

  --transition: 180ms ease;

  /* ================= TYPE SCALE — 2026-09-05 =================
     Six sizes, each 1.25x the one below (Major Third, the ratio recommended
     for landing pages). Sizes still differ; they now relate. Before this the
     landing path used 13 sizes chosen one at a time.
       39 held for later   31 wordmark   25 section headings + welcome pair
       20 tagline, lede, story, card titles, share line
       16 card text, buttons, legal links   13 copyright              */
  --t-xs:  0.8125rem;   /* 13px */
  --t-sm:  1rem;        /* 16px */
  --t-md:  1.25rem;     /* 20px */
  --t-lg:  1.5625rem;   /* 25px */
  --t-xl:  1.9375rem;   /* 31px */
  --t-2xl: 2.4375rem;   /* 39px */

  /* ================= SPACING RHYTHM =================
     Six gaps. Nothing else. The landing CSS had 25 different values.
       8 line to line   12 tight   16 inside a block
       24 between blocks   32 between sections   48 major break        */
  --s-1: 0.5rem;   /*  8px */
  --s-2: 0.75rem;  /* 12px */
  --s-3: 1rem;     /* 16px */
  --s-4: 1.5rem;   /* 24px */
  --s-5: 2rem;     /* 32px */
  --s-6: 3rem;     /* 48px */

  /* Legacy variable aliases so any stray references still resolve. */
  --primary: var(--coral);
  --primary-dark: var(--coral-ink);
  --primary-soft: var(--coral-wash);
  --text: var(--ink);
  --text-light: var(--ink-muted);
  --background: var(--bg);
  --border: var(--line);
  --border-light: var(--line);
  --cream: var(--surface-sunk);
  --section-bg: var(--surface-sunk);
  --header-bg: var(--surface);
  --shadow-hover: var(--shadow);
  --radius-small: var(--radius-sm);
  --font: var(--sans);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  /* 2026-09-04 — soften Fraunces (Sal: "it looks like Times Roman... we
     should be using a nice warm round font"). Fraunces is variable and
     carries a SOFT axis that rounds its terminals, and an opsz axis that
     controls contrast: HIGH opsz gives the thin-stroke, high-contrast look
     that reads as Times, LOW opsz gives sturdier, warmer letterforms. So:
     SOFT to the top of its range, opsz held low rather than letting it
     climb with size. WONK (the quirky alternate glyphs) stays off — it is
     charming but it changes letter shapes enough to cost legibility, and
     this page is read by people of every age.

     font-variation-settings inherits, so this reaches every serif on the
     site from one place. wght is deliberately NOT set here, so ordinary
     font-weight keeps working. Inter ignores axes it does not have. */
  font-variation-settings: "opsz" 24, "SOFT" 100, "WONK" 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  max-width: 100%;
  /* Never let anything scroll or bleed sideways — a horizontal spill on mobile
     makes the browser widen its viewport and fall back to the desktop layout.
     `clip` (not hidden) keeps the sticky header working. */
  overflow-x: clip;
}

a { color: var(--coral-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- Header ---------- */
/* 2026-09-04 — cut tight (Sal: "it's like an inch"). It was 93px: a 48px
   heart plus 44px of padding. The header is sticky, so that inch was spent
   on every screen and never came back, and nothing in it needed the room —
   a wordmark, a heart, one button. Now ~51px. */
header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0.6rem 1.5rem 0.55rem;
  position: sticky;
  top: 0;
  z-index: 100;
  text-align: center;
}

.header-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  /* The top row has to be as tall as the tallest thing standing in it.
     The wordmark is ~34px; the sign-in button on the right and the language
     picker on the left are 42-44px, because 40px is the floor for something
     a hand has to hit. Sizing the row to them is what keeps the reading nav
     BELOW both instead of underneath them. Set ONCE, here, for every width —
     the alternative is a second copy in a media query, which is exactly the
     duplicate-declaration bug that made the header sticky on phones for
     weeks (see the note at the old `header { position: sticky }` line). */
  min-height: 48px;
}

#logo {
  /* Was 48px and set the entire header height on its own. The heart
     supports the wordmark, it does not lead. */
  width: 30px;
  height: 30px;
  object-fit: contain;
}

header h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  /* The brand leads. It was 1.55rem while the tagline below ran to 2.8rem,
     so the page shouted its tagline and whispered its name. */
  font-size: var(--t-xl);
  line-height: 1.1;
  letter-spacing: 0;
  color: var(--ink);
}

/* Header taglines + nav retired from the front-door header on all viewports —
   the greeting and callout below carry the message so the header stays
   minimal (just the wordmark + Sign in). Rooms/Help remain reachable
   through footer links and in-app navigation. */
.tagline,
.tagline-line { display: none; }
body:not(.authed) header nav { display: none; }

/* The nine reading pages, across the top (Sal, 20 Sep).
   ⚠️ These deliberately escape the two rules that hide `header nav` — signed
   out, and on a phone. The room nav is for members and has no business showing
   to a stranger. These pages are the opposite: they exist FOR the stranger and
   for search engines, both of which arrive signed out, and more than half of
   them arrive on a phone. Hiding them there would have made them invisible to
   everyone they were written for. */
body:not(.authed) header nav.nav-reading { display: flex; }

/* ONE row, edge to edge — Sal, 20 Sep: "spread them out along the page what
   you did was you created two rows... make that banner smaller It's way too
   wide Or like too deep".
   It was 44rem wide and centred, so nine labels had nowhere to go but a second
   line, which doubled the depth of the header. Now the row uses the full width
   with space-between, so the labels distribute themselves instead of bunching,
   and the type and spacing are tighter so it reads as a strip rather than a
   band. It still wraps below ~700px, because at phone width one line of nine
   is unreadable — but that is the only place it does. */
.nav-reading {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.25rem 0.6rem;
  margin: 0.45rem auto 0;
  max-width: 68rem;
  width: 100%;
  padding: 0 var(--s-3);
}
.nav-reading a {
  font-size: var(--t-xs);
  letter-spacing: 0.01em;
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  white-space: nowrap;
}
.nav-reading a:hover,
.nav-reading a:focus-visible { color: var(--coral); border-bottom-color: currentColor; }

nav {
  display: flex;
  justify-content: center;
  gap: 0.25rem;
  margin-top: 0.75rem;
}

nav a {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: var(--t-sm);
  padding: 0.4rem 0.75rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: var(--transition);
}

nav a:hover { color: var(--ink); background: var(--surface-sunk); text-decoration: none; }

/* ---------- Main ---------- */
main {
  max-width: none;
  margin: 0 auto 2rem;               /* no top gap — greeting sits flush under the header */
  padding: 0 2rem;
}

section {
  margin-bottom: 2rem;
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
  border-radius: 0;
}

h2 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-lg);
  color: var(--ink);
  margin: 0 0 0.5rem;
  padding: 0;
  border: none;
  letter-spacing: -0.01em;
}

h3 {
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--ink);
  margin: 0 0 0.75rem;
}

/* ---------- Welcome band ---------- */
.welcome-band {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2rem 1.75rem;
  text-align: center;
  margin-bottom: 1.5rem;
}

.welcome-manifesto {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--ink-soft);
  font-weight: 400;
  max-width: 520px;
  margin-inline: auto;
}

/* The secondary tagline, matched to itself — 2026-09-18.
   Sal: "the fonts are wrong, they don’t match." The same locked sentence,
   "Creating community — One genuine conversation at a time.", appears here and
   above the hero. .public-tagline sets the house treatment for it, chosen by
   Sal on 4 Sep: serif italic, weight 600, coral, --t-md. This block was still
   at weight 400 in ink from when it carried a different sentence, so one line
   was rendering two ways on one page. Change both together or neither. */
.welcome-manifesto span {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--t-md);
  line-height: 1.4;
  color: var(--coral-ink);
}

/* ---------- Ask a Lüba ---------- */
#help-section {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.75rem;
}

#help-section > p {
  margin: 0 0 1.25rem;
  color: var(--ink-muted);
  font-size: var(--t-sm);
}

#question-categories { margin-bottom: 1rem; }

#question-categories label,
#help-section label {
  display: block;
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 0.4rem;
}

#category-select,
#question-input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-family: var(--sans);
  color: var(--ink);
  background: var(--surface);
  transition: var(--transition);
}

#question-input {
  resize: vertical;
  min-height: 96px;
  line-height: 1.5;
}

#category-select:focus,
#question-input:focus,
#chat-input:focus,
#onboard-name:focus {
  border-color: var(--coral);
  outline: none;
  box-shadow: 0 0 0 3px var(--coral-wash);
}

#question-controls {
  margin-top: 1rem;
  display: flex;
  justify-content: flex-end;
}

#ask-luva-btn {
  background: var(--coral);
  color: #fff;
  padding: 0.7rem 1.25rem;
  border: none;
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-weight: 600;
  font-family: var(--sans);
  cursor: pointer;
  transition: var(--transition);
}

#ask-luva-btn:hover { background: var(--coral-ink); }

/* ---------- Question feed ---------- */
#questions-feed { margin-top: 2rem; }
#questions-feed h3 { font-family: var(--serif); font-weight: 500; font-size: var(--t-md); color: var(--ink); margin-bottom: 1rem; }

#questions-list:empty::before {
  content: "No questions yet. Be the first to ask.";
  display: block;
  color: var(--ink-muted);
  font-size: var(--t-xs);
  padding: 1rem 0;
}

.question-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  margin-bottom: 0.75rem;
  transition: var(--transition);
}

.question-item:hover { border-color: var(--line-strong); }

.question-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
  font-size: var(--t-xs);
  color: var(--ink-muted);
}

.question-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.question-who { font-weight: 600; color: var(--ink); }

.question-category {
  background: var(--surface-sunk);
  color: var(--ink-soft);
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: capitalize;
}

.question-time { margin-left: auto; font-size: var(--t-xs); }

.question-content {
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--ink);
  margin-bottom: 0.6rem;
}

.question-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.answer-btn {
  background: transparent;
  color: var(--coral-ink);
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--t-xs);
  font-weight: 500;
  font-family: var(--sans);
  transition: var(--transition);
}

.answer-btn:hover { border-color: var(--coral); background: var(--coral-wash); }

.answers-count { color: var(--ink-muted); font-size: var(--t-xs); }

/* ---------- Share ---------- */
#share {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem 1.75rem;
  text-align: center;
}

#share h2 { margin-bottom: 0.4rem; }

.share-incentive {
  margin: 0 0 1.1rem;
  color: var(--ink-muted);
  font-size: var(--t-sm);
}

.share-copy {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  color: var(--ink);
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--t-xs);
  font-weight: 500;
  font-family: var(--sans);
  transition: var(--transition);
}

.share-copy:hover { border-color: var(--coral); color: var(--coral-ink); background: var(--coral-wash); }

#share-success p {
  margin: 0.75rem 0 0;
  color: var(--ink-soft);
  font-size: var(--t-xs);
}

/* ---------- Privacy promise ---------- */
.privacy-promise {
  background: var(--surface-sunk);
  border-radius: var(--radius-lg);
  padding: 1.5rem 1.75rem;
  text-align: center;
}

.promise-heading {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-md);
  color: var(--ink);
  margin: 0 0 0.4rem;
}

.promise-lead {
  margin: 0 0 0.6rem;
  color: var(--ink);
  font-weight: 500;
}

.privacy-promise .privacy-text {
  color: var(--ink-muted);
  font-size: var(--t-xs);
  max-width: 520px;
  margin: 0 auto;
  font-style: normal;
}

/* ---------- Footer ---------- */
/* 2026-09-05 — Sal: the closing band and the copyright line together are
   "easily a good 2 inches... so disproportionate". The footer was 133px for
   two small lines: 40px of margin above it, 48px of padding inside it. A
   copyright line should be quiet furniture, not a room of its own. Now 74px. */
footer {
  border-top: 1px solid var(--line);
  color: var(--ink-muted);
  text-align: center;
  /* Gutter: 16px held the ends too far in, 8px pushed them too far out
     ("too drastic"). 16px is the standing page gutter, and with the wrap bug
     fixed — which was the real cause of the misalignment — the ends now reach
     it properly. */
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-xs);
  /* 2026-09-05 — the footer measured ~127px with the space above it, and most
     of that was not padding but LINE-HEIGHT: everything here inherited 1.6
     from body, a reading value, applied to single lines that never wrap. 1.3
     is right for one-line UI text and takes the height out without touching
     the type size Sal just set. */
  line-height: 1.3;
  margin-top: var(--s-3);
  background: var(--surface);
}

footer a { color: var(--ink-soft); margin: 0 0.5rem; }
footer a:hover { color: var(--ink); }

/* ---------- Button base ---------- */
.btn.primary {
  background: var(--coral);
  color: #fff;
  padding: 0.7rem 1.25rem;
  border: none;
  border-radius: var(--radius);
  font-weight: 600;
  font-family: var(--sans);
  font-size: var(--t-sm);
  cursor: pointer;
  transition: var(--transition);
}

.btn.primary:hover { background: var(--coral-ink); }

/* Sign up / Sign back in choice — placed after the welcome copy. */
.door-cta {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 1.5rem;
}

.door-cta-btn {
  flex: 0 0 auto;
  min-width: 0;
  padding: 0.8rem 2rem;
  font-size: var(--t-sm);
  font-weight: 600;
}

/* "Sign back in" — coral outline, secondary to the filled "Sign up". */
.door-cta-ghost {
  background: transparent;
  color: var(--coral-ink);
  border: 1.5px solid var(--coral);
  border-radius: var(--radius);
  font-family: var(--sans);
  cursor: pointer;
  transition: var(--transition);
}

.door-cta-ghost:hover { background: var(--coral-wash); }

/* Crisis resources banner — permanently pinned at the top of the Safety Center. */
.crisis-banner {
  background: var(--coral-wash);
  border: 1px solid var(--coral);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.75rem;
}
.crisis-banner h2 { margin-top: 0; color: var(--coral-ink); }
.crisis-banner p { margin: 0.5rem 0; }

/* Community Guidelines list on the Safety Center. */
.rules-list { margin: 0 0 1rem; padding-left: 1.4rem; }
.rules-list li { margin-bottom: 0.75rem; line-height: 1.6; }
.rules-closing { margin-top: 1rem; }

/* Header "Sign in" — noticeable, top-right, so returning Lübas always have a
   clear way back in (the door speaks to everyone, not just newcomers).
   Hidden once signed in, when the whole front door is gone. */
.header-signin {
  /* Was `top: 50%` — centred on the band. That was written when the header was
     a wordmark and two taglines, and it was fine then. The nine-page reading
     nav arrived on 20 Sep and now occupies the bottom of the header, so the
     middle of the band is the nav's row, not the wordmark's.

     MEASURED on the live site at 1280x900, before any change here:
     document.elementFromPoint inside the button's box returns the nav link
     "Organizations". The button has been sitting on top of the last link on
     desktop as well as on phones — it is just less obvious on a wide screen
     because only one label reaches that far.

     Pinned to the wordmark's row instead. The button's position no longer
     depends on how tall the header happens to be, which is the property that
     kept breaking every time something was added to the header. */
  position: absolute;
  top: 0.6rem;
  transform: none;
  right: 1.25rem;
  padding: 0.4rem 1.05rem;
  font-size: var(--t-sm);
}

body.authed .header-signin { display: none; }

/* ================================================================
   PUBLIC-INTRO — SEO-facing content above the sign-in wall.
   Visible to search bots and anonymous visitors (no auth, no JS gate).
   Hidden once signed in — authed members skip the marketing.

   Desktop: clean centered marketing section.
   Mobile: greeting → pure photo band → white callout with headline +
   tagline + buttons → café-forward body copy for SEO / on-scroll.
   ================================================================ */
body.authed .public-intro { display: none; }
/* Full-bleed edge-to-edge on both mobile and desktop — even when main
   has side padding. Body's overflow-x:clip prevents horizontal scroll.
   Continuous white canvas across greeting → photo → callout → body so
   the whole above-the-fold reads as one clean premium surface. */
.public-intro {
  margin: 0;
  padding: 0;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: 100vw;
  background: var(--surface);
}

.public-intro-photo {
  /* Base (desktop). Mobile @media block overrides this with the full
     uncropped band — a phone is portrait, the photo is short there, and
     nothing is being pushed off the fold.

     2026-09-04 — THE FOLD FIX (BUILD-ORDER item 38).
     The photo is 1287x638, so locked to its own ratio and run full-bleed
     it renders ~714px tall on a 1440px laptop. Under the header and the
     greeting that is the entire first screen: a visitor met the barbecue
     and never reached "Why we're here", which is the reason the place
     exists. Sal, 4 Sep: "people don't even get to see the whole reason
     why the app exists they just see this huge barbecue picture."

     This REVERSES the earlier deliberate no-crop decision, knowingly.
     Capping the height crops, and the trade is worth it: every face in
     the photo sits in the upper half, and the bottom third is table and
     food bowls. Positioning at 34% keeps all five foreground faces and
     drops the crockery. What is gained is the callout and the first of
     the story being visible without scrolling.

     min() rather than a flat px so a short laptop and a tall monitor both
     end up with a band, not a wall. The floor stops it collapsing to a
     letterbox slot on a landscape phone.

     CORRECTED same day. The first attempt centred the crop at 34%, which
     took the top of the frame — and the woman at the barbecue lost her
     face. Sal: "you should have zoomed out."

     So: crop from the BOTTOM ONLY (`center top`), and shape the band to
     roughly the top 60% of the photo. Everyone survives that line — the
     barbecue at ~9% down, the three at the picnic table at ~35%, the
     people by the fence at ~14%. What goes is the front edge of the
     table and the bowls of food, which is the part carrying no faces.
     Same effect as zooming out on the people, without re-cutting the
     image file. */
     CORRECTED AGAIN, same day, and this is the real fix.

     Sal: "zoom it out just a little bit more... hold the picture and slide
     it up... there's about three quarters of an inch of greenery on top of
     the people's heads, and the women in the foreground their faces are cut
     off a bit."

     Both at once is impossible with a full-bleed `cover` crop: at a fixed
     width the height is fixed by the ratio, so showing MORE of the scene can
     only mean a TALLER band. Every previous attempt was moving a window over
     a photo that had dead space at the top and food at the bottom.

     So the dead space came out of the FILE instead. assets/hero-band.jpg is
     hero.jpg cropped to rows 8-455 of 638: the greenery above the heads and
     the bowls along the front of the table, neither of which carries a face.
     What is left is the people, and it is 2.88:1 rather than 2.02:1.

     Then `max-width` holds the band at a width where that whole crop fits in
     ~410px — so nothing is cropped a second time by CSS. Genuinely zoomed
     out: the entire picture, smaller. hero.jpg itself is untouched and still
     the Open Graph / social preview image. */
  display: block;
  width: 100%;
  /* 2026-09-05 — height now follows the VIEWPORT, not a fixed number.
     Screenshot showed "You know how most apps..." cut in half by the fold on
     Sal's screen. The photo is the only block big enough to pay for that, but
     capping its HEIGHT would crop faces, so the WIDTH is capped instead and
     the height follows the aspect ratio. Nothing is ever cropped.

       viewport 700px tall -> 735px wide -> 255px tall
       viewport 800px       -> 840px      -> 292px
       viewport 900px       -> 945px      -> 328px
       viewport 1000px+     -> 950px      -> 330px  (unchanged)

     Short screens get the relief; tall screens see no difference. */
  max-width: min(950px, 105vh);
  /* Rounded on all four corners, 20px to match .hero and .landing-cta so the
     photo belongs to the same family as everything else on the page. Safe
     here because the band is inset at 950px; the mobile rule below runs it
     edge to edge, where a radius would cut the corners against the screen. */
  border-radius: 20px;
  overflow: hidden;
  aspect-ratio: 1287 / 447;
  height: auto;
  min-height: 180px;
  margin: 0 auto;
  padding: 0;
  background: url("../assets/hero-band-2026-10b.jpg") center top / cover no-repeat #1a1512;
}

/* Desktop uses the same base .public-intro-photo above — aspect-ratio
   locked to the image (1287/768) with cover — so the whole photo is
   visible on any viewport width. No crop, no dark bars, no zoom-in. */
.public-intro-callout {
  background: var(--surface);
  /* 2026-09-04 balance pass: 32 all round -> 22/22, then 14 on top so the
     tagline sits closer under the photo (Sal: pull the text up a little). */
  padding: var(--s-2) var(--s-5) var(--s-3);
  text-align: center;
}
.public-intro-callout > * {
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}

/* 2026-09-04 — Sal reported this line still sitting left after it was
   centred on the rule itself. Every rule that touches it — base, all three
   media blocks, the parent — reads center, and no JS sets alignment, so the
   cause was not found in this stylesheet. Rather than guess, this three-class
   selector (0,3,0) outranks anything a single-class rule can say, in any
   block, at any breakpoint, regardless of source order. No !important
   needed. If something outside this file is responsible, this still wins. */
.public-intro .public-intro-callout .public-tagline {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
.public-intro-body {
  background: var(--surface);
  /* 2026-09-05 — THE DEAD SPACE. This had 30px of bottom padding while the
     section below adds 32px of margin: 62px of nothing between the lede and
     "Why We Exist", two gaps doing one job. The section margin alone is the
     gap now. */
  /* 2026-09-05, seen in a screenshot at last. Bottom padding was 0, so the
     white section ENDED about 6px under "relationships or familyships." and
     the cream band began hard against the sentence. That colour boundary
     hugging the text is what read as "too tight" — not the heading gap below
     it, which measures correctly. A section needs room before its background
     changes. */
  padding: 0 var(--s-5) var(--s-4);
  text-align: center;
}
.public-intro-body .public-lede {
  max-width: 720px;
  margin: 0 auto 1rem;
}
.public-intro-body .public-lede:last-of-type { margin-bottom: 0; }
/* Greeting section — the warm "We're Glad You're Here!" line, positioned
   ABOVE the photo hero so it's the first thing a visitor reads. */
.public-intro-greeting {
  background: var(--surface);
  /* 2026-09-04 balance pass: 24/20 -> 17/14. */
  /* 2026-09-05 — Sal: the welcome line sits too close to the photo. Bottom
     gap 12px -> 24px. Paid for by taking 12px off the "Why We Exist" heading
     gap below, which she said was too large — so the page height is unchanged
     and the space simply moved to where it was needed. */
  padding: var(--s-2) var(--s-5) var(--s-3);
  text-align: center;
}.public-headline {
  font-family: var(--serif);
  /* Matched to its partner on the shared line. */
  font-weight: 500;
  font-size: var(--t-lg);
  line-height: 1.25;
  letter-spacing: -0.012em;
  color: var(--ink);
  margin: 0;
  border: none;
  padding: 0;
}
.public-tagline {
  font-family: var(--serif);
  font-style: italic;
  /* 2026-09-04 — Sal: left-aligned, and it should be bold. Centring is
     stated here rather than left to inherit from the callout, because the
     <=860px block redeclares this rule and any inherited alignment there
     was one edit away from being lost. Same reason the weight is repeated
     in that block: it set 400 and would have quietly undone the bold. */
  font-weight: 600;
  text-align: center;
  /* Bold and coral by Sal's explicit request — the one brand line allowed
     to wear the action colour. It carries no underline, which is how voice
     is told apart from something clickable. */
  font-size: var(--t-md);
  line-height: 1.4;
  color: var(--coral-ink);
  /* Bottom margin now lives on .public-greeting-row — the two share a line. */
  margin: 0;
}
.public-lede {
  font-family: var(--sans);
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 620px;
  margin: 0 auto var(--s-3);
}
.public-lede:last-of-type { margin-bottom: 0; }
/* 2026-09-04 — the buttons were flex:1 into a 520px row, so each came out
   ~250px wide. At equal width "Sign in" carried the same visual weight as
   "Pull up a Seat", and the person arriving for the first time is who this
   screen is for. They now size to their own text. The 52px height is
   deliberately untouched: a generous target is kindness to anyone older,
   on a trackpad, or with unsteady hands. */
.public-actions {
  display: flex;
  gap: var(--s-2);
  justify-content: center;
  flex-wrap: wrap;
  max-width: none;
  margin: var(--s-3) auto 0;
}
.public-cta-primary,
.public-cta-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 1 auto;
  padding: 0.85rem 2.1rem;
  border-radius: 999px;
  font-family: var(--sans);
  font-weight: 600;
  font-size: var(--t-sm);
  text-decoration: none;
  min-height: 52px;
  transition: var(--transition);
  cursor: pointer;
}
.public-cta-primary {
  background: var(--coral);
  color: #fff;
  box-shadow: 0 8px 22px rgba(216, 74, 50, 0.24);
  border: none;
}
.public-cta-primary:hover { background: var(--coral-ink); text-decoration: none; color: #fff; }
.public-cta-secondary {
  background: transparent;
  color: var(--coral-ink);
  border: 1.5px solid var(--coral);
}
.public-cta-secondary:hover { background: var(--coral-wash); text-decoration: none; color: var(--coral-ink); }

/* ---------- The secure entrance (front door) ---------- */
/* Gated app sections are hidden until a real account is signed in. */
body:not(.authed) .gated { display: none !important; }
body.authed #front-door { display: none; }

.front-door {
  display: flex;
  justify-content: center;
  margin-bottom: 1.5rem;
}

.door-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 2.5rem 2.75rem;
  max-width: none;
  width: 100%;
  text-align: left;
}

.door-headline {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-lg);
  color: var(--ink);
  text-align: center;
  text-transform: uppercase;
  margin: 0 0 0.6rem;
}

.door-subline {
  margin: 0 0 1rem;
  text-align: center;
  font-size: var(--t-sm);
  color: var(--ink);
  font-weight: 500;
  line-height: 1.5;
}

.door-body {
  margin: 0 0 var(--s-3);
  font-size: var(--t-md);
  font-weight: 400;
  color: var(--ink-soft);
  line-height: 1.6;
  text-align: center;
}

/* Verified-return greeting: the whole line in brand coral, centered. */
/* The "you're verified" banner on the sign-in panel. This is the first thing
   a new Lüba sees coming back from the email link, and for most of them the
   session was left behind in another browser — so it has to carry the good
   news and the one remaining step on its own. */
.door-welcome {
  color: #FF6A52;
  text-align: center;
  margin: 0 0 1.25rem;
  padding: 0.9rem 1rem;
  border: 1px solid rgba(255, 106, 82, 0.35);
  border-radius: 12px;
  background: rgba(255, 106, 82, 0.08);
}

.door-welcome-head {
  margin: 0;
  font-weight: 700;
  font-size: var(--t-sm);
  line-height: 1.3;
}

.door-welcome-body {
  margin: 0.35rem 0 0;
  font-weight: 500;
  font-size: var(--t-sm);
  line-height: 1.4;
  color: inherit;
  opacity: 0.9;
}

/* Coral heart favicon used inline in place of an emoji. */
.welcome-heart {
  height: 1em;
  width: auto;
  vertical-align: -0.15em;
  margin-left: 0.1em;
}

/* Gentle heads-up that the first email may land in spam — friendly, not alarming. */
.door-spam-note {
  margin: 0 0 1.25rem;
  padding: 0.7rem 0.85rem;
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--ink-soft);
  text-align: left;
  background: #FFF3F0;
  border: 1px solid #FFD9D1;
  border-radius: 10px;
}

/* Louder variant — used while Firebase's default sender is being filtered to
   spam (OPEN-ITEMS 0b). Someone who misses this note never verifies and never
   reaches the room, so it has to read before the button, not after it.
   Drop back to plain .door-spam-note once the custom sender domain is live. */
.door-spam-loud {
  font-size: var(--t-sm);
  color: var(--ink);
  border-left: 4px solid var(--coral);
  padding-left: 0.9rem;
}
.door-spam-loud strong { color: var(--coral-ink); }

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

.door-form label {
  display: block;
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--ink-soft);
  margin: 0.85rem 0 0.35rem;
}

.door-form label .hint {
  font-weight: 400;
  color: var(--ink-muted);
}

.door-form input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-family: var(--sans);
  color: var(--ink);
  background: var(--surface);
  transition: var(--transition);
}

.door-form input:focus {
  border-color: var(--coral);
  outline: none;
  box-shadow: 0 0 0 3px var(--coral-wash);
}

/* Password show/hide toggle */
.pw-wrap {
  position: relative;
}

.pw-wrap input {
  /* room for the eye button so typed text never slips under it */
  padding-right: 3rem;
}

.pw-toggle {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 2.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  color: var(--ink-muted);
  cursor: pointer;
  border-radius: var(--radius);
  transition: var(--transition);
}

.pw-toggle:hover {
  color: var(--coral);
}

.pw-toggle:focus-visible {
  outline: none;
  color: var(--coral);
  box-shadow: 0 0 0 3px var(--coral-wash);
}

.pw-icon-hide {
  display: none;
}

.pw-toggle[aria-pressed="true"] .pw-icon-show {
  display: none;
}

.pw-toggle[aria-pressed="true"] .pw-icon-hide {
  display: block;
}

.door-btn {
  display: block;
  width: fit-content;
  min-width: 220px;
  margin: 1.25rem auto 0;
  padding: 0.8rem 1.9rem;
  font-size: var(--t-sm);
}

.door-btn:disabled { opacity: 0.65; cursor: default; }

/* ============ Professional landing (logged-out) ============ */
.front-door { display: block; }

.hero {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  min-height: 600px;
  display: flex;
  box-shadow: 0 10px 40px rgba(28, 22, 18, 0.18);
  margin-bottom: 2.75rem;
}
.hero-media {
  position: absolute;
  inset: 0;
  /* Warm coral fallback shows through until the photo paints — no cold white flash. */
  background-color: #E89B7E;
  background-image:
    linear-gradient(135deg, rgba(255,180,150,0.55) 0%, rgba(216,74,50,0.25) 60%, rgba(24,18,14,0.0) 100%),
    url("../assets/hero-2026-10.jpg");
  background-position: center 38%, center 38%;
  background-size: cover, cover;
  background-repeat: no-repeat, no-repeat;
}
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(24,18,14,0.80) 0%, rgba(24,18,14,0.52) 42%, rgba(24,18,14,0.18) 72%, rgba(24,18,14,0.04) 100%),
    linear-gradient(0deg, rgba(216,74,50,0.22), transparent 45%);
}
.hero-content {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: clamp(2rem, 4vw, 4rem);
  padding: clamp(1.75rem, 3.5vw, 3rem) clamp(1.5rem, 2.5vw, 2.25rem) clamp(1.75rem, 3.5vw, 3rem) clamp(2rem, 5vw, 4rem);
}
.hero-copy { flex: 1 1 auto; max-width: 580px; color: #fff; }
.hero-eyebrow {
  display: inline-block;
  margin: 0 0 1.1rem;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(255, 106, 82, 0.92);
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
}
.hero-headline {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.2rem, 4.2vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  color: #fff;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
}
.hero-subline {
  margin: 0;
  max-width: 520px;
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  line-height: 1.5;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.28);
}

/* ============ FRONT-DOOR & AUTH CARD (universal) ============
   The inline front-door hero is retired everywhere — the .public-intro
   sections above are the landing on both mobile and desktop. The auth
   card only appears when a CTA (Pull up a Seat / Sign in / header
   Sign in) is tapped, at which point body.signup-open is set and the
   card renders centered below the intro. */
.front-door .hero { display: none; }

/* BUG FIX 2026-08-17 — the signup card was unreachable on EVERY device.
   #auth-card is nested inside .hero, and the rule directly above switches
   .hero off. A display:none ancestor hides all of its descendants no matter
   what they declare themselves, so `body.signup-open .auth-card{display:block}`
   further down could never take effect. Tapping "Pull up a Seat" correctly set
   body.signup-open and absolutely nothing appeared — no form, no way in.
   Reveal only the wrapper chain the card actually needs, and neutralise the
   retired hero's own layout (600px min-height, flex, rounded card, shadow) so
   the form sits on a clean surface. The retired hero visuals stay hidden so
   nothing duplicates the .public-intro landing above. */
body.signup-open .front-door .hero {
  display: block;
  min-height: 0;
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 0;
  overflow: visible;
}
body.signup-open .front-door .hero-content {
  display: block;
  padding: 0;
  gap: 0;
}
body.signup-open .front-door .hero-media,
body.signup-open .front-door .hero-scrim,
body.signup-open .front-door .hero-copy { display: none; }
.front-door {
  display: block;
  background: var(--bg);
  padding: 0;
  margin: 0;
}
body.signup-open .front-door {
  padding: 2.75rem 1.5rem 3rem;
}
.auth-card { display: none; }
body.signup-open .auth-card {
  display: block;
  /* Warm paper, not office white — see --surface-card. Sal, 21 Sep. */
  background: var(--surface-card);
  max-width: 480px;
  width: 100%;
  margin: 0 auto;
  padding: 2rem 1.75rem 2.25rem;
  text-align: left;
  border: 1px solid var(--line);
  border-top: 4px solid var(--coral);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(24,18,14,0.15);
}
body.signup-open .door-form input,
body.signup-open .door-form .pw-wrap { min-width: 0; width: 100%; }

/* The hero CTA + sign-in link + locked tagline line are legacy mobile-only
   sub-elements from an earlier iteration — never render. */
.hero-cta,
.hero-signin-link,
.hero-tagline-line { display: none; }

/* ============ MOBILE LANDING (2026-07-07 rebuild v4) ============
   Top-to-bottom on a phone, cleanly separated:
     1. Header (white): centered Lüba wordmark + heart, Sign in top-right
     2. Greeting (white): "We're Glad You're Here!" big + centered
     3. Photo (~50svh): the backyard dinner photo, uncluttered — no text
        or buttons overlaid on it, just the photo
     4. Callout (white): value-prop headline + tagline + two side-by-side
        buttons on a clean white section BELOW the photo
     5. Body: café-forward marketing copy for SEO / on-scroll visitors
     6. Front-door hero hidden; auth card appears as a standalone card
        below the intro when a CTA is tapped
============================================================== */
/* Below-hero: the why */
/* 2026-09-05 — the story is the heart of the page (Sal), so it is now the
   biggest body text on it: 0.95rem -> 1.12rem. Measure narrowed 760 -> 660px
   to hold roughly 65 characters a line at the larger size, which is the
   comfortable reading width. Comfort is the point when someone is meant to
   FEEL this rather than skim it. */
/* 2026-09-05 — the gap above "Why We Exist" was ZERO. Killing the dead space
   earlier removed 30px of padding on the assumption that section{margin-bottom}
   would still supply the gap — but .public-intro sets margin:0, which cancels
   it. Nothing replaced it. 32px above, stated here rather than inherited from
   a rule that gets overridden. */
/* PADDING, not margin, and the reason matters. A margin-top here COLLAPSES:
   .front-door has no padding and no border, so the child's top margin passes
   straight through it and is hoisted out of the layout. The CSS said 32px and
   the page rendered 0 — which is why setting a margin twice changed nothing.
   Padding cannot collapse. */
.landing-story { max-width: 660px; padding-top: var(--s-3); margin: 0 auto var(--s-5); text-align: center; }
.landing-h {
  /* ONE font-size. There were two — 1.95rem then 1.6rem — and the second
     silently won. 2026-09-05: down another step on Sal's call — "the statement
     Why We Exist doesn't have to be that large" — so 25px -> 20px. It still
     outranks the story beneath it, because that is 20px at weight 400 while
     this is 20px at 500 in the serif. Rank does not have to mean bigger. */
  font-size: var(--t-md);
  /* 2026-09-05 — Nunito was tried here and reverted the same hour. Sal:
     "it is not even the same font, you gotta put it back to what it was."
     Correct: one heading in a family of its own reads as a mistake, not a
     choice. If the warm face is ever wanted it has to be the whole system —
     wordmark, welcome pair, card titles — not one line. */
  font-family: var(--serif);
  font-variation-settings: "opsz" 14, "SOFT" 100, "WONK" 0;
  font-weight: 500;
  color: var(--ink);
  /* line-height was inheriting 1.6 from body — loose for display type, and it
     padded this heading's own line box by 7.5px above and below, which is why
     the space under it read as bigger than the 12px actually set. 1.2 makes
     the gap on screen match the gap in the CSS. */
  line-height: 1.2;
  /* 24px -> 12px. Sal: too large a gap between the heading and the story. */
  margin: 0 0 var(--s-2);
}
.landing-story .door-body { text-align: center; max-width: none; margin: 0 0 var(--s-3); }

/* 2026-09-05 — the house note. Sal: "same words, different register."
   Everything above it is a promise TO the reader; this is the only line that
   asks something OF them, so it earns a voice of its own rather than being a
   fourth paragraph. Coral, serif italic, a size down, and a hairline above it
   to set it apart — a note pinned to the wall, not another clause. */
.door-note {
  max-width: 620px;
  margin: 0 auto;
  /* 2026-09-05 — Sal did not like the SERIF italic; Fraunces italic is a
     flourish. Inter italic is not — it just leans. So the face stays Inter
     and the slant comes back on her request. Everything else about this line
     is unchanged: same place, same size, same coral. */
  font-family: var(--sans);
  font-style: italic;
  /* Coral, and deliberately not underlined — see the tagline note. Voice,
     not a link. */
  font-weight: 500;
  font-size: var(--t-md);
  line-height: 1.5;
  color: var(--coral-ink);
  text-align: center;
}

/* Value cards */
.landing-values {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* 2026-09-05 — smaller and tighter, so they support the story instead of
     competing with it. */
  gap: var(--s-3);
  max-width: 900px;
  margin: 0 auto var(--s-4);
}
.value-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-3);
  text-align: center;
  box-shadow: var(--shadow-sm);
}
.value-ico { font-size: var(--t-lg); display: block; margin-bottom: var(--s-1); }
.value-card h4 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-md);
  margin: 0 0 var(--s-1);
  color: var(--ink);
}
.value-card p { margin: 0; font-size: var(--t-sm); font-weight: 400; line-height: 1.55; color: var(--ink-soft); }

/* Closing CTA — 2026-09-05, third attempt and the right one.

   Sal: "the coral banner at the bottom is still the entire length of the
   screen, it is so ridiculous and oversized." Twice I made the band smaller.
   The band was the problem. A full-width, high-contrast slab at the foot of a
   page is the exact shape people have been trained to ignore — Nielsen Norman
   Group documented it by eyetracking as banner blindness — and bottom-of-page
   banners convert around 0.9% where inline calls to action get 121% more
   clicks than the same offer set apart in furniture.

   So there is no band now. A sentence in the page's own voice, and one coral
   button beside it. Coral where it belongs: on the thing you press. The first
   line of this stylesheet has said so all along — "Coral is the accent, not
   the wallpaper."

   204px originally, 84px after two trims, ~52px now. */
.landing-cta {
  background: none;
  border-radius: 0;
  padding: 0;
  margin: 0 auto var(--s-2);
  max-width: 660px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
}
.landing-cta h3 {
  font-family: var(--serif);
  font-weight: 500;
  color: var(--ink);
  font-size: var(--t-md);
  line-height: 1.4;
  margin: 0;
}
.landing-cta-btn {
  /* 2026-09-05 — reversed on Sal's call: white button, coral lettering.
     The coral border is not decoration — this sits on the near-white page
     background (#FAF7F2), and without it a white button on an off-white
     page has almost no edge to find. */
  /* 2026-09-05 — the heart lives in the button now (Sal). Rectangular rather
     than a pill so the mark has square corners to sit against, and nudged
     down a step so it is not crowding the note above it. */
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  background: #fff;
  border: 1.5px solid var(--coral);
  color: var(--coral-ink);
  padding: 0.6rem 1.4rem;
  margin-top: var(--s-1);
  border-radius: 14px;
  font-weight: 600;
  font-size: var(--t-sm);
  min-height: 44px;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
}
/* The heart inside the Join button. Decorative — alt="" — because the button
   already says what it does; a screen reader announcing an image here would
   just add noise to a clear label. */
.btn-heart {
  width: 26px;
  height: 26px;
  object-fit: contain;
  flex: 0 0 auto;
}
.landing-cta-btn:hover { background: var(--coral); border-color: var(--coral); text-decoration: none; color: #fff; opacity: 1; }


/* ============ Neighbourhood picker (Section 3 — room selection) ============ */
.nbhd-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.nbhd-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-lg);
  margin: 0 0 0.3rem;
  color: var(--ink);
}
.nbhd-sub { margin: 0; color: var(--ink-muted); font-size: var(--t-sm); max-width: 620px; }
/* The account chip sits hard right, on every width.
   Sal, 20 Sep: "This is supposed to be aligned right and right now you have it
   on the left: SA Sal Sign out".
   .nbhd-head is space-between, which only right-aligns this while both children
   fit on one line. The greeting had no flex basis, so on a narrower window it
   claimed the full row, the account wrapped underneath it — and a wrapped flex
   item starts at the LEFT. margin-left:auto keeps it right whether it wraps or
   not, and giving the welcome a basis lets it shrink instead of shoving. */
.nbhd-welcome { flex: 1 1 260px; min-width: 0; }
.nbhd-account {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--t-xs);
  flex-wrap: wrap;
  margin-left: auto;
  justify-content: flex-end;
  text-align: right;
}

.nbhd-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 258px), 1fr));
  gap: 1.1rem;
}
.nbhd-card {
  --nbhd-accent: #FF6A52;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--nbhd-accent);
  border-radius: var(--radius-lg);
  padding: 1.4rem 1.35rem 1.15rem;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}
.nbhd-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--nbhd-accent); }
.nbhd-card:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--coral-wash); }
.nbhd-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  font-size: var(--t-lg);
  margin-bottom: 0.2rem;
  background: #F3EEE6;
  background: color-mix(in srgb, var(--nbhd-accent) 16%, #fff);
}
.nbhd-name { font-family: var(--serif); font-weight: 500; font-size: var(--t-md); color: var(--ink); }
.nbhd-invite { font-size: var(--t-xs); line-height: 1.5; color: var(--ink-soft); flex: 1 1 auto; }
.nbhd-presence {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--t-xs);
  font-weight: 600;
  color: #2e9e5b;
  margin-top: 0.4rem;
}
.nbhd-presence .nbhd-dot { font-size: var(--t-xs); line-height: 1; }
.nbhd-presence.is-quiet { color: var(--ink-muted); font-weight: 500; }

/* Main Room leads the grid — full width, horizontal. */
.nbhd-card.is-main {
  grid-column: 1 / -1;
  border-left-width: 5px;
  background: linear-gradient(180deg, #FFF6F3, #fff);
  flex-direction: row;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
}
.nbhd-card.is-main .nbhd-invite { flex: 1 1 240px; }


/* The welcome, where someone actually arrives — 2026-09-18.
   Sal: "that comment so glad you’re here, it should be like front and centre
   for them to see." It was living in the row status slot, small and right
   aligned. This is the first line on the board now, and it carries their name. */
/* "Who's on Lüba right now" — the first thing on the board, 2026-09-19.
   Sal: "that should be the very first thing that people see on the main page,
   because then they're going to stick around." Sits directly under the
   greeting, above everything else, and reads as life rather than as a stat. */
.lobby-count {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 var(--s-2);
  font-size: var(--t-sm);
  font-weight: 600;
  color: #2e9e5b;
}
.lobby-count .lobby-dot { font-size: var(--t-xs); line-height: 1; }
/* "Here: 3", at the right of the Lobby head (Sal, 4 Oct) — beside the
   greeting rather than on a line of its own, so the Lobby moves up. */
.nbhd-head .lobby-count { margin: 0.35rem 0 0 auto; white-space: nowrap; }
/* The greeting is switched off for good (below), so with the counter hidden the head row is
   empty — but kept its 24px gap, which was the band Sal saw (4 Oct). */
.nbhd-head:not(:has(#lobby-count:not([hidden]))) { margin-bottom: 0; }

.nbhd-greeting {
  margin: 0 0 var(--s-1);
  font-family: var(--serif);
  font-size: var(--t-lg);
  font-weight: 500;
  line-height: 1.25;
  color: var(--coral-ink);
}
.nbhd-greeting .nbhd-heart { font-size: 0.95em; }

/* "N new messages" — the reader decides when to move — 2026-09-18.
   Sal: "users should not be yanked around at all." The room no longer jumps
   to the bottom while someone is reading; it counts what arrived and offers
   it here. Sits just above the composer, out of the transcript, so it never
   covers the thing being read. */
.new-messages {
  display: block;
  margin: 0 auto var(--s-2);
  padding: 0.45rem 1rem;
  font: inherit;
  font-size: var(--t-xs);
  font-weight: 600;
  color: #fff;
  background: var(--coral);
  border: none;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: var(--transition);
}
.new-messages:hover { background: var(--coral-ink); }
.new-messages:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--coral-wash); }

/* ============ The board (Neighbourhood picker) — 2026-09-18 ============
   Sal, 18 Sep: ten large cards "looks very busy", and the useful question —
   where are the people? — took ten reads to answer. A list answers it in one
   glance. That scannable list is the one thing AOL genuinely got right; the
   expression here is entirely ours: Fraunces, coral, warm paper, air.

   .nbhd-card is NOT retired — the Feeling-Tables screen still uses it. This is
   an addition for the Neighbourhood board only. */
.nbhd-board { display: flex; flex-direction: column; gap: var(--s-5); }

.nbhd-board-section {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-4);
  box-shadow: var(--shadow-sm);
}
.nbhd-board-label {
  font-family: var(--sans);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0;
}
.nbhd-board-note {
  margin: var(--s-1) 0 0;
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.nbhd-row {
  --nbhd-accent: #FF6A52;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: transparent;
  border: none;
  border-top: 1px solid var(--line);
  padding: var(--s-3) var(--s-2);
  margin: 0;
  border-radius: var(--radius);
  transition: var(--transition);
}
.nbhd-board-label + .nbhd-row,
.nbhd-board-note + .nbhd-row { border-top: none; margin-top: var(--s-2); }
.nbhd-row:hover { background: var(--surface-sunk); }
.nbhd-row:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--coral-wash); }
.nbhd-row:hover .nbhd-row-name { color: var(--coral-ink); }

.nbhd-row-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  font-size: var(--t-md);
  background: color-mix(in srgb, var(--nbhd-accent) 16%, #fff);
}
.nbhd-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nbhd-row-name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-md);
  color: var(--ink);
  transition: var(--transition);
}
.nbhd-row-invite {
  font-size: var(--t-sm);
  line-height: 1.45;
  color: var(--ink-muted);
}
.nbhd-row-status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--t-xs);
  font-weight: 600;
  color: #2e9e5b;
  white-space: nowrap;
}
.nbhd-row-status .nbhd-dot { font-size: var(--t-xs); line-height: 1; }
/* is-invite: what a row says when there is no count to show. It names what a
   click does, never what the room lacks. */
.nbhd-row-status.is-invite { color: var(--coral-ink); font-weight: 600; }
.nbhd-row:hover .nbhd-row-status.is-invite { text-decoration: underline; text-underline-offset: 3px; }
.nbhd-row-status.is-quiet,
.nbhd-row-status.is-listed { color: var(--ink-muted); font-weight: 500; }
.nbhd-row-status.is-add {
  color: var(--coral-ink);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
}
.nbhd-row:hover .nbhd-row-status.is-add {
  border-color: var(--coral);
  background: var(--coral-wash);
}

/* Opening as we grow: present, legible, and plainly not open yet. Never
   greyed to the point of looking broken — it is a door with a date, not a
   locked one. */
.nbhd-row.is-soon .nbhd-row-ico { filter: saturate(0.75); }
.nbhd-row.is-soon .nbhd-row-name { color: var(--ink-soft); }

/* Room view */
.room-view { max-width: 900px; margin: 0 auto; }
.room-view .chat-header { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
.btn-back {
  background: transparent;
  border: none;
  color: var(--coral-ink);
  font-weight: 600;
  font-size: var(--t-xs);
  cursor: pointer;
  padding: 0.2rem 0;
  align-self: flex-start;
}
.btn-back:hover { text-decoration: underline; }

.door-fine {
  margin: 0.9rem 0 0;
  font-size: var(--t-xs);
  color: var(--ink-muted);
  line-height: 1.5;
  text-align: center;
}

.door-switch {
  margin: 1rem 0 0;
  font-size: var(--t-xs);
  color: var(--ink-soft);
  text-align: center;
}

.door-error {
  margin: 0.9rem 0 0;
  padding: 0.6rem 0.8rem;
  background: var(--coral-wash);
  border: 1px solid var(--coral);
  border-radius: var(--radius-sm);
  color: var(--coral-ink);
  font-size: var(--t-xs);
}

/* Sign out matches the existing "Change name" link button. */
#signout-btn { margin-left: 0.5rem; }

/* ---------- Responsive ---------- */
/* ---- Phone verification (the code screen) ----
   Large, widely tracked digits: this is read and typed by people with tired
   eyes, often on a phone, often once only. Nothing here should feel fiddly. */
.code-input {
  font-family: "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace;
  font-size: var(--t-xl);
  letter-spacing: .38em;
  text-align: center;
  text-indent: .38em;
  font-variant-numeric: tabular-nums;
  padding: .55rem .5rem;
}
.field-hint {
  font-size: var(--t-xs);
  color: #6E6663;
  margin: -.25rem 0 .85rem;
  line-height: 1.4;
}
/* Firebase only paints in here if it decides a challenge is needed. */
#recaptcha-container:empty { display: none; }
#recaptcha-container { margin: .5rem 0; }


/* Honeypot. Hidden every way at once: off-screen AND display:none, plus
   aria-hidden and tabindex="-1" on the markup. A screen-reader user must never
   be able to reach it — being silently rejected for filling in an invisible
   field would be the cruellest bug in the door. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  display: none !important;
}


/* ---- "Why we ask for your number" ----
   Sits between the ask and the field. Quiet, not shouty: a card that explains
   itself rather than a warning. Ticks are drawn in CSS so they inherit the
   brand colour and never arrive as a stray emoji font. */
.why-box {
  border: 1px solid rgba(255, 106, 82, 0.28);
  background: rgba(255, 106, 82, 0.06);
  border-radius: 10px;
  padding: 0.85rem 1rem 0.9rem;
  margin: 0 0 1.15rem;
}
.why-box-head {
  margin: 0 0 0.55rem;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #B4462F;
}
.why-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.why-list li {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--t-xs);
  line-height: 1.4;
  color: #4A4341;
}
.why-list li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.3rem;
  width: 0.42rem;
  height: 0.72rem;
  border: solid #FF6A52;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
@media (prefers-color-scheme: dark) {
  .why-box { background: rgba(255, 106, 82, 0.10); }
  .why-list li { color: #CFC7C4; }
  .why-box-head { color: #E0836A; }
}


/* ---- Feeling-Tables (Layer 3) ----
   Same card language as the Neighbourhoods so the two levels feel like one
   place, but quieter: you have already chosen your people, this is only how
   you want to sit today. */
#tables-screen .nbhd-welcome { display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; }
#tables-screen .btn-back { margin-bottom: .25rem; }

.nbhd-card.is-locked { opacity: .72; }
.nbhd-card.is-locked .nbhd-presence { display: none; }

/* The one-year message. CLAUDE.md is explicit: no error screen, no lock icon,
   nothing that reads as a refusal. Just the words, warmly. */
.tables-locked {
  margin: 1.25rem auto 0;
  max-width: 34rem;
  padding: 1.1rem 1.25rem;
  border-left: 3px solid #FF6A52;
  background: rgba(255, 106, 82, 0.07);
  border-radius: 0 8px 8px 0;
  font-size: var(--t-sm);
  line-height: 1.55;
  color: #4A4341;
}
@media (prefers-color-scheme: dark) {
  .tables-locked { background: rgba(255, 106, 82, 0.12); color: #CFC7C4; }
}


/* ---- "Give yourself some space" ----
   Deliberately quiet. This is not a report and not a punishment — it is one
   person choosing who they sit with, so it should feel like turning your chair,
   not pressing an alarm. */
/* Your People — sits beside "Give me space" on a message, and behaves the
   same way: invisible until you reach for it, so the transcript stays a
   conversation rather than a control panel. Once someone is on the list the
   button stays visible and coral, because that state is worth seeing. */
.msg-people {
  border: 0;
  background: none;
  padding: 0 .15rem;
  margin-left: .4rem;
  font-size: var(--t-xs);
  line-height: 1;
  color: #9E9490;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s ease, color .15s ease;
}
.chat-message:hover .msg-people,
.chat-message:focus-within .msg-people,
.msg-people:focus-visible { opacity: 1; }
.msg-people:hover, .msg-people:focus-visible { color: var(--coral); }
.msg-people.is-on { opacity: 1; color: var(--coral-ink); font-weight: 600; }

.msg-space {
  border: 0;
  background: none;
  padding: 0 .15rem;
  margin-left: .4rem;
  font-size: var(--t-xs);
  line-height: 1;
  color: #9E9490;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s ease, color .15s ease;
}
.chat-message:hover .msg-space,
.chat-message:focus-within .msg-space,
.msg-space:focus-visible { opacity: 1; }
.msg-space:hover, .msg-space:focus-visible { color: #FF6A52; }
/* Touch screens have no hover, so it must never be hidden there. */
/* Touch screens have no hover. Only "Give me space" was shown there, so on a
   phone "Add to Your People" and "Report" were invisible — but still took
   their room, which is the empty band Sal saw in every bubble (4 Oct). Members
   on phones could not add anyone to Your People at all. */
@media (hover: none) { .msg-space, .msg-people, .msg-report { opacity: .7; } .msg-people.is-on { opacity: 1; } }

.space-toast {
  display: flex;
  align-items: center;
  gap: .75rem;
  justify-content: space-between;
  margin: .5rem 0 0;
  padding: .6rem .85rem;
  border: 1px solid #E5E0DD;
  border-radius: 8px;
  background: #FBFAF9;
  font-size: var(--t-xs);
  color: #4A4341;
}
.space-undo {
  border: 0;
  background: none;
  color: #FF6A52;
  font-weight: 600;
  font-size: var(--t-xs);
  cursor: pointer;
  padding: .1rem .3rem;
}
.space-undo:hover, .space-undo:focus-visible { text-decoration: underline; }

#space-list { display: flex; flex-direction: column; gap: .5rem; margin: .75rem 0 1rem; }
.space-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .55rem .7rem; border: 1px solid #E5E0DD; border-radius: 8px;
  font-size: var(--t-xs);
}
.space-row button {
  border: 0; background: none; color: #FF6A52; font-weight: 600;
  font-size: var(--t-xs); cursor: pointer;
}
.space-empty { font-size: var(--t-xs); color: #6E6663; margin: .75rem 0 1rem; }

@media (prefers-color-scheme: dark) {
  .space-toast { background: #201B1A; border-color: #352E2C; color: #CFC7C4; }
  .space-row { border-color: #352E2C; }
  .space-empty { color: #9E9490; }
}


/* ---- Moderation, before the message leaves ----
   Firm but not shouty. The point is to make someone look again, not to make
   them feel caught. Warm border rather than a red alarm. */
.mod-hold {
  margin: .5rem 0 .25rem;
  padding: .9rem 1rem 1rem;
  border: 1px solid #B4462F;
  background: #FBE7E1;
  border-radius: 10px;
}
.mod-hold-title { margin: 0 0 .35rem; font-weight: 600; font-size: var(--t-sm); color: #B4462F; }
.mod-hold-why   { margin: 0 0 .5rem; font-size: var(--t-xs); line-height: 1.45; color: #4A4341; }
.mod-hold-note  { margin: 0 0 .75rem; font-size: var(--t-xs); line-height: 1.45; color: #4A4341; }
.mod-hold .btn  { width: auto; }

/* Distress. Nothing here says no to anybody. */
.mod-care {
  margin: .5rem 0 .25rem;
  padding: .9rem 1rem 1rem;
  border: 1px solid #FF6A52;
  background: rgba(255,106,82,.08);
  border-radius: 10px;
}
.mod-care-lead { margin: 0 0 .4rem; font-weight: 600; font-size: var(--t-sm); color: #4A4341; }
.mod-care-body { margin: 0 0 .6rem; font-size: var(--t-xs); line-height: 1.5; color: #4A4341; }

@media (prefers-color-scheme: dark) {
  .mod-hold { background: #2E1C17; border-color: #E0836A; }
  .mod-hold-title { color: #E0836A; }
  .mod-hold-why, .mod-hold-note, .mod-care-lead, .mod-care-body { color: #CFC7C4; }
  .mod-care { background: rgba(255,127,106,.10); border-color: #FF7F6A; }
}


/* ---- Telling us about a message ---- */
.report-panel {
  margin: .5rem 0 .25rem;
  padding: .9rem 1rem 1rem;
  border: 1px solid #E5E0DD;
  border-radius: 10px;
  background: #FBFAF9;
}
.report-title { margin: 0 0 .4rem; font-weight: 600; font-size: var(--t-sm); }
.report-quote {
  margin: 0 0 .7rem; padding: .45rem .6rem;
  border-left: 3px solid #E5E0DD; background: #FFF;
  font-size: var(--t-xs); color: #6E6663; line-height: 1.4;
  max-height: 5rem; overflow: auto; border-radius: 0 6px 6px 0;
}
.report-reasons { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .75rem; }
.report-reason {
  border: 1px solid #E5E0DD; background: #FFF; border-radius: 999px;
  padding: .35rem .7rem; font-size: var(--t-xs); cursor: pointer; color: #4A4341;
}
.report-reason:hover, .report-reason:focus-visible { border-color: #FF6A52; color: #FF6A52; }
.report-reason.is-picked { background: #FF6A52; border-color: #FF6A52; color: #FFF; }
.report-note-label { display: block; font-size: var(--t-xs); color: #6E6663; margin-bottom: .25rem; }
.report-note { width: 100%; border: 1px solid #E5E0DD; border-radius: 6px; padding: .45rem .6rem; font: inherit; font-size: var(--t-xs); resize: vertical; }
.report-actions { display: flex; align-items: center; gap: 1rem; margin-top: .75rem; }
.report-actions .btn { width: auto; }

.msg-report {
  border: 0; background: none; padding: 0 .15rem; margin-left: .3rem;
  font-size: var(--t-xs); line-height: 1; color: #9E9490; cursor: pointer;
  opacity: 0; transition: opacity .15s ease, color .15s ease;
}
.chat-message:hover .msg-report,
.chat-message:focus-within .msg-report,
.msg-report:focus-visible { opacity: 1; }
.msg-report:hover, .msg-report:focus-visible { color: #B4462F; }
@media (hover: none) { .msg-report { opacity: .7; } }

@media (prefers-color-scheme: dark) {
  .report-panel { background: #201B1A; border-color: #352E2C; }
  .report-quote { background: #171413; border-left-color: #352E2C; color: #9E9490; }
  .report-reason { background: #171413; border-color: #352E2C; color: #CFC7C4; }
  .report-note { background: #171413; border-color: #352E2C; color: #F2EEEC; }
  .report-note-label { color: #9E9490; }
}



/* Footer layout — 2026-09-05, Sal: share on the left and bold, legal links on
   the right. Wraps to stacked and centred on a narrow screen, where two
   opposite corners would leave a gap in the middle instead of a shape. */
.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  /* 2026-09-05 — Sal wants the two ends further apart. The row was capped at
     1080px and centred, which parked both ends well inside the page. It now
     runs the full width of the footer, so share sits at the left edge and the
     policies at the right. */
  gap: var(--s-1) var(--s-4);
  max-width: none;
  width: 100%;
  margin: 0 0 var(--s-1);
  text-align: left;
}
/* The share line is the one thing in the footer meant to be READ, not
   skimmed past. It was 0.82rem and muted, i.e. the same weight as the legal
   links beside it. Now 1.15rem, bold, in ink rather than the footer grey. */
/* 2026-09-05 — both ends of the footer are now the same size and the same
   warm grey, so the row reads as balanced rather than as a loud end and a
   quiet one. Coral is kept for the Facebook link alone, because that is the
   only thing here you act on. */
.footer-share-line {
  /* min-width:0 and its own wrap matter: this line now holds four things —
     the label, the share link, the Facebook link and the heart. Without them
     it refuses to shrink, and .footer-row wraps the policies onto a second
     line instead, where they stop looking right-aligned at all. It wraps
     inside itself now; the two ends stay anchored. */
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-1);
  /* 2026-09-05 — Sal: "they both look kind of elementary, they don't look
     like they're from a professional site." They were identical — both ends
     20px semibold in the same grey — so two things with opposite jobs were
     dressed the same. Differentiated by role now.

     THIS side is the invitation: the serif, so it carries the same voice as
     the rest of the page, and 16px rather than 20. Warm, and human. */
  font-family: var(--serif);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-soft);
}
/* "Share link" performs an action, so it is a button; it sits mid-sentence
   beside a link, so it looks like one. Same coral and underline as the
   Facebook link, because they do the same job by different routes. */
.footer-sharelink {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  /* Pinned: the label grew, this did not. */
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--coral-ink);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.footer-sharelink:hover { color: var(--coral); }
.footer-share-done {
  color: var(--ink-muted);
  font-size: var(--t-sm);
  font-style: italic;
}
/* Icon only now, and in Facebook's own blue rather than our coral. A brand
   mark is recognised by its colour as much as its shape, and this is the one
   thing in the footer that is not ours — so it is the one place the coral
   rule does not apply. No underline: there is no text to underline, and the
   mark itself is the affordance. */
.footer-fb {
  display: inline-flex;
  align-items: center;
  color: #1877F2;
  margin: 0;
  line-height: 0;
  text-decoration: none;
}
.footer-fb:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; border-radius: 4px; }
.footer-fb svg { flex: 0 0 auto; }
.footer-fb:hover { color: #0f5fd0; text-decoration: none; }
/* 2026-09-05, CORRECTED. These were made bold coral to match the share line,
   on a literal reading of "same colour, same size". That dressed the least
   important text on the page identically to the most important, and it broke
   the colour rule: coral means you can act on it. Privacy, Terms and Safety
   are fine print. They are fine print again. */
.footer-links {
  flex: 0 0 auto;
  text-align: right;
  /* THIS side is legal furniture, so it gets the treatment legal furniture
     gets on every serious site: small, uppercase, letter-spaced, muted, sans.
     It reads as considered rather than shouted, and it stops competing with
     the invitation opposite it. */
  font-size: var(--t-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
}
.footer-links a { color: var(--ink-muted); font-weight: 600; margin: 0 0.2rem; }
.footer-links a:hover { color: var(--ink); }
.footer-legal { text-align: center; font-size: var(--t-sm); font-weight: 600; color: var(--ink-muted); }

/* ================================================================
   RESPONSIVE — rebuilt 2026-09-05.

   WHAT WAS HERE BEFORE: five breakpoints — 860, 768, 720, 620, 480 —
   written into the file in the order 860, 720, 768, 480, 620. Not
   descending. Equal-specificity rules resolve by source order, so on a
   700px window (which matches 860, 768 AND 720 at once) whichever value
   applied was accidental. It produced real bugs: the wordmark was
   2.3rem at 860, 1.75rem at 768 and 2rem at 480, so it got BIGGER on a
   smaller phone; and 768 set `main { padding: 0 0.85rem }`, quietly
   undoing the full-bleed photo that the 860 block existed to create.
   Between them the blocks carried 30 distinct spacing values and 14
   hard-coded font sizes — the same ad-hoc state the desktop was in
   before the design pass, preserved untouched.

   WHAT IS HERE NOW: two blocks, descending, both written in the same
   --t-* and --s-* tokens as the desktop. Anything a phone genuinely
   needs to do differently keeps a rule; anything that merely restated a
   desktop value is gone.

   These sit at the END of the stylesheet deliberately, so they always
   win over the desktop rules regardless of where those are declared.
   ================================================================ */

/* ---------- NARROW: tablets and large phones ---------- */
@media (max-width: 860px) {
  /* Header. The wordmark keeps its rank from the desktop scale rather
     than being re-picked per breakpoint. */
  header {
    padding: var(--s-2) var(--s-3);
    padding-top: max(var(--s-2), calc(0.55rem + env(safe-area-inset-top)));
    position: relative;
    z-index: 20;
    border-bottom: none;
  }
  header h1 { font-size: var(--t-xl); }
  #logo { width: 30px; height: 30px; filter: none; }
  /* The top row has to be as tall as the tallest thing standing in it.
     The wordmark is 28px; the sign-in button beside it is 42px, because 40px
     is the floor for something a hand has to hit and these members are the
     last people to give a fiddly tap target to. Sizing the row to the button
     is what keeps the reading nav BELOW the button instead of underneath it —
     the alternative, nudging the nav's margin until the overlap goes away, is
     arithmetic that breaks the moment either element changes size. */
  .header-signin {
    /* 2026-09-05 centred this on the header band, which was right at the time:
       the header was a wordmark and a tagline, so "half way down" was beside
       the wordmark.

       2026-09-23 — it is not right any more, and this is measured, not
       reasoned. The nine-page reading nav was added to the header on 20 Sep.
       On a 390px screen those nine labels wrap into THREE rows, so the header
       grew to 143px and "half way down" stopped meaning beside the wordmark
       and started meaning ON TOP OF THE NAV. Measured on the live site at
       390x844: the button occupies (286,50)-(378,93); nav.nav-reading occupies
       (14,42)-(376,136); document.elementFromPoint at the button's bottom-left
       corner returns the link "At Work". Two of the three nav rows run
       underneath it.

       Pinned to the TOP row now, level with the wordmark, where its position
       no longer depends on how tall the nav happens to be. The safe-area inset
       is still respected as a floor, which is what the 2026-09-05 note was
       actually protecting. */
    top: max(var(--s-2), calc(0.55rem + env(safe-area-inset-top)));
    right: var(--s-2);
    left: auto;
    transform: none;
    padding: var(--s-1) var(--s-2);
    font-size: var(--t-sm);
    min-height: 40px;
    z-index: 101;
  }
  header .tagline,
  header .tagline-line,
  header nav { display: none; }
  /* ...except the reading pages, which are for visitors arriving from search —
     and most of them arrive on a phone. See the .nav-reading block above. */
  /* ONE ROW THAT SCROLLS, not three rows that stack.

     The base rule above allows this nav to wrap, and notes that it wraps
     "below ~700px, because at phone width one line of nine is unreadable".
     Measured at 390x844 on the live site, the cost of that decision is:
     nine links, THREE rows, 94px — which is most of a 143px header, on every
     page, and it is the thing Sal is describing as pushing her content down.

     A sideways strip keeps all nine links, keeps them legible at the same
     size, and costs one row instead of three. Sal, 20 Sep, on the same nav:
     "spread them out along the page what you did was you created two rows...
     make that banner smaller It's way too wide Or like too deep."

     The right-edge fade is the part that makes this honest: a strip that
     scrolls and does not LOOK like it scrolls is a strip whose last four
     links nobody ever finds. The label is cut mid-fade on purpose — a
     half-visible word is the clearest possible signal that there is more.
     Browsers without mask-image simply get a hard edge; nothing breaks. */
  header nav.nav-reading {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: center;
    gap: 0 1rem;
    margin-top: 0.55rem;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    scroll-padding-inline: var(--s-3);
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
  }
  header nav.nav-reading::-webkit-scrollbar { display: none; }
  header nav.nav-reading a {
    font-size: var(--t-xs);
    flex: 0 0 auto;
    padding-bottom: 2px;
  }

  /* The photo runs edge to edge here, so main gives up its gutter — and
     the landing blocks below take their own, or the story would touch
     the glass. That gutter was missing before. */
  main { padding: 0; margin: 0 0 var(--s-4); }
  /* main gives up its gutter so the photo can run edge to edge, so every
     gated app section takes its own — otherwise the rounded cards below
     would sit hard against the glass. All of them carry .gated. */
  .gated { margin-left: var(--s-3); margin-right: var(--s-3); }

  /* The welcome pair cannot share a line at this width. Stacked, and the
     coral dash between them retired with the shared line. */
  .public-intro-greeting { padding: var(--s-1) var(--s-4) var(--s-2); }/* Photo: full-bleed, square corners against the screen edge. */
  .public-intro-photo {
    max-width: none;
    border-radius: 0;
    margin: 0;
  }

  .public-intro-callout {
    max-width: none;
    /* Bottom padding 24 -> 12: Sal, "way too much space below the Pull up a
       Seat and Sign in buttons". */
    padding: var(--s-3) var(--s-4) var(--s-2);
    margin: 0;
  }
  .public-tagline { font-size: var(--t-md); margin: 0 0 var(--s-3); }

  .public-actions {
    max-width: 420px;
    width: 100%;
    margin: 0 auto;
    gap: var(--s-2);
    flex-wrap: nowrap;
  }
  .public-cta-primary,
  .public-cta-secondary { flex: 1 1 0; padding: var(--s-2); min-height: 52px; }

  .public-intro-body { max-width: none; padding: 0 var(--s-4) var(--s-3); }
  .door-note { font-size: var(--t-sm); max-width: none; }
  .public-intro-body .public-lede { font-size: var(--t-sm); max-width: 560px; margin: 0 auto; }

  /* The gutter main gave up. */
  .landing-story,
  .landing-cta { padding-left: var(--s-4); padding-right: var(--s-4); }
  .landing-values {
    grid-template-columns: 1fr;
    gap: var(--s-3);
    padding: 0 var(--s-4);
  }

  /* App and door areas. */
  #help-section, #share, .welcome-band { padding: var(--s-4); }
  .welcome-manifesto { font-size: var(--t-sm); }
  .welcome-manifesto span { font-size: var(--t-md); }
  .nbhd-greeting { font-size: var(--t-md); }
  .door-card { padding: var(--s-4) var(--s-3); }
  .door-headline { font-size: var(--t-lg); }

  body.signup-open .front-door { padding: var(--s-4) var(--s-3) var(--s-5); }
  body.signup-open .auth-card { max-width: 460px; padding: var(--s-4); }

  .door-cta { flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-4); }
  .door-cta-btn {
    width: 100%;
    padding: var(--s-2) var(--s-3);
    font-size: var(--t-sm);
    min-height: 48px;
  }
  .door-btn {
    display: block;
    width: 100%;
    min-width: 0;
    margin: var(--s-4) 0 0;
    padding: var(--s-2) var(--s-3);
    font-size: var(--t-sm);
    min-height: 50px;
  }
}

/* ---------- PHONE ---------- */
@media (max-width: 520px) {
  header h1 { font-size: var(--t-lg); }
  #logo { width: 26px; height: 26px; }

  .public-intro-greeting { padding: var(--s-1) var(--s-3) var(--s-2); }
  .public-intro-callout { padding: var(--s-3) var(--s-3) var(--s-4); }
  .public-tagline { font-size: var(--t-sm); margin-bottom: var(--s-3); }

  .public-actions { max-width: none; gap: var(--s-1); }
  .public-cta-primary,
  .public-cta-secondary { padding: var(--s-2) var(--s-1); font-size: var(--t-sm); min-height: 52px; }

  .public-intro-body { padding: 0 var(--s-3) var(--s-3); }
  .landing-story,
  .landing-cta,
  .landing-values { padding-left: var(--s-3); padding-right: var(--s-3); }

  /* Two opposite corners leave a hole in the middle on a phone, so the
     footer stacks and centres instead. */
  /* 2026-09-05 — Sal: balance the label, the share link and the Facebook
     mark across the line. space-between spreads them to the full width
     instead of clustering them in the middle with the mark trailing off. */
  .footer-row { justify-content: center; text-align: center; }
  /* 2026-09-05 — the share link is now TRUE-centred between the label and
     the Facebook mark, not merely spread by space-between. space-between
     positions items by their own widths, so a long label pushed the link off
     centre. Giving the label and the mark equal flex weight and leaving the
     link at its natural width puts it exactly in the middle.

     The label needed a <span> to do it: a bare text node inside a flex
     container becomes an anonymous flex item, and anonymous items cannot be
     targeted by CSS. */
  .footer-share-line {
    width: 100%;
    justify-content: space-between;
    flex-wrap: nowrap;
    gap: var(--s-2);
  }
  /* CORRECTED. Giving the label flex weight let it shrink and wrap — Sal:
     "don't crunch the words Share us on socials". It keeps its natural width
     now and never wraps. space-between still parks the label left and the
     mark right; the link just gets a right margin, which eats free space on
     its right and slides it a few spaces left. That was the whole ask. */
  .footer-share-label { flex: 0 0 auto; white-space: nowrap; }
  .footer-share-line .footer-sharelink { flex: 0 0 auto; margin-right: var(--s-4); }
  .footer-share-line .footer-fb { flex: 0 0 auto; }
  .footer-links { text-align: center; width: 100%; }
  /* 26 Sep 2026 — translated, the three pieces can be wider than a phone
     ("¡Compártenos en Redes!" + "Compartir enlace" pushed the Facebook mark
     off a 390px screen). English keeps the one balanced line Sal set above;
     every other language may wrap onto a second centred line instead of
     running off the edge. The words themselves still never break. */
  html:not([lang="en"]) .footer-share-line { flex-wrap: wrap; justify-content: center; row-gap: 0.35rem; }
  html:not([lang="en"]) .footer-share-line .footer-sharelink { margin-right: 0; }

  body.signup-open .front-door { padding: var(--s-4) var(--s-2) var(--s-5); }
  body.signup-open .auth-card {
    padding: var(--s-4) var(--s-3);
    width: 100%;
    max-width: none;
    margin: 0;
  }
  .door-card { padding: var(--s-4) var(--s-3); }

  .nbhd-title { font-size: var(--t-lg); }
  .nbhd-grid { gap: var(--s-2); }
  .nbhd-card { padding: var(--s-3); }
  .nbhd-card.is-main { flex-direction: column; align-items: flex-start; }

  /* The board on a phone: the status is the thing people scan for, so give it
     its own line under the name rather than crushing the invite to fit. */
  .nbhd-board { gap: var(--s-4); }
  .nbhd-board-section { padding: var(--s-3); }
  .nbhd-row { grid-template-columns: auto 1fr; row-gap: var(--s-1); padding: var(--s-3) var(--s-1); }
  .nbhd-row-status { grid-column: 2; justify-self: start; }
  .nbhd-row-name { font-size: var(--t-sm); }
  .nbhd-row-ico { width: 34px; height: 34px; font-size: var(--t-sm); }
}

/* Group-chat hours notice — 2026-09-05.
   Shown once per visit when a room holds fewer than ten people, or when
   presence cannot be counted. Coral wash rather than a modal: it sits in the
   room and can be read past, because a message about the room should not block
   the room. Dismissible, and it never says "closed". */
.hours-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2) var(--s-3);
  margin: 0 0 var(--s-3);
  padding: var(--s-3);
  background: var(--coral-wash);
  border: 1px solid rgba(255, 106, 82, 0.35);
  border-radius: var(--radius-lg);
}
.hours-note-body {
  flex: 1 1 260px;
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink);
}
/* nowrap removed 2026-09-19. "Wednesdays and Sundays, 7-9:30pm EST" is an
   unbreakable 34-character run; on a phone it cannot fit the note and the text
   ran outside the box — Sal saw it on the real device. Keeping the times on one
   line is worth nothing next to the copy staying inside its border. */
.hours-note-body strong { color: var(--coral-ink); }
.hours-note-close {
  flex: 0 0 auto;
  background: #fff;
  border: 1.5px solid var(--coral);
  color: var(--coral-ink);
  font-family: var(--sans);
  font-size: var(--t-sm);
  font-weight: 600;
  padding: 0.5rem 1.25rem;
  min-height: 44px;
  border-radius: 999px;
  cursor: pointer;
}
.hours-note-close:hover { background: var(--coral); color: #fff; }

/* ============ The Lobby boxes — 2026-09-19 ============
   Sal: Ask a Lüba and The Bin, "two boxes the same size, side by side", in the
   Lobby where people land — not buried under the chat where "people aren't
   gonna see it". Equal width by grid rather than by luck, so they stay matched
   however long the copy gets. */
.lobby-boxes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-3);
  margin: 0 0 var(--s-4);
}
.lobby-box {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-3);
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}
.lobby-box:hover { border-color: var(--coral); box-shadow: var(--shadow); }
.lobby-box:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--coral-wash); }
.lobby-box-ico {
  font-size: var(--t-md);
  line-height: 1.2;
  flex: 0 0 auto;
}
.lobby-box-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lobby-box-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--t-md);
  color: var(--ink);
}
.lobby-box-sub { font-size: var(--t-sm); line-height: 1.4; color: var(--ink-muted); }


/* Phone: one compact line each, so The Main Room stays above the fold — which
   is the thing the whole day was spent getting right. */
@media (max-width: 520px) {
  .lobby-boxes { grid-template-columns: 1fr; gap: var(--s-2); margin-bottom: var(--s-3); }
  .lobby-box { align-items: center; padding: var(--s-2) var(--s-3); }
  .lobby-box-title { font-size: var(--t-sm); }
  .lobby-box-sub {
    font-size: var(--t-xs);
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* ============ Ask a Lüba — the board, 2026-09-19 ============
   AOL's list, at phone size. One row per conversation, and the row tells you
   whether to open it: what it is about, who started it, how many replies, how
   recent, and whether anything is new since you last looked.

   Deliberately the same skeleton as the room list in the Lobby — Sal reads that
   one comfortably, and nobody should have to learn a second layout. */
.ask-sub { margin-bottom: var(--s-3); }

.ask-list { margin: 0 0 var(--s-3); display: flex; flex-direction: column; }

.ask-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line);
  padding: var(--s-3) var(--s-1);
  border-radius: var(--radius);
  transition: var(--transition);
}
.ask-list .ask-row:first-child { border-top: 0; }
.ask-row:hover { background: var(--surface-sunk); }
.ask-row:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--coral-wash); }

.ask-row-q {
  grid-column: 1;
  font-size: var(--t-sm);
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
}
.ask-row:hover .ask-row-q { color: var(--coral-ink); }

.ask-row-meta {
  grid-column: 1;
  font-size: var(--t-xs);
  color: var(--ink-muted);
  margin-top: 2px;
}

/* The badge AOL got right. Seeing "3 new" is what brought people back — it is
   the only thing on this screen allowed to be loud. */
.ask-new {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  white-space: nowrap;
  font-size: var(--t-xs);
  font-weight: 700;
  color: #fff;
  background: var(--coral);
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
}
.ask-row.is-new .ask-row-q { font-weight: 600; }

.ask-empty { margin: var(--s-3) 0; color: var(--ink-muted); font-size: var(--t-sm); }

.ask-fade {
  margin: var(--s-3) 0 var(--s-2);
  font-size: var(--t-xs);
  color: var(--ink-muted);
}

/* --- one conversation --- */
.ask-thread-q {
  margin: var(--s-2) 0 2px;
  font-family: var(--serif);
  font-size: var(--t-md);
  line-height: 1.3;
  color: var(--ink);
}
.ask-replies { display: flex; flex-direction: column; gap: var(--s-3); margin: var(--s-3) 0; }
.ask-reply { border-top: 1px solid var(--line); padding-top: var(--s-2); }
.ask-replies .ask-reply:first-child { border-top: 0; padding-top: 0; }
.ask-reply-text { margin: 2px 0 0; font-size: var(--t-sm); line-height: 1.45; color: var(--ink); }

.ask-compose { border-top: 1px solid var(--line); padding-top: var(--s-3); }
.ask-label { display: block; margin-bottom: var(--s-1); font-size: var(--t-sm); color: var(--ink-soft); }
#ask-status, #ask-thread-status { font-size: var(--t-xs); color: var(--ink-muted); }

/* A board on a phone is a screen, not a pop-up. Sal asked whether there is room
   for AOL's format on mobile — there is, once it stops trying to be a dialog
   floating inside the page. Same treatment the room already gets. */
@media (max-width: 520px) {
  .ask-modal { padding: 0; align-items: stretch; }
  .ask-modal .ask-card {
    max-width: none;
    width: 100%;
    height: 100dvh;
    border-radius: 0;
    overflow-y: auto;
    padding: var(--s-3);
  }
  .ask-row { padding: var(--s-3) 0; }
}

/* ===================================================================
   HEADER SPACING — 20 Sep 2026

   Sal: "check your line spacing for this entire section It's entirely
   too big". She is right. The header carries five things now — wordmark,
   two taglines, the reading row, and on a phone the greeting right
   underneath — and each was spaced as though it were the only one.
   Tightened as a set rather than one line at a time.
   =================================================================== */
header .tagline { margin: 0.3rem 0 0; line-height: 1.25; }
header .tagline-line { margin: 0.1rem 0 0; line-height: 1.25; }
.header-brand { margin-bottom: 0.1rem; }

/* NOTE, 20 Sep: .public-intro builds a full-bleed band from 100vw, and 100vw
   includes the scrollbar — so it is about 15px wider than the page. An
   overflow-x: clip was tried here and REVERTED: it hid the overflow instead of
   removing it, which is worse, because content you cannot scroll to is content
   that is gone. The right fix is to stop building the band from vw units, and
   that needs measuring on a real device first. Logged, not papered over. */

@media (max-width: 520px) {
  header { padding: 0.45rem 0.9rem 0.4rem; }
  header .tagline { font-size: var(--t-xs); margin-top: 0.2rem; }
  header .tagline-line { font-size: var(--t-xs); }
  .nbhd-greeting { margin: 0.35rem 0 0.2rem; }
}

/* ===================================================================
   WHO YOU ARE — top right of the page, 20 Sep 2026

   Sal: "SA Sal Sign out, should go at the Very top Right and the users
   initials and name should be larger but the sign out button should
   stay the same size."

   It used to live in the board's own header, so it moved about depending
   which screen you were on, and on a narrow window it wrapped under the
   greeting and landed on the LEFT. Up here it has one fixed place.
   =================================================================== */
/* 2026-09-23 — this line USED to read `header { position: sticky; }`.
   It was almost certainly written to guarantee a positioned ancestor for the
   .nbhd-account block directly below, which is absolutely positioned. But it
   sits outside every media query and LATER in the file than the phone rule at
   ~2177, which says `header { position: relative }`. Same specificity, later
   source order — so it won, and the header has been sticky on phones the whole
   time, against the stated intent of that rule. Measured on a 390x844 render
   of the live site: a 143px header on the front page and 159px on the reading
   pages, fixed to the top, eating 17-19% of the screen on every scroll.

   `relative` does the containing-block job just as well, and the desktop rule
   at line 145 still declares `position: sticky` where it is wanted. So this
   declaration is simply removed rather than replaced. */
body.authed header .nbhd-account {
  position: absolute;
  top: 0.55rem;
  right: 1.1rem;
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  z-index: 2;
}
body:not(.authed) header .nbhd-account { display: none; }

/* The person, bigger. The button, deliberately not — it is an exit, not a
   destination, and it should never compete with someone's own name. */
header .nbhd-account .user-status { font-size: var(--t-sm); font-weight: 600; color: var(--ink); }
header .nbhd-account .user-status .avatar-chip { width: 30px; height: 30px; font-size: var(--t-xs); }
header .nbhd-account .user-status img.avatar-chip { width: 30px; height: 30px; }
header .nbhd-account .linkish { font-size: var(--t-xs); }

/* The welcome band, tighter again — Sal, 20 Sep: "this spacing is waay too
   much still". Both lines now sit as one block rather than two paragraphs
   with a gap between them. */
.welcome-band { padding-block: 0.35rem; }
.welcome-manifesto { margin: 0; line-height: 1.3; }
.welcome-manifesto span { display: inline-block; margin-top: 0.1rem; }

@media (max-width: 520px) {
  body.authed header .nbhd-account { top: 0.4rem; right: 0.7rem; gap: 0.45rem; }
  header .nbhd-account .user-status { font-size: var(--t-xs); }
  header .nbhd-account .user-status .avatar-chip,
  header .nbhd-account .user-status img.avatar-chip { width: 26px; height: 26px; }
  .welcome-band { padding-block: 0.25rem; }
  .welcome-manifesto { font-size: var(--t-sm); }
}

/* The welcome band is one centred line now — Sal, 20 Sep. "Show up. Relax &
   Have a Good Time" removed; the band carries the tagline alone. */
.welcome-band { text-align: center; }
/* Sal only ever asked for the COLOUR. I changed the face as well — serif,
   italic, weight 600 — because that is the treatment the sentence carries
   above the hero, and she came straight back: "change the font back to what it
   was... I loved the font it was perfect all I did was tell you to make it
   coral."
   So: the original face, size and weight, in coral. Nothing else touched. */
.welcome-manifesto {
  max-width: 46ch;
  margin-inline: auto;
  color: var(--coral-ink);
}

/* The Lobby greeting, the notice and the quiet line read as ONE block rather
   than three full-width bands. Sal: "they're too large and they also go out
   right across the page". */
.nbhd-welcome { max-width: 52ch; }
.nbhd-greeting { font-size: var(--t-md); margin: 0.4rem 0 0.15rem; }
.lobby-count { font-size: var(--t-xs); margin: 0; line-height: 1.4; }
.hours-note { margin: 0 0 0.5rem; }

/* What is actually on the Message Board, live on the tile. A sign gets read
   once; real posts moving are what make somebody look twice. */
.lobby-box-feed { display: block; margin-top: 0.15rem; }
.ask-feed-row {
  display: block;
  font-size: var(--t-xs);
  line-height: 1.35;
  color: var(--ink-soft);
  margin-top: 0.15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ask-feed-who { font-weight: 600; color: var(--ink); }
.ask-feed-meta { color: var(--ink-muted); }

@media (max-width: 520px) {
  .nbhd-greeting { font-size: var(--t-md); }
  .lobby-count { font-size: var(--t-xs); }
  .ask-feed-row { font-size: var(--t-xs); }
}

/* ===================================================================
   THE LOBBY TILES — balanced, 20 Sep 2026

   Sal: "the message board is gonna be at least two bands tall What we
   could do is we could align that to the right the just so you know
   button and then underneath that we could put the Play a game... so
   we have everything we want but we've just balanced the page."

   Exactly right, and the reason it works is that the Message Board is
   the only tile with live content in it — real posts, updating. It
   earns the height. The notice and the game are both two lines and
   were each taking a full band to say very little.

       ┌──────────────────────┬───────────────┐
       │  Message Board       │  We're just   │
       │  (live posts, tall)  │  getting…     │
       │                      ├───────────────┤
       │                      │  Play a game  │
       └──────────────────────┴───────────────┘
   =================================================================== */
.lobby-boxes {
  display: grid;
  grid-template-columns: 1fr 1.45fr;
  /* Both left rows EXACTLY equal, so the two stacked tiles together measure
     the same as the one beside them. Sal, 20 Sep: "play a game actually sticks
     out of the box that is currently message board Nothing should be sticking
     out of the boxes the boxes should be perfectly even the same size
     perfectly aligned to the page."
     Without this the rows sized to their own content — the notice is three
     lines and the game is two — so the column came out taller than the board
     and the bottom tile hung past it. */
  grid-template-rows: 1fr 1fr;
  gap: 0.6rem;
  align-items: stretch;
}
/* No tile brings its own margin or height to the grid; the grid decides. */
.lobby-boxes > * {
  margin: 0;
  height: 100%;
  min-height: 0;
  box-sizing: border-box;
}
/* Notice and game stack on the LEFT; the Message Board takes the right and
   runs the full height of both. Sal, 20 Sep — she tried it the other way round
   first and preferred this. */
.lobby-boxes #hours-note { grid-column: 1; grid-row: 1; margin: 0; }
.lobby-boxes #game-open  { grid-column: 1; grid-row: 2; }
.lobby-boxes #ask-open {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-items: flex-start;
}

/* When the notice has been dismissed, the game takes the whole left column
   rather than leaving a hole in the grid. */
.lobby-boxes #hours-note[hidden] ~ #game-open { grid-row: 1 / span 2; }

/* The greeting was competing with the room names underneath it. */
/* The greeting sits at the same size as a tile title — Sal, 20 Sep: "where it
   says so glad you're here and then the person's name is about one or two font
   sizes too small it should be the same size as play a game, the main room,
   that's how big that sentence should be." Matching .lobby-box-title. */
.nbhd-greeting { font-size: var(--t-md); font-weight: 600; line-height: 1.25; }

@media (max-width: 720px) {
  /* One column. Reading order follows the visual order on the wide layout:
     notice, game, board. */
  .lobby-boxes { grid-template-columns: 1fr; }
  .lobby-boxes #hours-note,
  .lobby-boxes #game-open,
  .lobby-boxes #ask-open { grid-column: 1; grid-row: auto; }
  .lobby-boxes #hours-note { order: 1; }
  .lobby-boxes #game-open  { order: 2; }
  .lobby-boxes #ask-open   { order: 3; }
  .nbhd-greeting { font-size: var(--t-md); }
}

/* The quiet line runs as ONE line — Sal, 20 Sep: "this line is completely
   wrapped and left aligned it needs to be just one long straight line".
   Measured: the block was capped at 52ch (right edge 481) while the board
   beside it ran to 1215, so an 86-character sentence had 734px of unused
   width to its right and still wrapped onto two lines. The cap was mine, added
   an hour earlier for a different complaint. The head is a flex row, so the
   welcome side can take what it needs and the Bin tab keeps its own space. */
.nbhd-welcome { max-width: none; flex: 1 1 auto; min-width: 0; }
.lobby-count { white-space: normal; }

@media (min-width: 721px) {
  /* Wide enough to hold it, so hold it. */
  .lobby-count { white-space: nowrap; }
}


/* ===================================================================
   THE MESSAGE BOARD PANEL — 20 Sep 2026

   Sal: "it's all centred like everything is like the size of a mobile
   phone and it runs right down the centre of the page like a banner and
   you can't even see the bottom... the window needs to be wider."

   It was inheriting .onboard-card, which is sized for a short sign-up
   form — a narrow column is right for six fields and wrong for a board
   of conversations. It also grew with its content instead of scrolling,
   so a board with real posts on it ran off the bottom of the screen and
   took the only exit with it.
   =================================================================== */
.ask-modal .ask-card {
  width: min(96vw, 54rem);
  max-width: none;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
#ask-list-view,
#ask-thread-view {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
}
/* The list scrolls; the heading and the compose box stay put, so the way out
   and the way to post are always on screen. */
.ask-list,
#ask-replies {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
#ask-exit { align-self: flex-start; margin-bottom: var(--s-2); }

/* Posts were set at list-row size. These are people talking — Sal: "font's a
   little too tiny I think each message should be a little larger". */
.ask-row-q { font-size: var(--t-sm); line-height: 1.45; }
.ask-row-meta { font-size: var(--t-xs); }
.ask-feed-row { font-size: var(--t-xs); }

@media (max-width: 720px) {
  .ask-modal .ask-card { width: 100vw; max-height: 100dvh; border-radius: 0; }
  .ask-row-q { font-size: var(--t-sm); }
}

/* THE FRONT DOOR TWO-COLUMN GRID WAS REVERTED, 20 Sep 2026.

   Sal: "my perfect registration card is completely gone. Just a complete blank
   canvas."

   Constraining .hero into a grid column collapsed the sign-up card inside it.
   The card is the most important thing on this page — nothing about the layout
   is worth losing it — so the stacked layout is back exactly as it was.

   The side-by-side arrangement is still what she wants; it needs to be built
   from the card's own container rather than by squeezing .hero, and that is a
   daylight job, not a 1am one. */

/* ===================================================================
   THE FOLD — 20 Sep 2026

   Sal: "these buttons are too big and there's too much space… once you
   take all that extra padding and space out what's gonna happen is it's
   gonna move up your sign up / sign in button, and it's going to show
   the top of Why We Exist and encourage people to read more. Right now
   that stuff is barely showing at the bottom of the fold."

   MEASURED at an 804px viewport before touching anything:
     header 89 · greeting 59 · photo 293 · tagline+buttons 127 ·
     blurb 86  →  Why We Exist began at 654, leaving 150px of it visible.

   Every number below is a trim to one of those five, not a redesign.
   =================================================================== */
@media (min-width: 900px) {
  .public-intro-greeting { padding-top: 6px; padding-bottom: 8px; }
  .public-intro-photo { max-height: 232px; }
  .public-intro-photo img { object-fit: cover; }
  .public-intro-callout { padding-top: 8px; padding-bottom: 8px; }
  .public-tagline { margin-bottom: 0.35rem; }
  .public-intro-body { padding-bottom: 12px; }
  .public-intro-body .public-lede { margin: 0.2rem auto 0; }
  .landing-story { padding-top: 8px; }
}

/* The buttons were 47px tall with 16px type — a size you use for a primary
   action on a phone, not for two buttons sitting together on a laptop. */
@media (min-width: 900px) {
  .public-intro-callout .btn,
  .public-intro-callout .landing-cta-btn {
    padding: 0.5rem 1.25rem;
    font-size: var(--t-sm);
  }
}


/* ===================================================================
   WHY THIS EXISTS — the founder's story, and the bottom of the page
   20 Sep 2026

   Two jobs in one block.

   THE STORY fills the space Sal spotted at the foot of the login page,
   and it is the strongest thing on the page: a real reason, in a real
   voice, from a real person. It is set wider and quieter than the
   marketing above it, because it should read like someone talking
   rather than like a pitch.

   THE BOTTOM STACK was measured at 488px — share 178, privacy 170,
   footer 76, plus margins — for two short blocks and a line of links.
   Sal: "the bottom footer is so large it's ridiculous, it looks so
   unprofessional." She is right, and it was all padding.
   =================================================================== */
/* Now a block INSIDE the front door, above the closing call — not a band of
   its own. It sits between Why We Exist and the ask, so it needs air around it
   rather than a full-width surface change. */
.origin {
  border-top: 1px solid var(--line);
  padding-block: var(--s-4);
  margin-top: var(--s-3);
}
body.authed .origin { display: none; }   /* members have already read it */
.origin-inner {
  max-width: 62ch;
  margin-inline: auto;
  padding-inline: var(--s-3);
}
.origin-h {
  font-family: var(--serif);
  font-size: var(--t-lg);
  font-weight: 500;
  margin: 0 0 var(--s-3);
  color: var(--ink);
  text-align: left;
}
.origin-p {
  margin: 0 0 var(--s-3);
  color: var(--ink-soft);
  font-size: var(--t-sm);
  line-height: 1.65;
  text-align: left;
}
.origin-p strong { color: var(--coral-ink); }
.origin-sig {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  color: var(--ink-muted);
  font-size: var(--t-sm);
}

/* The bottom stack, trimmed. Measured 488px before; the padding was doing
   nothing but pushing the footer off the bottom of people's screens. */
#share { padding-block: var(--s-3); margin-bottom: var(--s-3); }
#privacy-notice { padding-block: var(--s-3); margin-bottom: var(--s-3); }
#share h2, #privacy-notice h2 { margin-bottom: 0.3rem; font-size: var(--t-md); }
#share p, #privacy-notice p { margin: 0.2rem 0; }
footer { margin-top: var(--s-2); padding-block: 0.5rem; }

@media (max-width: 720px) {
  .origin { padding-block: var(--s-4); }
  .origin-h { font-size: var(--t-md); }
  .origin-p { font-size: var(--t-sm); }
}

/* ===================================================================
   THE DOOR BUTTONS — 20 Sep 2026

   Sal, twice: "these buttons are too big and there's too much space",
   then "you totally forgot to fix this problem, the buttons are still
   too big."

   She was right both times. My first attempt targeted .btn — these are
   .public-cta-primary / .public-cta-secondary, so it never applied to
   them at all. The real size was min-height: 52px with 0.85rem/2.1rem
   of padding: a full-width phone button, shown as a pair on a laptop.
   =================================================================== */
.public-cta-primary,
.public-cta-secondary {
  min-height: 42px;
  padding: 0.55rem 1.6rem;
}
.public-actions { margin-top: var(--s-2); gap: 0.6rem; }
.public-intro-body .public-lede { line-height: 1.5; }

@media (max-width: 720px) {
  /* A phone still wants a comfortable target — 44px is the accessibility
     floor and these stay above it. */
  .public-cta-primary,
  .public-cta-secondary { min-height: 46px; padding: 0.6rem 1.4rem; }
}

/* ===================================================================
   TWO CARDS, SIDE BY SIDE — 21 Sep 2026

   Sal: "it was sitting perfectly centred but it was like a smaller box
   and there was nothing on either side and then below that it said Why
   We Exist. All I asked you to do was move that perfectly beautiful
   registration card to the left and pull Why We Exist up to the right."

   Exactly that, and nothing else. Scoped to body.signup-open — the only
   state where the card exists at all — so no other state of this page
   can be affected by it.

   Three failed attempts preceded this one, all for the same reason: I
   kept laying out .hero without understanding that the card inside it
   is display:none until a CTA is tapped. This rule changes only where
   two existing blocks sit. It touches no display property.
   =================================================================== */
@media (min-width: 980px) {
  body.signup-open .front-door {
    display: grid;
    grid-template-columns: minmax(0, 520px) minmax(0, 1fr);
    column-gap: var(--s-5);
    row-gap: var(--s-4);
    align-items: start;
    max-width: 1180px;
    margin-inline: auto;
  }
  /* Everything keeps its full width; only these two share the top row. */
  body.signup-open .front-door > * { grid-column: 1 / -1; }
  body.signup-open .front-door > .hero { grid-column: 1; grid-row: 1; }
  body.signup-open .front-door > .landing-story { grid-column: 2; grid-row: 1; }

  /* The card stops centring itself, so it sits hard left in its column. */
  body.signup-open .auth-card { margin: 0; max-width: none; }

  /* Why We Exist becomes the matching card on the right — same paper, same
     coral top edge, same corner radius, so they read as a pair. */
  body.signup-open .front-door > .landing-story {
    background: #fff;
    border: 1px solid var(--line);
    border-top: 4px solid var(--coral);
    border-radius: 18px;
    padding: 2rem 1.75rem 2.25rem;
    box-shadow: 0 24px 60px rgba(24,18,14,0.15);
    margin: 0;
    text-align: left;
  }
  body.signup-open .front-door > .landing-story .landing-h { text-align: left; margin-top: 0; }
  body.signup-open .front-door > .landing-story .door-body { text-align: left; }
}

/* The door buttons, fourth pass — Sal has raised these four times and each of
   my attempts moved one number and left another. MEASURED: 45px tall, 16px
   type, 8.8px/25.6px padding. Both the height AND the type had to come down;
   setting min-height alone left them reading just as large. */
.public-cta-primary,
.public-cta-secondary {
  min-height: 36px;
  padding: 0.35rem 1.2rem;
  font-size: var(--t-xs);
  letter-spacing: 0.01em;
}
@media (max-width: 720px) {
  .public-cta-primary,
  .public-cta-secondary { min-height: 44px; padding: 0.55rem 1.3rem; font-size: var(--t-sm); }
}

/* ===================================================================
   THE REGISTRATION CARD AND THE STORY BESIDE IT — 21 Sep 2026

   Sal: "instead of it saying Let's get you registered, which is what it
   should say, it has two buttons in there — totally redundant because
   we have those buttons above… and I want you to take Why We Exist out
   of the box and just make it free-flowing text, centre aligned."

   ⚠️ Every size below is a design-system token. The 5 Sep audit found
   13 font sizes with no rule connecting them and replaced them with six
   (--t-xs..--t-xxl). I spent tonight adding hard-coded rem values back
   into the same files, which is the exact fault that audit fixed.
   =================================================================== */
#auth-card .door-cta { display: none; }
.door-card-h {
  font-family: var(--serif);
  font-size: var(--t-lg);
  font-weight: 500;
  color: var(--ink);
  margin: 0 0 var(--s-3);
  text-align: center;
}

/* Why We Exist: no card, no border, no shadow. Free-flowing and centred. */
@media (min-width: 980px) {
  body.signup-open .front-door > .landing-story {
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: var(--s-3) 0 0;
    text-align: center;
    align-self: center;
  }
  body.signup-open .front-door > .landing-story .landing-h { text-align: center; }
  body.signup-open .front-door > .landing-story .door-body { text-align: center; }
}

/* ---- Hard-coded sizes I added tonight, put back on the scale ---- */
.nav-reading a            { font-size: var(--t-xs); }
.public-cta-primary,
.public-cta-secondary     { font-size: var(--t-xs); }
.nbhd-greeting            { font-size: var(--t-md); }
.lobby-count              { font-size: var(--t-xs); }
.ask-row-q                { font-size: var(--t-sm); }
.ask-row-meta             { font-size: var(--t-xs); }
.ask-feed-row             { font-size: var(--t-xs); }
.origin-p                 { font-size: var(--t-sm); }
.origin-sig               { font-size: var(--t-xs); }
.bin-tab                  { font-size: var(--t-xs); }
.welcome-manifesto        { font-size: var(--t-md); }

/* With "Let's get you registered" at the top of the card, the form's own
   all-caps headline underneath it is a second shout saying the same thing.
   Demoted to a quiet step label — it still tells you where you are. */
#auth-card #signup-form .door-headline {
  font-family: var(--sans);
  font-size: var(--t-xs);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--ink-muted);
  margin: 0 0 var(--s-3);
  text-align: center;
}.public-headline { font-size: var(--t-xl); letter-spacing: -0.02em; }

/* 2. THE PAGE SAID THE SAME THING FOUR TIMES.
   "relax, have fun and find your people" · Why We Exist · the three value
   cards · "Have Fun & Be Kind". Each is fine; together they read as padding.
   The three cards go: the reasons box INSIDE the form already makes the
   "real accounts, no anonymous sign-ups" point at the moment somebody is
   deciding, which is worth more than restating it further down a page they
   may never reach.
   Hidden rather than deleted — one line to bring back. */
/* Hidden on 21 Sep as part of the design pass, RESTORED the same night — Sal:
   "where did our three cards go... put them back where they were."
   My reasoning for cutting them (the reasons box in the form already makes the
   real-accounts point) was about repetition on the page. Hers is about what a
   stranger needs to read before trusting a sign-up form, and that outranks it. */
.landing-values { display: grid; }

/* 3. MOTION.
   Nothing on this page responded to a hand. These are small on purpose: a
   lift on hover, a settle on press, and one quiet entrance for the card.
   Anyone who has asked their system not to animate gets none of it. */
.public-cta-primary,
.public-cta-secondary,
.landing-cta-btn {
  transition: transform 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
.public-cta-primary:hover,
.landing-cta-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(255,106,82,0.32); }
.public-cta-primary:active,
.public-cta-secondary:active,
.landing-cta-btn:active { transform: translateY(0); }

@keyframes door-card-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
body.signup-open .auth-card { animation: door-card-in 260ms ease-out both; }

@media (prefers-reduced-motion: reduce) {
  .public-cta-primary:hover,
  .landing-cta-btn:hover { transform: none; }
  body.signup-open .auth-card { animation: none; }
}

/* ===================================================================
   THE FOOTER, ONE BALANCED LINE — 21 Sep 2026

   Sal: "the bottom footer is still not right."

   It was a split left/right row — share on the left, legal links on the
   right — with the copyright centred on its OWN line underneath. Three
   alignments in a block four lines tall reads as unbalanced, because it
   is.

   One row, three parts, each doing its own job: share left, copyright
   centre, links right. Stacks to centred lines on a phone, where three
   across cannot fit legibly.
   =================================================================== */
footer {
  background: var(--bg);           /* same paper as the page, not a white band */
  padding-block: var(--s-2);
}
footer .footer-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-3);
  max-width: 1180px;
  margin-inline: auto;
}
footer .footer-share-line { justify-self: start; margin: 0; display: inline-flex; align-items: center; gap: 0.4rem; }
footer .footer-links { justify-self: end; margin: 0; }
footer .footer-legal {
  grid-column: 2;
  grid-row: 1;
  justify-self: center;
  margin: 0;
  white-space: nowrap;
}

@media (max-width: 720px) {
  footer .footer-row { grid-template-columns: 1fr; text-align: center; gap: var(--s-1); }
  footer .footer-share-line,
  footer .footer-links,
  footer .footer-legal { justify-self: center; grid-column: 1; grid-row: auto; }
}

/* The house rule, inside the card. Sal, 21 Sep — it goes where somebody reads
   it BEFORE they join, not at the foot of a page they may never reach.
   Set quietly: it is a promise being asked for, not a warning being issued. */
/* The house rule: coral, centred, and the width of the page.
   Sal, 21 Sep — it was --t-xs ink-soft inside the left column, which made it
   look like fine print rather than the promise the place is built on. */
.door-card-note {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--t-md);
  font-weight: 600;
  line-height: 1.45;
  color: var(--coral-ink);
  text-align: center;
  max-width: 62ch;
  margin: var(--s-4) auto 0;
}

/* When people are here — the visitor's copy of the Lobby note (4 Oct). */
.landing-hours {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-soft);
  text-align: center;
  max-width: 56ch;
  margin: var(--s-2) auto 0;
  padding: var(--s-2) var(--s-3);
  background: var(--coral-wash);
  border-radius: var(--radius-lg);
}
.landing-hours strong { color: var(--coral-ink); }

/* ===================================================================
   WHY WE EXIST — same paper as the card, and room to breathe
   21 Sep 2026

   Sal: "the colour inside Find Your People is good, but if you're going
   to use that colour you should also be using it as the background for
   the free-floating Why We Exist text. And that text needs to be moved
   over a bit — it's smushed in too close to the box and not balanced to
   the other side of the border."

   MEASURED at 1247px before: card 58-578, story text 610-1190. A 32px
   gap, and the story had no inner padding at all — so its first letter
   sat 32px from the card while the card's own text sat 32px inside its
   border. One block breathed, the other did not.

   Same surface as the card, and padding of its own. No border and no
   shadow, so it still reads as text on paper rather than a second box.
   =================================================================== */
@media (min-width: 980px) {
  body.signup-open .front-door > .landing-story {
    background: var(--surface-card);
    border-radius: 18px;
    padding: var(--s-4) var(--s-5);
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* The two headings sit side by side, so they match. Sal, 21 Sep: "Find Your
   People and Why We Exist have two different types of fonts."
   MEASURED: both Fraunces 500, but 25px against 20px — and two headings level
   with each other at different sizes read as two different faces, which is
   exactly what she saw. Both on --t-lg now. */
@media (min-width: 980px) {
  body.signup-open .front-door > .landing-story .landing-h {
    font-size: var(--t-lg);
    font-weight: 500;
  }
}

/* The story lines up with the cards above it — 21 Sep 2026.
   It was sitting in a narrow centred column while the two cards ran the full
   width of the page, so it read as a different piece of furniture. Same
   container width and the same left edge as the registration card now; the
   paragraphs stay around 68 characters, which is where prose is comfortable. */
.origin-inner {
  max-width: 1180px;
  margin-inline: auto;
  /* No padding of its own — .front-door already provides the gutter, and
     adding a second one pushed the story 24px inside the card edge. */
  padding-inline: 0;
}
.origin-h,
.origin-p,
.origin-sig { max-width: 68ch; }

/* ===================================================================
   THE FRONT PAGE, MEASURED AND SQUARED UP — 21 Sep 2026

   Sal: "the colour of the box itself does not match Why We Exist… look
   at both of those cards and measure the full length of the page,
   because right now they're not even, they're not aligned perfectly
   across the entire page… and the How it All Started story is supposed
   to span the page, right now it's aligned left."

   MEASURED at 1247px before any of this:
     card   58-578  (520 wide)   bg rgb(255,252,248)
     why    610-1190 (580 wide)  bg rgb(255,252,248)
     three cards    174-1074 (900 wide)  — floating, matching nothing
     story paragraphs 58-644 — left column width, not the page

   The two backgrounds were already identical. What made them look
   different was that the card carried a 1px border and a heavy drop
   shadow and the other carried neither, so one read as raised white
   and the other as flat paper. And the columns were genuinely unequal:
   520 against 580.
   =================================================================== */
@media (min-width: 980px) {
  /* Two equal columns, so the cards are the same width as each other. */
  body.signup-open .front-door { grid-template-columns: 1fr 1fr; }

  /* The card matches Why We Exist: same paper, no border, no shadow.
     The coral top edge stays — Sal called that out as the part she likes. */
  body.signup-open .auth-card {
    border: 0;
    border-top: 4px solid var(--coral);
    box-shadow: none;
    padding: var(--s-4) var(--s-5) var(--s-5);
  }
  body.signup-open .front-door > .landing-story { padding: var(--s-4) var(--s-5) var(--s-5); }

  /* The three cards run the full page width, flush with the two above them. */
  body.signup-open .front-door > .landing-values {
    max-width: none;
    width: 100%;
    margin-inline: 0;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-4);
  }

  /* The story spans the page too, rather than sitting in one column's width. */
  .origin-h,
  .origin-p,
  .origin-sig { max-width: none; }
}.public-headline { display: block; }/* The Lobby greeting comes out. Sal: "later down on the page we say we're so
   glad you're here and then the person's name — remove that now."
   The header already welcomes them; saying it twice on one screen is saying
   it once badly. */
.nbhd-greeting { display: none; }

/* ===================================================================
   THE TOP OF THE SIGN-IN PAGE — 21 Sep 2026

   Sal: "the fonts, the height, the text size are still too large, not
   appropriate or balanced… 'Your people are closer than you think' has
   no space below it before the photo starts… if you make the font the
   correct size you can pull the photo down one and lift the Find Your
   People card up, so someone could actually put in their phone number."

   MEASURED at an 804px viewport before touching anything:
     header 0-91 · headline 97-136 (31px) · photo starts 144
     tagline+buttons 376-468 · blurb 471-543 · CARD STARTS 595

   Eight pixels between the headline and the photo — it was resting on
   the image. And with the card starting at 595 on an 804px screen, the
   phone field itself sat below the fold: you could not register without
   scrolling, which is the actual fault underneath the aesthetic one.
   =================================================================== */
@media (min-width: 900px) {
  /* 1. The headline was the only thing on the page at 31px, shouting
        next to a 16px blurb. */
  .public-headline { font-size: var(--t-lg); line-height: 1.2; }

  /* 2. Real air beneath it, so the photo drops clear instead of touching. */
  .public-intro-greeting { padding-bottom: 20px; }

  /* 3. The photo is a band, not a hero. 200px is plenty at this width. */
  .public-intro-photo { max-height: 200px; }

  /* 4. A few pixels each from the callout and the blurb. No content cut. */
  .public-intro-callout { padding-top: 6px; padding-bottom: 6px; }
  .public-tagline { margin-bottom: 0.25rem; }
  .public-intro-body { padding-bottom: 8px; }
}

/* The plain explanation of why a phone number, above the four reasons. */
.door-why-phone {
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--ink-soft);
  text-align: center;
  margin: 0 0 var(--s-3);
}

/* ===================================================================
   THE READING PAGES' WAY IN — 23 Sep 2026

   The nine pages written for people arriving cold from a search engine
   had no control on them at all. Measured on trans-community.html at
   390x844: three plain 16px text links, all to index.html, and the only
   one near the top said "← Back to the Rooms".

   "Back" is written for somebody who came FROM the site. The person
   these pages exist for has never seen the Rooms, so "back" describes a
   journey they did not take — it reads as a breadcrumb, not a door. The
   one line that did invite them, "Pull up a seat →", sat 3,418px down,
   four screens past the top.

   So: Sal's own locked CTA, the same words and the same pill as the
   front page, pointing at #front-door so it lands on the registration
   card rather than the top of the home page. `.motto` had no rule of its
   own anywhere in the stylesheet, which is why it rendered as default
   body text — it has one now.

   lgbtq-teens.html is DELIBERATELY EXCLUDED and still carries the old
   line. The platform is 18+; putting a join button in front of a
   teenager is the one place this change would be wrong. That page exists
   to hand somebody the crisis resources and let them go.
   =================================================================== */
.motto {
  margin: 0.7rem 0 0;
}
.motto-cta {
  /* Slightly tighter than the front-page pill: this one sits under a
     headline rather than leading a hero, and the header on these pages
     is already carrying the page's h1. 48px still clears the 40px floor
     for something a hand has to hit. */
  padding: 0.65rem 1.7rem;
  min-height: 48px;
}

/* ---------- LANGUAGE SWITCHER — 23 Sep 2026 ----------
   A plain <select>, sitting under the reading nav. Deliberately quiet:
   somebody who reads English never needs to notice it, and somebody who
   does need it is already looking for their own language in the list. */
/* Pinned to the LEFT of the wordmark's row, mirroring the sign-in button on
   the right. 2026-09-23, and it is a measurement not a preference: sitting
   under the nav it added 51px to a 390x844 header — 102px back up to 153px,
   giving back half of the morning's work on header height. The top row is
   already 48px tall because of the sign-in button, and there are 118px of
   empty space to the left of the centred wordmark. Putting it there costs
   nothing at all. */
.lang-pick {
  position: absolute;
  top: 0.6rem;
  left: 1.25rem;
  display: flex;
  align-items: center;
  z-index: 101;
}
.lang-pick select {
  font-family: var(--sans);
  font-size: var(--t-xs);
  color: var(--ink-muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 1.6rem 0.3rem 0.7rem;
  /* 44px is the floor for something a hand has to hit — these members
     are the last people to give a fiddly tap target to. */
  min-height: 44px;
  cursor: pointer;
}
.lang-pick select:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }

/* Label for screen readers only — the select's own text says the rest. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

/* Phone: the same place, but sized to the space that is actually there.
   The wordmark is centred, so the language control has the gap to its left
   and nothing more — measured at 118px on a 390 screen and 103px on a 360.
   max-width keeps the longest name ("Français") from ever reaching the "L"
   of Lüba, whatever the font does. */
@media (max-width: 860px) {
  .lang-pick {
    top: max(var(--s-2), calc(0.55rem + env(safe-area-inset-top)));
    left: var(--s-2);
  }
  .lang-pick select {
    max-width: 96px;
    padding: 0.3rem 1.3rem 0.3rem 0.5rem;
    min-height: 40px;
  }
}

/* ---------- VOLUNTEERING — 23 Sep 2026 ----------
   The four terms are set as a real list, with room around them, because
   they are the part a person needs to actually read — not fine print
   under a button. See the comment on #volunteer-modal in index.html for
   why each line is there. */
.volunteer-back {
  display: inline-block;
  margin-bottom: var(--s-2);
}
.volunteer-terms {
  margin: var(--s-2) 0 var(--s-3);
  padding-left: 1.1rem;
}
.volunteer-terms li {
  margin-bottom: var(--s-2);
  line-height: 1.5;
}
.volunteer-status {
  margin: var(--s-2) 0;
  color: var(--coral-ink);
  font-weight: 600;
}


/* ===================================================================
   PHONE PASS — 4 Oct 2026
   Sal, after seeing the site on a friend's phone: "it is not nice… go
   through page by page, line by line, and make sure it aligns properly".
   Measured at 390px wide (iPhone 12–15) in headless Chrome.
   =================================================================== */
.nowrap { white-space: nowrap; }

@media (max-width: 860px) {
  /* The reading pages (body.reading — FAQ, Safety, Terms and the twelve
     pages for each community) had NO side margin on a phone: the rule
     above that lets the landing photo run edge to edge (main { padding: 0 })
     applied to every page, so their text touched the glass. */
  body.reading main { padding: 0 var(--s-4); }
  /* Their language picker floated over the headline. On a phone it takes
     its own line at the top instead. */
  body.reading .lang-pick { position: static; justify-content: flex-start; margin: 0 0 var(--s-1); }
  /* (4 Oct) The menu briefly wrapped onto four lines here; Sal asked for the
     one sideways-scrolling line back (5 Oct), so the rule above stands. */
}

@media (max-width: 520px) {
  body.reading main { padding: 0 var(--s-3); }
  /* Long passages read better ranged left on a narrow screen; the story
     below them already was, so the two sections now match. */
  .landing-story .door-body { text-align: left; }
  /* The hint under the phone box was touching the box. */
  .field-hint { margin: 0.4rem 0 0.85rem; }
  /* Tap targets — 44px is the floor for a thumb. Measured before: footer
     links 17px tall, "Share link" 21px, the Facebook icon 22px, "Sign in"
     under the form 16px. */
  .footer-links a, footer a { display: inline-block; padding: 0.7rem 0.35rem; }
  .footer-sharelink { padding: 0.7rem 0.4rem; }
  .footer-fb { padding: 11px; box-sizing: content-box; }
  #show-signin { display: inline-block; padding: 0.7rem 0.3rem; }
  /* "Sign out" showed twice in a room on a phone — the header has it already. */
  .room-signout { display: none; }
}



/* ===================================================================
   LAYOUT A — Sal, 4 Oct 2026: the photo on the left, the three cards
   stacked on the right to balance it, the founder's story open below.
   (Before: the cards in a row, then the photo alone at 860x430, then the
   story folded — "the whole thing is taking up the entire bottom half".)
   =================================================================== */
.landing-pair {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--s-3);
  align-items: stretch;
  max-width: 1000px;
  margin: 0 auto var(--s-4);
}
.landing-pair .landing-values {
  grid-template-columns: 1fr;
  max-width: none;
  margin: 0;
}
.landing-pair .value-card { display: flex; flex-direction: column; justify-content: center; }
.pair-photo {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 320px;
  object-fit: cover;
  object-position: 62% 40%;         /* the three women at the table */
  border-radius: 20px;
}
@media (max-width: 720px) {
  .landing-pair { grid-template-columns: 1fr; }
  .pair-photo { height: auto; min-height: 0; aspect-ratio: 16 / 10; border-radius: 14px; }
}
/* Tighter cards beside the photo, so the photo is wider than it is tall
   and keeps the woman at the grill in the picture. */
.landing-pair .value-card { padding: var(--s-2) var(--s-3); }
.landing-pair .value-ico { font-size: var(--t-md); margin-bottom: 0.15rem; }
.landing-pair .value-card h4 { margin-bottom: 0.2rem; }
@media (min-width: 721px) { .pair-photo { max-height: 440px; } .landing-pair { align-items: center; } }
/* The cards line up with the photo edges on a phone (they kept a 16px inset). */
.landing-pair .landing-values { padding-inline: 0; }
/* The story reads in a comfortable column, not the full page width. */
.origin-inner { max-width: 720px; }

/* Sal's own crop of the photo (4 Oct, "I think it looks great") is shown
   WHOLE — its own shape, nothing cut by the layout. The cards go compact
   beside it, icon to the left of the title, so the two sides balance. */
.landing-pair { grid-template-columns: 1.55fr 1fr; }
.pair-photo { height: auto; min-height: 0; max-height: none; aspect-ratio: 1116 / 689; object-position: center; }
.landing-pair .landing-values { gap: var(--s-2); }
.landing-pair .value-card {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.75rem;
  align-items: start;
  text-align: left;
  padding: 0.85rem 1rem;
}
.landing-pair .value-ico { grid-row: span 2; font-size: 1.5rem; margin: 0.1rem 0 0; }
.landing-pair .value-card h4 { margin: 0 0 0.15rem; }
.landing-pair .value-card p { font-size: 0.92rem; line-height: 1.45; }
@media (max-width: 720px) { .landing-pair { grid-template-columns: 1fr; } .pair-photo { aspect-ratio: 1116 / 689; border-radius: 14px; } }

/* The closing lines match the story (Sal, 4 Oct: "left aligned, the fonts
   and sizes have to meet"): same font, same size, left-aligned. */
.origin-sig { font-family: inherit; font-size: inherit; font-style: normal; text-align: left; color: var(--ink-soft); }

/* ===================================================================
   SUPPORT PAGE — 5 Oct 2026 (support.html). Signal's shape: monthly
   Supporter amounts, a one-off gift, and the Founding Lüba.
   =================================================================== */
.support-page section { max-width: 760px; margin: 0 auto; }
.support-lead { font-family: var(--serif); font-size: var(--t-md); color: var(--ink); margin-top: var(--s-4); }
.support-ways { display: grid; gap: var(--s-3); margin: var(--s-4) 0; }
.support-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-3) var(--s-4);
  box-shadow: var(--shadow-sm);
}
.support-card h2 { margin: 0 0 var(--s-1); font-size: var(--t-md); }
.support-card p { margin: 0 0 var(--s-2); }
.support-card ul { margin: 0 0 var(--s-3); padding-left: 1.2rem; }
.support-founding { border: 2px solid var(--coral); background: #FFF6F3; }
.support-get { font-weight: 600; color: var(--ink); }
.support-amounts { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.support-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0.55rem 1.2rem;
  border-radius: 999px; border: 1.5px solid var(--coral);
  background: #fff; color: var(--coral-ink);
  font-weight: 700; text-decoration: none;
}
.support-btn:hover { background: var(--coral-wash); }
.support-btn.primary { background: var(--coral); color: #fff; }
.support-btn.primary:hover { background: var(--coral-ink); }
.support-btn[aria-disabled="true"] { opacity: 0.55; cursor: default; }
.support-partners { margin-top: var(--s-3); font-size: var(--t-sm); font-style: italic; color: var(--ink-soft); }
.support-soon { text-align: center; font-weight: 600; color: var(--coral-ink); background: var(--coral-wash); border-radius: var(--radius); padding: var(--s-2); }
.support-fine { font-size: var(--t-sm); color: var(--ink-muted); border-top: 1px solid var(--line); padding-top: var(--s-2); margin-top: var(--s-4); }
@media (max-width: 520px) { .support-card { padding: var(--s-3); } .support-btn { flex: 1 1 auto; } }

/* Partners and investors introduce themselves (5 Oct 2026). */
.partner-form { display: grid; gap: var(--s-1); margin-top: var(--s-2); padding-top: var(--s-2); border-top: 1px solid #FFD3C8; }
.partner-form-h { margin: 0; font-weight: 700; color: var(--ink); }
.partner-form label { display: grid; gap: 0.2rem; font-size: var(--t-sm); color: var(--ink-soft); }
.partner-form input, .partner-form textarea {
  font: inherit; padding: 0.6rem 0.75rem; min-height: 44px;
  border: 1px solid var(--line-strong); border-radius: var(--radius); background: #fff; color: var(--ink);
}
.partner-form button { justify-self: start; }
.partner-hp { position: absolute; left: -10000px; width: 1px; height: 1px; opacity: 0; }
.partner-privacy { margin: 0; font-size: 0.85rem; color: var(--ink-muted); }
.partner-status { margin: 0; font-weight: 600; color: var(--coral-ink); }
.partner-status.is-ok { color: #2e7d4f; }

/* Sal's letter at the top of /support (5 Oct 2026). */
.support-letter { margin: var(--s-4) 0; padding: var(--s-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.support-letter h2 { font-family: var(--serif); font-size: var(--t-lg); line-height: 1.2; margin: 0 0 var(--s-3); color: var(--ink); }
.support-letter p { margin: 0 0 var(--s-2); line-height: 1.65; }
.support-letter-ask { font-weight: 700; color: var(--coral-ink); }
.support-letter-sig { font-family: var(--serif); font-style: italic; color: var(--ink-soft); margin-bottom: 0; }
@media (max-width: 520px) { .support-letter { padding: var(--s-3); } }

/* The coffee-shop photo inside "How it All Started" (5 Oct 2026). */
.story-photo { display: block; width: 100%; height: auto; aspect-ratio: 1080 / 528; border-radius: 16px; margin: var(--s-2) 0 var(--s-3); }

/* ===================================================================
   FINAL SWEEP BEFORE LAUNCH — 5 Oct 2026
   Sal: "check for all the same fonts, the right sizes, whether or not
   there should be italics… there's still a lot of spacing between 'The
   digital space to relax' and the top of Find Your People". Measured on
   every page at 1280px and 390px; these are the outliers it found.
   =================================================================== */

/* No italics for our own lines. Kept only where italic means something:
   a study's title, or one stressed word in the FAQ. */
header .tagline-line strong,
.door-card-note,
.support-partners,
.support-letter-sig { font-style: normal; }

/* Buttons that fell back to the browser's Arial 13px. */
.support-btn, .partner-form button, .partner-form input, .partner-form textarea { font-family: var(--sans); font-size: 1rem; }

/* Too small for our readers: the two hero buttons (13px), the "Let's
   start with your phone number" line, and the sign-up card's small print
   (all 13px) — up to 16px and 15px. */
.public-cta-primary, .public-cta-secondary { font-size: 1rem; }
h2.door-headline { font-size: 1rem; }
.door-why-phone, .field-hint, .why-box li, .auth-card label { font-size: 0.9375rem; }

/* One size for the three cards beside the photo (they were 14.7px). */
.landing-pair .value-card p { font-size: 1rem; }

/* One size for section headings, everywhere on the landing page. On a
   phone "Find Your People" was 25px while "Why We Exist" and "How it All
   Started" were 20px. */
.door-card-h, .landing-h, .origin-h { font-size: var(--t-lg); }
@media (max-width: 520px) { .door-card-h, .landing-h, .origin-h { font-size: 1.375rem; } }

/* One size for long reading text: "Why We Exist" was 20px, the founder's
   story 16px, side by side on the same page. 18px on a laptop, 16px on a
   phone, for both. */
.landing-story .door-body, .origin-p, .origin-sig, .public-lede { font-size: 1.125rem; }
@media (max-width: 520px) { .landing-story .door-body, .origin-p, .origin-sig, .public-lede { font-size: 1rem; } }

/* The gap Sal saw: "The digital space to relax…" to the top of the Find
   Your People card was 80px on a laptop (68px on a phone) — three spacings
   stacked: the intro's bottom padding, main's bottom margin and the front
   door's top padding. Now about 24px. */
.public-intro-body { padding-bottom: 0.5rem; }
body:not(.reading) main { margin-bottom: 1rem; }
#front-door, .front-door { padding-top: 0; }

/* Two smaller gaps: photo-and-cards to the story (64px), and the Join
   button to the footer (92px). */
.landing-pair { margin-bottom: var(--s-3); }
.origin { margin-top: var(--s-2); }
.landing-cta { margin-bottom: var(--s-3); }

/* Second pass, same sweep. */
/* The tagline under the photo — its italic lives on .public-tagline itself. */
.public-tagline, .public-tagline strong { font-style: normal; }
/* "Let's start with your phone number" — a quiet step label at 13px; 16px now. */
#auth-card #signup-form .door-headline { font-size: 1rem; }
/* The page menu and "Already have an account? Sign in" were 13px. */
header nav.nav-reading a { font-size: 0.9375rem; }
.door-switch, .door-switch a, #show-signin { font-size: 0.9375rem; }
/* Join button to the footer: the front door's 48px bottom padding + 16 + 16. */
.front-door, #front-door { padding-bottom: var(--s-3); }
.landing-cta { margin-bottom: 0; }
/* A little air above the Find Your People card (it sat flush on the edge),
   and the hint clear of the phone box at every width, not just phones. */
.front-door, #front-door { padding-top: 0.75rem; }
.field-hint { margin: 0.4rem 0 0.85rem; }

/* 5 Oct: the founder's story now lives in the "Why We Exist" box, read left-aligned
   like any story; the lower section holds what used to be there, under "How We
   Built It Differently". */
.landing-story .origin-p, .landing-story .origin-sig { text-align: left; }
.landing-story .story-photo { margin: var(--s-2) 0 var(--s-3); }

/* Sal, 5 Oct: the space under the sign-in card holds the women's photo and
   How We Built Lüba Differently; the three cards run across beneath. */
.landing-left .pair-photo { display: block; width: 100%; height: auto; aspect-ratio: 1116 / 689; border-radius: 16px; }
.landing-left .origin { margin: var(--s-4) 0 0; padding: 0; background: none; border: 0; box-shadow: none; }
.landing-left .origin-h { text-align: left; margin: 0 0 var(--s-3); }
.landing-left .origin-p { text-align: left; max-width: none; }
.front-door > .landing-values { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); padding: 0; margin: var(--s-4) 0 0; }
.front-door > .landing-values .value-card p { font-size: 1rem; }
@media (min-width: 980px) {
  body.signup-open .front-door > .landing-story { grid-row: 1 / span 2; }
  body.signup-open .front-door > .landing-left { grid-column: 1; grid-row: 2; }
}
@media (max-width: 979px) {
  .landing-left { margin-top: var(--s-4); }
  .front-door > .landing-values { grid-template-columns: 1fr; }
}
/* Sal, 5 Oct: "a lot of space at the top of the card where Why We Exist is".
   The box centred its words vertically; now they start at the top and the
   box is only as tall as what's in it. */
body.signup-open .front-door > .landing-story { justify-content: flex-start; align-self: start; }
/* Sal, 5 Oct: the house note now sits at the top of the Why We Exist box. */
.landing-story > .door-card-note { margin: 0 0 var(--s-3); max-width: none; font-size: 1.125rem; line-height: 1.4; }
/* Sal, 5 Oct: the Why We Exist box runs the full height beside the sign-in
   column again — its words start at the top, under the house note. */
body.signup-open .front-door > .landing-story { align-self: stretch; }
/* Sal, 5 Oct: the "We're just getting started!" announcement, much bigger —
   across most of the page. */
.front-door > .landing-hours {
  max-width: none; width: 100%; box-sizing: border-box;
  margin: var(--s-5) auto 0; padding: 1.75rem 2rem;
  font-size: 1.375rem; line-height: 1.5; border-radius: 18px;
}
.front-door > .landing-hours strong:first-child { display: block; font-family: var(--serif); font-size: 1.75rem; margin-bottom: 0.35rem; }
@media (max-width: 520px) {
  .front-door > .landing-hours { padding: 1.25rem 1rem; font-size: 1.125rem; }
  .front-door > .landing-hours strong:first-child { font-size: 1.375rem; }
}
.front-door > .landing-hours + .landing-cta, .landing-cta { margin-top: var(--s-4); }

/* ===== TOP SECTION — SPACING + SIZES, 5 Oct 2026 (Sal: "it feels too
   crunched"). Self-contained so it can be reverted in one go: delete from
   here to "END TOP SECTION". ===== */
.public-intro-greeting { padding-top: 24px; }
.public-intro-body { padding-bottom: 20px; }
.public-intro-photo { margin-top: 4px; }
.public-tagline { margin-top: 14px; }
.public-actions { margin-top: 24px; }
.public-intro-body { padding-top: 11px; }
body.signup-open .front-door { padding-top: calc(0.75rem + 12px); }
@media (max-width: 520px) {
  .public-intro-greeting { padding-top: 20px; }
  .public-tagline { margin-top: 4px; }
  .public-intro-body { padding-bottom: 16px; }
  .public-intro-body { padding-top: 0; }
  body.signup-open .front-door { padding-top: calc(0.75rem + 8px); }
}
/* The house note black, "Why We Exist" coral (Sal, 5 Oct). */
.landing-story > .door-card-note { color: var(--ink); font-size: 1.0625rem; text-wrap: balance; }
.landing-story .landing-h { color: var(--coral-ink); }
/* ===== END TOP SECTION ===== */
/* Lobby, 5 Oct 2026 — Sal: "this spacing is way too large. People need to
   see what's coming." Matters of the Heart to "Opening as we grow" was 130px
   (row padding + section padding + 32px between sections + padding again). */
.nbhd-board { gap: var(--s-2); }
.nbhd-board-section { padding: var(--s-3) var(--s-4); }
.nbhd-row { padding-block: var(--s-2); }
@media (max-width: 520px) {
  .nbhd-board { gap: var(--s-2); }
  .nbhd-board-section { padding: var(--s-2) var(--s-3); }
}
.nbhd-board > .nbhd-board-section { margin: 0; }
/* "Your data is yours" — the two small lines were off-centre (5 Oct). */
/* Sal, 5 Oct: centred, and on one line on a laptop. */
section.privacy-promise .privacy-text { margin-inline: auto; text-align: center; max-width: none; }

/* Message Board, full size (Sal, 5 Oct: "a full active message board, like
   back in the day with AOL"). Nearly the whole screen on a laptop, all of it
   on a phone; the conversations fill it and scroll. */
.ask-modal .ask-card { width: min(94vw, 1100px); height: 90vh; max-height: 90vh; }
.ask-start { align-self: flex-start; margin: 0 0 var(--s-3); }
#ask-compose { border-top: 0; padding-top: 0; margin-bottom: var(--s-3); }
#ask-compose .bin-input { min-height: 5.5rem; }
.ask-list { border-top: 1px solid var(--line); }
.ask-row-q { font-size: 1.0625rem; }
@media (max-width: 720px) {
  .ask-modal .ask-card { width: 100vw; height: 100dvh; max-height: 100dvh; }
}
#ask-compose[hidden], #ask-start[hidden] { display: none; }
