/*
 * Naabrent component layer (design-system.md).
 * Small, hand-written CSS for the bespoke components a classless Pico
 * baseline does not provide: top bar, nav, listing cards, badges/pills,
 * verification badge, notification bell, chat, availability states.
 * ADR-0004: no build step, plain CSS + custom properties only.
 */

/* Respect reduced-motion preferences everywhere (accessibility.md). */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Mobile-first global guards (mobile-first-ui.md §1): no body-level horizontal
   scroll at any width, and no element is ever wider than its container. */
html, body { overflow-x: hidden; }
img, svg, video, table { max-width: 100%; }

/* Form controls: never smaller than 16px so iOS Safari doesn't auto-zoom on
   focus (mobile-first-ui.md §5). */
input, select, textarea { font-size: max(16px, var(--fs-base)); }

/* Checkboxes: Pico's generic `input,select,textarea{border-radius:var(--pico-
   border-radius)}` rule also applies to <input type="checkbox">. Our control
   radius (10px) is half the checkbox's ~20px box, so every checkbox rendered
   as a solid circle instead of a check mark (item 6). Radios keep Pico's own
   `border-radius:50%` override and are unaffected. */
input[type="checkbox"] {
  border-radius: 4px;
}

/* Sticky footer app shell: the footer sits at the bottom even on short pages
   (no dead grey gap), while tall pages scroll normally (visual-refresh §5). */
body {
  background: var(--surface-page);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main.container {
  flex: 1 0 auto;
}

/* Skip link (accessibility.md) -------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  background: var(--color-primary);
  color: var(--text-on-primary);
  padding: var(--space-2) var(--space-4);
  border-radius: 0 0 var(--radius-control) 0;
}

.skip-link:focus {
  left: 0;
}

/* Focus ring everywhere, never removed without replacement ---------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Top navigation ------------------------------------------------------------ */
/* Light header (2026-07-11 refresh): white surface carrying the full-colour
   logo; brand presence comes from the logo mark instead of a dark band. */
.site-header {
  background: var(--surface-card);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

/* Pico gives landmark <header> its own block padding; on mobile that stacks on
   top of the nav-bar's padding and bloats the header past ~120px. Drop it on
   mobile (the nav-bar handles spacing) so the header stays ~90px. Desktop keeps
   Pico's padding for a roomier band. */
@media (max-width: 767px) {
  .site-header { padding-block: 0; }
  /* Open menu = full-screen overlay (mobile-first-ui.md §10): cover the page
     with the opaque header surface instead of pushing it down, so the page
     beneath is hidden (not a confusing half-visible layout). Sits above the
     chat FAB (z-index 900). Panel scrolls if the menu is taller than the
     viewport; safe-area padding keeps the last row clear of the home bar. */
  .site-header.is-open {
    position: fixed;
    inset: 0;
    z-index: 1000;
    overflow-y: auto;
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  }
}
/* Lock the page behind the open overlay (toggled by the nav button; only ever
   set on mobile, where the toggle exists). */
body.nav-open { overflow: hidden; }

/* Same idea for the chat popup: on phones it's a near-full-screen sheet, so
   the page behind must not scroll while it's open. From 576px it's a small
   floating card and the page stays scrollable. */
@media (max-width: 575px) {
  body.chat-open { overflow: hidden; }
}

.nav-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  /* Horizontal padding here (not 0) matters: `.container`'s own inline
     padding only applies from 576px up (Pico zeroes it below that), so
     without this the brand wordmark sits flush against the viewport edge
     and is clipped on phones (mobile-first-ui.md §3). */
  padding: var(--space-3) var(--space-4);
  flex-wrap: wrap;
  /* Our gap controls link spacing; Pico's extra nav li padding (derived from
     these vars) would otherwise widen the links row past the 700px container. */
  --pico-nav-element-spacing-vertical: 0;
  --pico-nav-element-spacing-horizontal: 0;
}

.nav-bar__brand {
  display: inline-flex;
  align-items: center;
  margin-right: var(--space-2);
  /* The logo must never be flex-squeezed away by a crowded nav row — the
     other items (links wrap internally) absorb the pressure instead. */
  flex: 0 0 auto;
}

/* The logo image. Height-driven so the PNG's aspect ratio is preserved; 2x
   assets keep it crisp on retina. On phones the <picture> serves the square
   mark only (logo-mark.png), so the width stays ~44px. */
.nav-bar__brand img {
  display: block;
  height: 40px;                        /* mobile: the square mark */
  width: auto;
}

@media (min-width: 768px) {
  .nav-bar__brand img { height: 40px; }
}

.nav-bar__links {
  display: flex;
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}

.nav-bar__links a {
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: 500;
}

.nav-bar__links a:hover,
.nav-bar__links a[aria-current="page"] {
  color: var(--color-primary-active);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.nav-bar__spacer {
  flex: 1 1 auto;
}

.nav-bar__end {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.neighbourhood-switcher select {
  margin: 0;
  height: 40px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  color: var(--text-primary);
  border: 1px solid var(--border);
  /* Long neighbourhood names must not blow the header row apart. */
  max-width: 200px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

/* Single-neighbourhood label (no switcher needed) in the header. */
.neighbourhood-current {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  color: var(--text-primary);
  font-weight: 500;
}

/* Header chrome on the light surface: one chip family. The account menu and
   the mobile menu button share the neighbourhood switcher's muted pill, so the
   header has exactly two control treatments: chips and ghost icon-buttons
   (bell, flag). */
.site-header .nav-toggle,
.site-header .dropdown > summary[role="button"] {
  background: var(--surface-muted);
  color: var(--color-primary-ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}

.site-header .nav-toggle:hover,
.site-header .dropdown > summary[role="button"]:hover {
  background: var(--color-primary-50);
  color: var(--color-primary-ink);
  border-color: var(--color-primary-100);
}

.nav-bar__end > a:not([role="button"]) {   /* "Log in" text link */
  color: var(--color-primary-ink);
}

.nav-bar__end > a[role="button"] {          /* "Sign up" — primary CTA */
  background: var(--color-primary);
  color: var(--text-on-primary);
  border-color: var(--color-primary);
}

/* In the open mobile menu, a solid pill next to plain text rows reads as one
   giant, out-of-place button (item 2/3). Give "Sign up" a clear but
   consistent tinted treatment: same row shape as its siblings, just bolder.
   Desktop keeps the compact solid CTA above. */
@media (max-width: 767px) {
  .nav-bar__end > a[role="button"] {
    background: var(--color-primary-50);
    color: var(--color-primary-ink);
    border: 1px solid var(--color-primary-100);
    font-weight: 600;
  }
  .nav-bar__end > a[role="button"]:hover {
    background: var(--color-primary-100);
  }
}

/* Mobile-first navigation (mobile-first-ui.md §3) ---------------------------- */
/* Base (mobile ≤767px): stacked, collapsible nav. Top row = brand | bell |
   hamburger; everything else lives in the collapsible menu as full-width,
   ≥44px rows. */
/* Tighten the whole top-row gap on mobile (not just row-gap): at 360px the
   brand + bell + flag + menu button otherwise overflow the row and wrap to a
   second line. 8px keeps all four on one row down to 360px. */
.nav-bar { gap: var(--space-2); }

.nav-toggle { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 48px; }

/* Mobile top-row order: brand | (bell) | flag | toggle. The brand takes the
   free space so the bell/flag/toggle cluster sits at the right; the three
   controls follow DOM order (all default `order: 0`) so no wrapping and no
   extra CSS ordering is needed to keep this a single non-wrapping row. */
.nav-bar__spacer { display: none; }              /* no spacer while stacked */
.nav-bar__brand { margin-right: auto; }
.notification-bell { order: 0; }
.nav-toggle { order: 0; }

.nav-bar__links,
.nav-bar__end {
  flex-basis: 100%;
  display: none;                                  /* hidden until toggled open */
  flex-direction: column;
  align-items: stretch;    /* reset the desktop/Pico `center` so rows fill width */
  gap: var(--space-1);
  padding-top: var(--space-2);
}

/* Full-width list items so the links/rows stretch and left-align (Pico's
   nav ul centres them otherwise). */
.nav-bar__links li { display: block; width: 100%; padding: 0; }

.site-header.is-open .nav-bar__links,
.site-header.is-open .nav-bar__end { display: flex; }

/* Full-width, ≥44px tap rows in the open menu */
.nav-bar__links a,
.nav-bar__end > a,
.nav-bar__end .dropdown > summary,
.neighbourhood-current,
.neighbourhood-switcher select {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
}

.nav-bar__links a:hover,
.nav-bar__end > a:hover { background: var(--surface-muted); }

/* Profile dropdown panel items: ensure ≥44px tap rows too. */
.dropdown li a { min-height: 44px; display: flex; align-items: center; }

/* Account menu (profile dropdown): on mobile, render its items INLINE in the
   mobile-menu flow — full-width, left-aligned rows — instead of Pico's
   absolute-positioned, right-anchored (`dir="rtl"`) overlay, which floats
   over page content on phones (item 4). Desktop keeps the overlay untouched
   (the `dir="rtl"` attribute + the ≥768px rule below still apply there). */
@media (max-width: 767px) {
  .nav-bar__end .dropdown > summary + ul {
    position: static;
    direction: ltr;
    text-align: left;
    display: flex;
    flex-direction: column;
    z-index: auto;
    width: 100%;
    min-width: 0;
    margin: var(--space-1) 0 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    opacity: 1;
    transform: none;
    transition: none;
  }
  .nav-bar__end .dropdown > summary + ul li {
    width: 100%;
    margin: 0;
    padding: 0;
  }
  .nav-bar__end .dropdown > summary + ul li a {
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-control);
    color: var(--text-primary);
  }
  .nav-bar__end .dropdown > summary + ul li a:hover,
  .nav-bar__end .dropdown > summary + ul li a:focus-visible {
    background: var(--surface-muted);
  }
  /* Flatten the account section (mobile-first-ui.md §10): the toggle force-opens
     the <details>, so all rows show at once. Demote the user's name from a
     tappable pill to a muted, inert section label with a divider above it. */
  .site-header .nav-bar__end .dropdown > summary {
    pointer-events: none;
    min-height: 0;
    margin-top: var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-1);
    border: none;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .site-header .nav-bar__end .dropdown > summary::after { display: none !important; } /* caret */

  /* "Log out": a distinct, separated, full-width action pinned at the bottom of
     the account section — reachable the moment the menu opens. Quiet outline
     (not red: signing out is reversible). */
  .nav-bar__end .dropdown form {
    width: 100%;
    margin: var(--space-3) 0 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
  }
  .nav-bar__end .dropdown form button[type="submit"] {
    width: 100%;
    min-height: 48px;
    background: transparent;
    color: var(--color-primary-ink);
    border: 1px solid var(--border-strong);
  }
  .nav-bar__end .dropdown form button[type="submit"]:hover,
  .nav-bar__end .dropdown form button[type="submit"]:focus-visible {
    background: var(--surface-muted);
    border-color: var(--color-primary);
  }
  /* Pico's dropdown pulls itself up with a negative top margin (fine for the
     desktop overlay, but here it made the account summary overlap the
     neighbourhood switcher above it). Reset it in the inline mobile flow. */
  .nav-bar__end .dropdown { margin-top: 0; }
  /* Pico adds a fixed, full-viewport backdrop (summary::before) when the
     dropdown is open, to catch outside clicks. With the menu rendered inline it
     sat on top of the account rows and swallowed every tap (profile, log out).
     Remove it on mobile — the drawer's own toggle closes the menu. */
  .nav-bar__end .dropdown > summary::before { display: none !important; }
}

/* Desktop: restore the right-anchored overlay position that `dir="rtl"`
   used to imply on its own, now expressed explicitly so it only applies
   here (kept exactly equivalent to Pico's own `[dir=rtl]` dropdown rule). */
@media (min-width: 768px) {
  .nav-bar__end .dropdown > summary + ul[dir="rtl"] { right: 0; left: auto; }
}

/* --- md (≥768px): horizontal bar, matches Pico's desktop switch --- */
@media (min-width: 768px) {
  /* Brand | primary nav | (spacer) | end-actions on the SAME centred
     `.container` grid as the page content, so the logo's left edge lines up
     with every page's heading. The row is allowed to wrap: on mid-size
     screens the right-aligned control cluster drops to a second row instead
     of pushing off-screen; from ~1280px everything fits on one row. */
  .nav-bar {
    flex-wrap: wrap;
    padding: var(--space-4) 0;
    gap: var(--space-2) var(--space-4);
  }
  .nav-toggle { display: none; }
  .nav-bar__spacer { display: block; flex: 1 1 auto; }
  .nav-bar__links,
  .nav-bar__end { display: flex; flex-direction: row; flex-basis: auto;
                  align-items: center; padding-top: 0; gap: var(--space-4); flex-wrap: nowrap; }
  .nav-bar__links a,
  .nav-bar__end > a,
  .nav-bar__end .dropdown > summary,
  .neighbourhood-current,
  .neighbourhood-switcher select { width: auto; min-height: 40px; }
  .nav-bar__brand { margin-right: 0; }        /* desktop uses the spacer instead */
  /* One-line links: two-line wrapped labels read as clutter on the bar. */
  .nav-bar__links a { white-space: nowrap; }
  /* The bell joins the end cluster (its early DOM slot is a mobile-top-row
     concern); if the bar wraps, the whole control group right-aligns on its
     own row instead of dangling at the left edge. */
  .notification-bell { margin-left: 0; order: 1; }
  .nav-bar__end { margin-left: auto; }
  .language-flag { display: block; order: 2; }  /* outermost top-right */
}

/* Language flag picker -------------------------------------------------------
   Current language's flag as a compact icon button (like the bell); clicking
   opens a <details> dropdown listing every language (flag + native name). */
.language-flag { position: relative; margin: 0; }

/* Ghost icon-button, same family as the notification bell. The extra
   `.language-flag__toggle` class is load-bearing: Pico styles
   `details.dropdown summary:not([role])` as a form control (light chip with a
   blue-grey border), and the :not() raises its specificity above a plain
   `.site-header .language-flag > summary`. */
.site-header .language-flag > summary.language-flag__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  list-style: none;
}
.language-flag > summary::-webkit-details-marker { display: none; }
.language-flag > summary::after { display: none !important; }  /* kill Pico's caret */
.site-header .language-flag > summary.language-flag__toggle:hover { background: var(--surface-muted); }
.site-header .language-flag > summary.language-flag__toggle:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* The flag graphic itself. flex:0 0 auto stops it collapsing in the flex row
   of a dropdown option. A faint neutral hairline defines it on any backdrop. */
.flag {
  display: block;
  flex: 0 0 auto;
  width: 26px;
  height: 17px;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.language-flag > summary .flag { width: 24px; height: 16px; }

/* Dropdown options: flag + native name, ≥44px tap rows on a light panel. */
.language-flag ul { min-width: 11rem; }
.language-flag ul li { padding: 0; }
.language-flag ul button.language-flag__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border: none;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--text-primary);
  font-size: var(--fs-base);
  font-weight: 400;
  text-align: left;
  cursor: pointer;
}
.language-flag ul button.language-flag__option:hover {
  background: var(--surface-sunken);
}
.language-flag ul button.language-flag__option.is-active {
  font-weight: 600;
}
.language-flag ul button.language-flag__option.is-active::after {
  content: "\2713";           /* ✓ */
  margin-left: auto;
  color: var(--color-primary);
}

/* Notification bell ---------------------------------------------------------- */
.notification-bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  color: var(--color-primary-ink);
  text-decoration: none;
  background: transparent;
  border: 1px solid transparent;
}

.notification-bell:hover {
  background: var(--surface-muted);
}

.notification-bell__count {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: var(--radius-pill);
  background: var(--color-secondary);
  color: #fff;
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  font-weight: 600;
}

.notification-panel {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  max-width: 640px;
}

.notification-panel li {
  list-style: none; /* Pico puts square markers on the li itself */
  border-bottom: 1px solid var(--border);
  padding: var(--space-3) var(--space-2);
}

.notification-panel li:last-child {
  border-bottom: none;
}

.notification-panel a {
  color: var(--color-primary-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.notification-panel a:hover {
  color: var(--color-primary);
}

.notification-panel .is-unread {
  font-weight: 600;
  border-left: 3px solid var(--color-primary);
  padding-left: var(--space-3);
  background: var(--color-primary-50);
}

/* Page heading with an inline secondary action (e.g. "Mark all as read"). */
.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.page-head form {
  margin: 0;
}

.page-head button {
  width: auto;
  margin: 0;
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
}

/* Icon sprite --------------------------------------------------------------- */
.icon {
  width: 1.1em;
  height: 1.1em;
  stroke: currentColor;
  fill: none;
  vertical-align: -0.15em;
}

/* Cards ----------------------------------------------------------------------*/
/* Mobile-first (mobile-first-ui.md §4.2): exactly one column on phones (no
   horizontal overflow), 2+ from 576px, roomier from 768/1024px. */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  padding: 0;
  margin: var(--space-4) 0;
  list-style: none;
}

@media (min-width: 576px) {
  .card-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}

.listing-card {
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}

.listing-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
  transform: translateY(-2px);
}

.listing-card__link {
  color: inherit;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.listing-card__photo {
  aspect-ratio: 16 / 10;
  background: var(--color-primary-50);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-primary-ink);
  object-fit: cover;
  width: 100%;
}

/* Photo-less cards read as an intentional, colourful category mosaic rather
   than a wall of broken-image icons (visual-refresh §5). */
.listing-card__photo--empty {
  flex-direction: column;
  gap: var(--space-1);
  background: var(--cat-bg, var(--color-primary-50));
  color: var(--cat-ink, var(--color-primary-ink));
  font-weight: 600;
  font-size: var(--fs-sm);
  padding: var(--space-3);
  text-align: center;
}

.listing-card__photo--empty .icon {
  width: 1.8em;
  height: 1.8em;
}

/* Listing detail photo gallery (ADR-0008): no carousel JS, no cropping. The
   first photo is the hero; any further photos render as a compact row of
   smaller images below it, so the gallery doesn't push the description and
   booking form multiple screens down (especially on phones). */
.listing-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  align-content: start;
}

.listing-gallery__image {
  /* Show the whole image on the detail page — no fixed ratio, no crop.
     Capped so a tall image doesn't dominate; letterboxed on the muted panel. */
  max-width: 100%;
  max-height: 70vh;
  height: auto;
  object-fit: contain;
  background: var(--surface-muted);
  border-radius: var(--radius-card);
}

.listing-gallery__image:first-child {
  grid-column: 1 / -1;
  width: 100%;
}

.listing-gallery__image:not(:first-child) {
  width: 100%;
  max-height: 130px;
}

/* "Take a photo" capture button on the listing form: only meaningful on
   devices with a camera in hand, so it stays hidden on mouse-driven desktops
   (where the plain file input already covers webcams via the OS dialog). */
.photo-capture { display: none; }

@media (hover: none) and (pointer: coarse) {
  .photo-capture {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-2) 0 var(--space-1);
  }
}

.photo-capture__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  width: auto;
  margin: 0;
  cursor: pointer;
}

/* The hidden input is still focusable; mirror the focus ring on its label. */
.photo-capture input:focus-visible + .photo-capture__btn {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.photo-capture__status {
  font-size: var(--fs-sm);
  color: var(--success-ink);
}

.photo-capture__status--error {
  color: var(--danger-ink);
}

/* Gallery + camera pickers on the listing form share one row. The native
   file input is visually hidden (its chrome follows the *browser* locale, so
   it stayed English for Estonian members) and driven by a styled label. */
.photo-pickers {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: var(--space-2) 0 var(--space-1);
}

.photo-pickers .photo-capture {
  margin: 0;
}

.photo-pickers input:focus-visible + .photo-capture__btn {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Client-side thumbnails of the photos picked for upload (decorative; the
   status line carries the count). Matches the 16:10 listing-card ratio. */
.photo-previews {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.photo-previews:not(:empty) {
  margin: var(--space-2) 0;
}

.photo-previews img {
  width: 96px;
  height: 60px;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-md, 6px);
}

/* Listing form sections (listing-form-ux.md §6): headings sized between the
   page title and field labels so the groups read at a glance on mobile. */
.form-section {
  margin-bottom: var(--space-5, 2rem);
}

.form-section__heading {
  font-size: 1.25rem;
  margin-bottom: var(--space-2);
}

/* Required-field marker; the adjacent visually-hidden "(required)" carries
   the meaning for screen readers. */
.req {
  color: var(--danger-ink);
}

/* "Fill from photo" AI prefill on the listing form (US-031, ADR-0010). */
.ai-suggest {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: var(--space-2) 0 var(--space-3);
}

.ai-suggest button {
  width: auto;
  margin: 0;
}

.ai-suggest__status {
  font-size: var(--fs-sm);
  color: var(--success-ink);
}

.ai-suggest__status--error {
  color: var(--danger-ink);
}

/* My-listings neighbourhood filter pills (only rendered for members of 2+). */
.listing-filter {
  margin: var(--space-3) 0;
}

.listing-filter a[role="button"] {
  width: auto;
}

/* Thumbnails with a Remove control on the listing-edit page (ADR-0008). */
.photo-manager {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.photo-manager__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  width: 120px;
}

.photo-manager__image {
  width: 120px;
  height: 80px;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-md, 6px);
}

.listing-card__body {
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
}

.listing-card__title {
  font-size: var(--fs-lg);
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
}

.listing-card__meta {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

.listing-card__provider {
  color: var(--text-secondary);
  font-size: var(--fs-sm);
}

/* Pills & badges -------------------------------------------------------------*/
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  line-height: 1.4;
  white-space: nowrap;
}

.pill--free {
  background: var(--color-primary-50);
  color: var(--color-primary-active);
  font-weight: 500;
}

.pill--price {
  background: var(--surface-sunken);
  color: var(--text-primary);
  font-weight: 500;
}

.pill--distance {
  color: var(--text-muted);
}

/* The "add your address" nudge rendered where the distance pill would sit
   when the viewer has no saved coordinates (#95). Underline so it reads as
   a link, but keep the muted pill tone. */
a.pill--distance-hint {
  color: var(--text-muted);
  text-decoration: underline;
  white-space: normal;
}

/* Category colour map, shared by the chip and the photo placeholder. Each
   category sets a tint (--cat-bg) + AA-safe ink (--cat-ink); components read
   them so the mapping lives in one place (visual-refresh §2.8). */
[data-category="power-tools"],
[data-category="hand-tools"],
[data-category="building-renovation"] {
  --cat-bg: var(--color-primary-50);
  --cat-ink: var(--color-primary-ink);
}
[data-category="garden-outdoor"] { --cat-bg: #eaf3e0; --cat-ink: #3a5a17; }
[data-category="household"],
[data-category="cleaning"] {
  --cat-bg: var(--color-secondary-50);
  --cat-ink: var(--color-secondary-ink);
}
[data-category="vehicles-transport"] { --cat-bg: #eceaf4; --cat-ink: #3e357a; }
[data-category="services"] {
  --cat-bg: var(--color-amber-50);
  --cat-ink: var(--color-amber-ink);
}
[data-category="other"] {
  --cat-bg: var(--surface-sunken);
  --cat-ink: var(--text-secondary);
}

.pill--category {
  background: var(--cat-bg, var(--surface-sunken));
  color: var(--cat-ink, var(--text-secondary));
  border: 1px solid transparent;
  font-weight: 500;
}

.badge-verified {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  color: var(--color-amber-ink);
  font-size: var(--fs-xs);
  font-weight: 600;
}

.rating {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--color-amber-ink);   /* AA for the small numeric rating */
  font-size: var(--fs-sm);
  white-space: nowrap;
}

.rating .icon {
  color: var(--color-amber);       /* star glyph: 3:1 is fine for an icon */
}

.rating__stars {
  letter-spacing: 1px;
}

.rating__value {
  color: var(--text-secondary);
  font-weight: 500;
}

/* Status pills (booking / membership states) --------------------------------*/
.status-pill {
  display: inline-block;
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  border: 1px solid transparent;
}

/* Five distinct treatments across the lifecycle; the visible text label is the
   non-colour cue (visual-refresh §2.9). */
.status-pill--requested,
.status-pill--pending {
  background: var(--warning-50);
  color: var(--warning-ink);
}

.status-pill--approved,
.status-pill--active {
  background: var(--success-50);
  color: var(--success-ink);
}

.status-pill--denied,
.status-pill--cancelled,
.status-pill--declined {
  background: var(--danger-50);
  color: var(--danger-ink);
}

.status-pill--awaiting_confirmation {
  background: var(--info-50);
  color: var(--info-ink);
}

.status-pill--completed {
  background: var(--surface-sunken);
  color: var(--text-secondary);
}

/* Neutral treatment (e.g. the "Member" role badge — deliberately quiet next
   to the green "Admin" badge, see .status-pill--active above). */
.status-pill--neutral {
  background: var(--surface-sunken);
  color: var(--text-secondary);
}

/* Empty states ---------------------------------------------------------------*/
.empty-state {
  text-align: center;
  padding: var(--space-6) var(--space-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

/* Inline messages / toasts ---------------------------------------------------*/
.message {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-control);
  margin-bottom: var(--space-4);
  border: 1px solid transparent;
}

/* Messages that carry a leading icon (e.g. the signup two-step explainer):
   align the icon with the first line of text instead of stretching it.
   Scoped with an explicit modifier rather than :has() for broad support. */
.message--with-icon {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}
.message--with-icon .icon { flex: 0 0 auto; margin-top: 3px; }

.message--success {
  background: var(--success-50);
  color: var(--success-ink);
  border-color: var(--color-primary-100);
}

.message--error,
.message--danger {
  background: var(--danger-50);
  color: var(--danger-ink);
  border-color: var(--danger);
}

.message--warning {
  background: var(--warning-50);
  color: var(--warning-ink);
}

.message--info {
  background: var(--info-50);
  color: var(--info-ink);
}

/* Field errors ---------------------------------------------------------------*/
.field-error {
  color: var(--danger);
  font-size: var(--fs-sm);
  margin-top: -8px;
  margin-bottom: var(--space-2);
}

.field-hint {
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

/* Availability calendar / blocks ---------------------------------------------*/
.availability-list {
  list-style: none;
  margin: var(--space-2) 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.availability-list li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-control);
  align-items: center;
  flex-wrap: wrap;
}

/* Chat -------------------------------------------------------------------- */
.chat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 120px;
  max-height: 420px;
  overflow-y: auto;
  /* Reaching the top/bottom of the log must not start scrolling the page
     behind it (mobile scroll chaining). */
  overscroll-behavior: contain;
  padding: var(--space-3);
  /* Muted panel, not white — so the conversation log doesn't read as an input. */
  background: var(--surface-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  margin-bottom: var(--space-3);
}

/* Centre the "no messages yet" placeholder in the empty panel. */
.chat > p {
  margin: auto;
  text-align: center;
}

.chat-message {
  max-width: 80%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-card);
  border-bottom-left-radius: var(--space-1);
  background: var(--surface-card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

/* My messages: solid brand fill so the two sides read at a glance
   (colour + alignment, two cues). */
.chat-message--mine {
  align-self: flex-end;
  background: var(--color-primary);
  border-color: transparent;
  color: var(--text-on-primary);
  border-bottom-left-radius: var(--radius-card);
  border-bottom-right-radius: var(--space-1);
}

.chat-message--mine .chat-message__meta {
  color: rgba(255, 255, 255, 0.8);
}

.chat-message__meta {
  display: block;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-bottom: 2px;
}

.chat-form {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
}

.chat-form textarea {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  min-height: 48px;
  resize: vertical;
}

/* Pico makes <button> width:100% by default, which in this flex row collapsed
   the textarea to nothing. Keep the Send button to its own width. */
.chat-form button {
  width: auto;
  flex: 0 0 auto;
  margin: 0;
  align-self: stretch;
}

/* Tables -> cards on mobile (mobile-first-ui.md §4.5, §4.6) ------------------ */
/* Base (mobile): each row is a card; each cell is a label:value line. */
.table-reflow table,
.table-reflow thead,
.table-reflow tbody,
.table-reflow tr,
.table-reflow td { display: block; width: 100%; }

.table-reflow thead { display: none; }           /* headers move into data-label */

.table-reflow tbody tr {
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}

.table-reflow td {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-1) 0;
  border: none;
}

.table-reflow td::before {
  content: attr(data-label);
  font-weight: 500;
  color: var(--text-secondary);
  font-size: var(--fs-sm);
}

/* The actions cell: buttons full-width, stacked, ≥44px. Some action cells
   (e.g. my_listings.html) mix plain links with form buttons — treat both the
   same way so every action row-item reaches the touch-target minimum. */
.table-reflow td.cluster { flex-direction: column; align-items: stretch; }
.table-reflow td.cluster::before { margin-bottom: var(--space-1); }
.table-reflow td.cluster button,
.table-reflow td.cluster > a {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* md: restore real table layout */
@media (min-width: 768px) {
  .table-reflow table { display: table; }
  .table-reflow thead { display: table-header-group; }
  .table-reflow tbody { display: table-row-group; }
  .table-reflow tr { display: table-row; background: none; border: none;
                     box-shadow: none; padding: 0; margin: 0; }
  .table-reflow td { display: table-cell; width: auto; }
  .table-reflow td::before { content: none; }

  /* Action cells: back to a compact inline row of small controls that may
     wrap (the full-width stacked buttons are a phone affordance only). */
  .table-reflow td.cluster form { display: inline-block; width: auto; margin: 0; }
  .table-reflow td.cluster button,
  .table-reflow td.cluster > a {
    display: inline-flex;
    width: auto;
    min-height: 36px;
    margin: var(--space-1) var(--space-1) var(--space-1) 0;
    padding: var(--space-1) var(--space-3);
    font-size: var(--fs-sm);
    white-space: nowrap;
  }

  /* My listings: hug the photo/type/status columns so the title gets the
     leftover width instead of wrapping next to a sea of empty space. */
  .listings-table th:first-child,
  .listings-table td:first-child { width: 80px; }
  .listings-table td:nth-child(3),
  .listings-table td:nth-child(4) { width: 1%; white-space: nowrap; }
  /* Wide enough for two small action buttons per row (2×2 grid). */
  .listings-table td:last-child { width: 210px; }
}

/* Tabs ---------------------------------------------------------------------*/
.tabs {
  display: flex;
  gap: var(--space-2);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-4);
  flex-wrap: nowrap;
  overflow-x: auto;
}

.tabs a {
  padding: var(--space-3) var(--space-4);
  min-height: 44px;
  display: flex;
  align-items: center;
  text-decoration: none;
  color: var(--text-secondary);
  border-bottom: 2px solid transparent;
  font-weight: 500;
  white-space: nowrap;
}

.tabs a[aria-current="page"] {
  color: var(--color-primary-active);
  border-bottom-color: var(--color-primary);
  font-weight: 700;
}

@media (min-width: 768px) {
  .tabs { flex-wrap: wrap; overflow-x: visible; }
}

/* Utility --------------------------------------------------------------------*/
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.cluster {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

/* CTA button clusters (e.g. home hero/dashboard actions): full-width stacked
   buttons on mobile, inline row from sm (mobile-first-ui.md §4.1). Scoped to
   [role=button] children so it never touches pill/status clusters. */
.cluster > [role="button"] { width: 100%; }

@media (min-width: 576px) {
  .cluster > [role="button"] { width: auto; }
}

.text-muted {
  color: var(--text-muted);
}

.nowrap {
  white-space: nowrap;
}

.text-secondary {
  color: var(--text-secondary);
}

.mt-0 {
  margin-top: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.sticky-action {
  position: sticky;
  bottom: 0;
  background: var(--surface-page);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--border);
}

/* Reserve bottom space so the sticky "Request to book" action and the chat
   FAB never overlap on phones (mobile-first-ui.md §4.3). >=96px so the FAB
   (56px + its own margin) always clears the last card/action (item 8). The
   only allowed max-width exceptions in this file, both FAB-related. */
@media (max-width: 767px) {
  main.container { padding-bottom: calc(56px + var(--space-4) + var(--space-5)); }
  .sticky-action { padding-right: calc(56px + var(--space-3)); }
}

/* Booking detail actions: full-width, stacked, unambiguous on mobile
   (mobile-first-ui.md §4.4). */
@media (max-width: 767px) {
  .cluster > form { flex: 1 1 100%; }
  .cluster > form button { width: 100%; }
}

/* Floating chat popup (bottom-right, all pages) ----------------------------- */
.chat-fab {
  position: fixed;
  right: var(--space-4);
  /* Safe-area aware so the FAB clears the home-indicator area on notched
     phones instead of sitting under it (item 8). */
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  z-index: 900;
}

.chat-fab__btn {
  position: relative;
  width: 56px;
  height: 56px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: #fff;
  box-shadow: var(--shadow-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.chat-fab__btn .icon {
  width: 1.6em;
  height: 1.6em;
}

.chat-fab__badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--color-secondary);
  color: #fff;
  font-size: 11px;
  line-height: 20px;
  text-align: center;
  font-weight: 600;
}

.chat-fab__badge.is-hidden {
  display: none;
}

/* Base (mobile): near-full-screen bottom sheet — leaves a small top gap and
   clears the FAB, never covers the composer (mobile-first-ui.md §4.7). */
.chat-pop {
  position: fixed;
  right: var(--space-3);
  left: var(--space-3);
  /* Stays anchored just above the (safe-area aware) FAB. */
  bottom: calc(var(--space-3) + 64px + env(safe-area-inset-bottom));
  width: auto;
  min-height: 180px;
  max-height: calc(100dvh - 96px);
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  z-index: 900;
}

.chat-pop[hidden] {
  display: none;
}

#chat-pop-body {
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - 96px);
  min-height: 0;
}

/* From 576px: floating card, not a full-width sheet. */
@media (min-width: 576px) {
  .chat-pop {
    left: auto;
    right: var(--space-4);
    bottom: calc(var(--space-4) + 68px + env(safe-area-inset-bottom));
    width: min(360px, calc(100vw - 2 * var(--space-4)));
    max-height: min(70vh, 540px);
  }
  #chat-pop-body { max-height: min(70vh, 540px); }
}

.chat-pop__header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
}

.chat-pop__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-pop__close,
.chat-pop__back {
  width: auto;
  margin: 0;
  padding: 0 var(--space-2);
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.chat-pop__empty {
  padding: var(--space-5) var(--space-4);
  text-align: center;
}

.chat-convos {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Fill the popup below the header and scroll inside it. Without min-height,
     a flex child never shrinks below its content, so the list just got
     clipped and wheel/touch scrolled the page behind the popup instead. */
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.chat-convo {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  margin: 0;
  padding: var(--space-3) var(--space-6) var(--space-3) var(--space-3);
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  text-align: left;
  color: var(--text-primary);
  cursor: pointer;
}

.chat-convo:hover {
  background: var(--surface-muted);
}

.chat-convo__sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.chat-convo__preview {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.chat-convo__time {
  flex-shrink: 0;
  font-size: var(--fs-xs);
}

.chat-convo__unread {
  position: absolute;
  top: 50%;
  right: var(--space-3);
  transform: translateY(-50%);
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--color-secondary);
  color: #fff;
  font-size: 11px;
  line-height: 20px;
  text-align: center;
  font-weight: 600;
}

/* Reuse the .chat log styling, but fill the popup (no outer border/margin). */
.chat--pop {
  flex: 1;
  min-height: 140px;
  border: none;
  border-radius: 0;
  margin: 0;
}

.chat-form--pop {
  padding: var(--space-2);
  border-top: 1px solid var(--border);
}

/* Date + 24h time-slot picker (booking form): date grows, time select sits beside it.
   Allowed to wrap on narrow phones so the two controls never overflow
   (mobile-first-ui.md §4.3). */
.datetime-field {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.datetime-field input[type="date"] {
  flex: 1 1 60%;
  min-width: 0;
  margin: 0;
}

.datetime-field select {
  flex: 1 1 30%;
  width: auto;
  margin: 0;
}

/* Browse filters (item 7): the search box stays visible above; the four
   filter fields collapse behind a <details>/<summary> disclosure on mobile
   so a listing card is visible sooner. Always rendered `<details open>` so
   it works with no JS either way — desktop simply hides the summary toggle
   and the fields stay inline as before. */
.browse-filters { margin-bottom: var(--space-4); }
.browse-filters .grid {
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.browse-filters .grid label { margin-bottom: var(--space-1); }
.browse-filters .grid select { margin-bottom: 0; }

.browse-filters__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-card);
  color: var(--text-primary);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.browse-filters__summary::-webkit-details-marker { display: none; }
.browse-filters__summary::after {
  content: "\25BE";                 /* ▾ */
  color: var(--text-muted);
}
.browse-filters[open] > .browse-filters__summary::after { content: "\25B4"; }  /* ▴ */

@media (min-width: 768px) {
  .browse-filters__summary { display: none; }
  .browse-filters .grid { margin-top: 0; }
  /* Desktop keeps the filters inline regardless of the <details> open state
     (the summary is hidden, so there's no toggle) — force the panel visible. */
  .browse-filters:not([open]) > .grid { display: grid; }
}

/* Account pages (allauth) — centred card on the branded chrome --------------- */
.auth-page main#main-content {
  max-width: 26rem;
  margin: var(--space-7) auto;
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-md);
  padding: var(--space-6);
}

@media (max-width: 767px) {
  .auth-page main#main-content { padding: var(--space-5); }
}

.auth-page main#main-content h1 {
  margin-top: 0;
}

.auth-page form {
  margin: 0;
}

.auth-page form button[type="submit"] {
  width: 100%;
}

/* Auth form fields (login/signup/password reset): comfortable tap targets
   and a consistent field rhythm (item 6). */
.auth-page form label { margin-bottom: var(--space-2); }
.auth-page form input:not([type="checkbox"]),
.auth-page form select {
  height: 52px;
  border-radius: var(--radius-control);
  margin-bottom: var(--space-5);
}

/* "Remember me": a single tappable row (label wraps the checkbox + text) so
   the whole row — not just the tiny checkbox — responds to taps. */
.auth-checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  margin: 0 0 var(--space-5);
  cursor: pointer;
}
.auth-checkbox-row input[type="checkbox"] { margin: 0; flex: 0 0 auto; }

/* Google sign-in (ADR-0003) --------------------------------------------------
   A neutral/secondary treatment (Pico's `.secondary.outline` combo, already
   used elsewhere e.g. my_listings.html's Pause/Reactivate) so the OAuth
   alternative reads as secondary to the primary email form above it. */
.auth-divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1 1 auto;
  border-top: 1px solid var(--border);
}

.auth-oauth-btn {
  display: block;
  width: 100%;
  text-align: center;
}

/* Address autocomplete (ADR-0009 addendum: In-AKS replaces the map-pin) ------*/
.address-search {
  margin-bottom: var(--space-4);
}

.address-search__combobox {
  position: relative;
}

.address-search__listbox {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  box-shadow: var(--shadow-md);
  max-height: 16rem;
  overflow-y: auto;
}

.address-search__option {
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
}

.address-search__option:hover,
.address-search__option.is-active {
  background: var(--surface-muted);
}

.address-search__status {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin-top: var(--space-1);
}

/* Homepage / landing (homepage-redesign.md §1-§5C) --------------------------- */
.home-section { padding-block: var(--space-7); }
@media (min-width: 768px) { .home-section { padding-block: var(--space-8); } }
.home-section:first-of-type { padding-top: var(--space-5); }

/* Pico's `main{padding-block:var(--pico-block-spacing-vertical)}` adds its
   own top gap above the hero/dashboard; on mobile that pushes the first CTA
   further down than intended, so the home page zeroes it and relies on
   `.home-section:first-of-type`/`.dashboard-intro` for a tighter, controlled
   top gap instead (item 5/9). */
@media (max-width: 767px) {
  .home-page main.container { padding-top: 0; }
  .home-section:first-of-type { padding-top: var(--space-4); }
  .dashboard-intro { padding-top: var(--space-4); }
}

/* Hero ------------------------------------------------------------------ */
.hero__grid { align-items: center; gap: var(--space-6); }
.hero h1 {
  font-size: var(--fs-2xl); line-height: 1.2; font-weight: 800;
  margin-bottom: var(--space-4);
}
@media (min-width: 768px) {
  .hero h1 { font-size: var(--fs-3xl); line-height: 1.15; }
}
.hero__lead {
  font-size: var(--fs-lg); max-width: var(--measure);
  margin-bottom: var(--space-5);
}
/* CTA buttons: full-width + roomy on mobile, back to auto-sized from 576px
   (matches the `.cluster > [role=button]` width breakpoint below). */
.hero__cta { gap: var(--space-3); }
.hero__cta > [role="button"] { min-height: 56px; }
@media (min-width: 576px) {
  .hero__cta > [role="button"] { min-height: auto; }
}
.hero__login { margin-top: var(--space-4); }
.hero__art { display: flex; justify-content: center; }
.hero-spot { width: 100%; max-width: 340px; height: auto; }

/* Logged-in dashboard intro (home.html): same vertical rhythm as the hero
   above — heading, CTA buttons, then a muted status line (item 9). */
.dashboard-intro h1 { margin-bottom: var(--space-4); }
.dashboard-cta { gap: var(--space-3); }
.dashboard-cta > [role="button"] { min-height: 56px; }
@media (min-width: 576px) {
  .dashboard-cta > [role="button"] { min-height: auto; }
}
.dashboard-status {
  margin-top: var(--space-5);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-muted);
  border-radius: var(--radius-control);
  color: var(--text-secondary);
}

/* Glanceable dashboard cards: pending requests, unread messages, next
   booking. Each card is one link; rendered only when there is a value. */
.dashboard-stats {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

@media (min-width: 576px) {
  .dashboard-stats { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}

.dashboard-stat {
  display: block;
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  text-decoration: none;
  color: var(--text-primary);
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

.dashboard-stat:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
}

.dashboard-stat__value {
  display: block;
  font-size: var(--fs-2xl);
  font-weight: 700;
  color: var(--color-primary-ink);
}

.dashboard-stat__label {
  color: var(--text-secondary);
  font-size: var(--fs-sm);
}

/* Shared-example cards ---------------------------------------------------- */
.example-card {
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}
.example-card__icon { width: 2em; height: 2em; color: var(--color-primary); }
.example-card__title { font-size: var(--fs-lg); font-weight: 600; margin: 0; }
.example-card__line { font-size: var(--fs-sm); margin: 0; }

/* How it works (3 steps) -------------------------------------------------- */
.steps { list-style: none; padding: 0; margin: 0; gap: var(--space-6); }
.step {
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--text-on-primary);
  font-weight: 700;
}
.step__icon { width: 1.75em; height: 1.75em; color: var(--color-primary); }
.step__title { font-size: var(--fs-lg); font-weight: 600; margin: 0; }

/* Trust badges ------------------------------------------------------------ */
.trust-grid {
  list-style: none; padding: 0; margin: 0; display: grid;
  grid-template-columns: 1fr; gap: var(--space-4);
}
@media (min-width: 576px)  { .trust-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .trust-grid { grid-template-columns: repeat(4, 1fr); } }
.trust-badge {
  background: var(--color-primary-50);
  border: 1px solid var(--color-primary-100);
  border-radius: var(--radius-card);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.trust-badge__icon { width: 1.75em; height: 1.75em; color: var(--color-primary-ink); }
.trust-badge__title {
  font-size: var(--fs-lg); font-weight: 600; margin: 0;
  color: var(--color-primary-ink);
}

/* Honest positioning ------------------------------------------------------- */
.positioning { background: var(--surface-muted); border-radius: var(--radius-card); }
.positioning__inner {
  max-width: var(--measure); margin-inline: auto; text-align: center;
}

/* Final CTA band: the one place the warm terracotta accent is used
   (homepage-redesign.md §7). */
.cta-band {
  background: var(--color-primary-strong);
  border-radius: var(--radius-card);
  color: var(--text-on-primary);
}
.cta-band__inner { max-width: var(--measure); margin-inline: auto; text-align: center; }
.cta-band h2, .cta-band p { color: var(--text-on-primary); }
.cta-band__actions { justify-content: center; margin-top: var(--space-4); }
.cta-band__primary {
  background: var(--color-secondary);
  border-color: var(--color-secondary);
  color: var(--text-on-primary);
}
.cta-band__primary:hover {
  background: var(--color-secondary-hover);
  border-color: var(--color-secondary-hover);
}
.cta-band__login { color: var(--text-on-primary); text-decoration: underline; }

/* Info pages / footer --------------------------------------------------- */
.info-page { max-width: var(--measure); margin-inline: auto; }
.info-page h2 { margin-top: var(--space-6); }
.info-page__updated { margin-top: calc(-1 * var(--space-2)); }

/* Notification preferences (profile settings, REQ-012) -------------------- */
.pref-group {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-3) var(--space-4);
  margin-block-end: var(--space-4);
}
.pref-group__label { font-weight: 600; padding-inline: var(--space-1); }
.pref-group .field-hint { margin-block: 0 var(--space-2); }
.pref-choice { display: inline-flex; align-items: center; gap: var(--space-1); margin-inline-end: var(--space-4); }
.pref-push-status { font-weight: 600; }

/* The per-type email/push matrix (REQ-012 amendment). */
.pref-matrix-wrap { overflow-x: auto; }
.pref-matrix { width: 100%; margin-block-end: var(--space-3); }
.pref-matrix th, .pref-matrix td { padding-block: var(--space-1); }
.pref-matrix thead th { border-bottom: 1px solid var(--border); }
.pref-matrix__group th {
  padding-block-start: var(--space-4);
  font-weight: 600;
  color: var(--color-primary-ink);
}
.pref-matrix__event { font-weight: 400; text-align: left; }
.pref-matrix td { text-align: center; width: 5rem; }
.pref-matrix input[type="checkbox"] { margin: 0; }

/* Individual reviews list (REQ-005 amendment, US-050) --------------------- */
.review-list { list-style: none; padding: 0; }
.review-item {
  border-bottom: 1px solid var(--border);
  padding-block: var(--space-3);
}
.review-item:last-child { border-bottom: none; }
.review-item__meta { display: flex; align-items: center; gap: var(--space-3); margin-block-end: var(--space-1); }
.review-item__comment { margin-block: 0; }

/* Contact-form honeypot: kept in the DOM (naive bots fill it) but hidden from
   humans and assistive tech (the field is aria-hidden in the template). */
.honeypot-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--surface-muted);
  margin-top: var(--space-8);
  padding-block: var(--space-6);
  flex-shrink: 0;
}
.site-footer__grid {
  display: grid; grid-template-columns: 1fr; gap: var(--space-5);
}
@media (min-width: 576px) { .site-footer__grid { grid-template-columns: repeat(3, 1fr); } }
.site-footer__heading {
  font-size: var(--fs-base); font-weight: 700;
  color: var(--text-primary); margin: 0 0 var(--space-2);
}
/* The columns are semantic <nav>; override Pico's navbar styling (which forces
   nav + nav ul into a horizontal flex row) so the heading stacks above a
   vertical list instead of spreading across the row and overflowing. Pico also
   gives nav ul a -8px inline margin and nav a an 8px padding / -8px margin,
   which pushed the link text 8px left of the headings — zero all of it so
   headings and links share one left edge. */
.site-footer__col {
  display: block;
  /* Zero Pico's nav spacing at the source (it derives the ul's -8px inline
     margin and the links' 8px padding from these), rather than fighting its
     higher-specificity selectors rule by rule. */
  --pico-nav-element-spacing-vertical: 0;
  --pico-nav-element-spacing-horizontal: 0;
}
.site-footer__col ul { display: block; list-style: none; margin: 0; padding: 0; }
.site-footer__col li { display: block; margin-bottom: var(--space-1); padding: 0; }
.site-footer__col a {
  display: inline-flex; align-items: center; min-height: 44px;
  margin: 0; padding: 0;
}
.site-footer__bar { margin-top: var(--space-5); }

/* Give the last footer row the same clearance as the chat FAB reserves in
   `main.container`, so its links/copyright aren't hidden under the FAB when
   a page is scrolled all the way down (item 8). Pages short enough that the
   footer is pinned to the viewport bottom (sticky-footer layout) can still
   sit directly behind the FAB corner — flagged for visual confirmation. */
@media (max-width: 767px) {
  .site-footer { padding-bottom: calc(56px + var(--space-4) + var(--space-5)); }
}

/* Signup UX polish (homepage-redesign.md §5-signup) -------------------------- */
.pw-rules {
  list-style: none;
  margin: var(--space-1) 0 var(--space-3);
  padding: var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-control);
}
.pw-rules__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  padding: 2px 0;
}
.pw-rules__mark { color: var(--color-primary); flex: 0 0 auto; }
.pw-agree {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-3) 0;
  font-size: var(--fs-sm);
}
.pw-agree input[type="checkbox"] { margin-top: 3px; }

/* Admin dashboard (neighbourhood_admin_members.html / _pending.html) ---------
   Shared page shell + header card + table polish for the two neighbourhood-
   admin pages. Reuses .status-pill, .tabs, .table-reflow and .empty-state
   rather than duplicating them (visual-refresh §5, mobile-first-ui.md). */

.admin-page {
  max-width: 1160px;
  margin-inline: auto;
  margin-top: var(--space-5);   /* header -> page-header card: 24px mobile */
}

@media (min-width: 768px) {
  .admin-page { margin-top: var(--space-6); }   /* 32px desktop */
}

.admin-card {
  background: var(--surface-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--space-5);   /* card -> tabs: 24px (.tabs adds its own 16px below) */
}

.admin-card__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .admin-card__header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
  }
}

.admin-card__intro { min-width: 0; }

.admin-card__title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: 0 0 var(--space-1);
  font-size: var(--fs-2xl);
}

.admin-card__badge { flex: 0 0 auto; }

.admin-card__subtitle {
  margin: 0;
  color: var(--text-secondary);
}

.admin-card__stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 0 0 auto;
}

.admin-stat {
  /* inline-flex (not the default list-item) so no square list marker renders
     beside each pill; Pico sets `li` list-style at a specificity that beats the
     parent's `list-style:none`, so neutralise it on the item itself too. */
  display: inline-flex;
  align-items: center;
  list-style: none;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: 500;
  white-space: nowrap;
}

/* Table card: on mobile the rows are already individual cards (table-reflow),
   so the wrapper stays plain there; from md up it becomes one rounded,
   bordered card holding the real <table> (item 5). */
@media (min-width: 768px) {
  .admin-table-card {
    background: var(--surface-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
  }

  .admin-table-card table thead th {
    background: var(--surface-sunken);
    padding: var(--space-4);
    text-align: left;
  }

  .admin-table-card table td {
    padding: var(--space-4);
    vertical-align: middle;
  }

  .admin-table-card table tbody tr:not(:last-child) td {
    border-bottom: 1px solid var(--border);
  }

  /* Action column: visible header, right-aligned, fixed width so the button
     never crowds the table's edge. */
  .admin-table__action-col {
    width: 170px;
    text-align: right;
  }
}

/* Member name link: readable colour, underline only on hover/focus. */
.admin-table__member-link {
  color: var(--text-primary);
  font-weight: 500;
  text-decoration: none;
}
.admin-table__member-link:hover,
.admin-table__member-link:focus-visible {
  text-decoration: underline;
}

/* Promote button: compact single-line control on desktop; the existing
   .table-reflow td.cluster rules already make it full-width + >=44px tall
   on mobile. */
@media (min-width: 768px) {
  .admin-table__promote-btn {
    width: auto;
    min-height: 40px;
    padding: 0 var(--space-4);
    border-radius: var(--radius-control);
    white-space: nowrap;
  }
}

/* Booking rows: small listing thumbnail beside the title (my_bookings) ------- */
.booking-listing {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.booking-thumb {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-control);
  object-fit: cover;
  background: var(--surface-sunken);
}
.booking-thumb--empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--cat-bg, var(--surface-sunken));
  color: var(--cat-ink, var(--text-muted));
}
.booking-thumb--empty .icon { width: 1.3em; height: 1.3em; }

/* Booking detail heading: the same thumbnail beside the title + status pill. */
.booking-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.booking-head .booking-thumb { width: 56px; height: 56px; }
.booking-head h1 { margin-bottom: 0; }
.booking-head h1 a { color: inherit; text-decoration: none; }
.booking-head h1 a:hover { text-decoration: underline; }
.booking-head .status-pill { vertical-align: middle; }

/* Destructive actions tucked behind a <details> (cancel / force-close):
   make the summary read as an intentional control, not a broken accordion —
   danger-coloured label with the chevron beside it instead of floated away. */
details.action-reveal summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  width: auto;
  color: var(--danger-ink);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
}
details.action-reveal summary::after {
  float: none;
  margin-left: 0;
  filter: none;
}

/* Booking tables fill their card with a stable, cross-browser column layout ---
   `table-layout: fixed` + explicit per-column widths make the columns
   deterministic: Firefox and Chrome agree, and long content (e.g. the period)
   wraps inside its own cell instead of columns colliding — the earlier
   content-sized / greedy-last-column approaches distributed leftover space
   differently per browser (Firefox overlapped cells; Chrome left a ~0.5px
   sliver). `border-collapse: separate` lets the header band tile exactly to the
   card's rounded edges: collapsed borders fold the outer edge into the table
   box and leave that light sliver on the right. Row separators are drawn as
   cell bottom-borders (the `.admin-table-card … td` rule above), which works
   the same with separated borders. Desktop only; mobile keeps the card reflow. */
@media (min-width: 768px) {
  .admin-table-card table.booking-table {
    table-layout: fixed;
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
  }

  /* Listing | Borrower | Period | Status | Actions */
  .booking-table--provider th:nth-child(1), .booking-table--provider td:nth-child(1) { width: 30%; }
  .booking-table--provider th:nth-child(2), .booking-table--provider td:nth-child(2) { width: 16%; }
  .booking-table--provider th:nth-child(3), .booking-table--provider td:nth-child(3) { width: 24%; }
  .booking-table--provider th:nth-child(4), .booking-table--provider td:nth-child(4) { width: 14%; }
  .booking-table--provider th:nth-child(5), .booking-table--provider td:nth-child(5) { width: 16%; }

  /* Listing | Period | Status */
  .booking-table--borrower th:nth-child(1), .booking-table--borrower td:nth-child(1) { width: 44%; }
  .booking-table--borrower th:nth-child(2), .booking-table--borrower td:nth-child(2) { width: 32%; }
  .booking-table--borrower th:nth-child(3), .booking-table--borrower td:nth-child(3) { width: 24%; }
}

/* =========================================================================
   How-it-works guide: three visual process flows (US-036)
   The signature element is a connecting "path" through numbered stops — a
   vertical spine on mobile, a horizontal track on desktop. The one warm
   accent (terracotta) marks the human moment in each loan: the handshake.
   ========================================================================= */
/* Beta banner: honest, unobtrusive site-wide notice (US-036) -------------- */
.beta-banner {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--color-primary-50);
  border-bottom: 1px solid var(--color-primary-100);
  font-size: var(--fs-sm); color: var(--color-primary-ink);
  text-align: center;
}
/* Beta explainer link — unchanged destination/copy, just moved off the
   outer element now that the banner holds two actions (US-042). */
.beta-banner__link {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: var(--space-2);
  color: var(--color-primary-ink); text-decoration: none;
}
.beta-banner__tag {
  text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700;
  font-size: var(--fs-xs); line-height: 1.6;
  background: var(--color-primary); color: var(--text-on-primary);
  padding: 0 var(--space-2); border-radius: var(--radius-pill);
}
.beta-banner__text { color: var(--color-primary-ink); }
.beta-banner__link:hover .beta-banner__text,
.beta-banner__link:focus-visible .beta-banner__text { text-decoration: underline; }

/* "Send feedback" CTA (US-042): the existing terracotta secondary button
   (same accent as .cta-band__primary) reads as a clearly distinct action
   next to the sage explainer link — no new colour or component introduced.
   `flex: 0 0 auto` keeps it at its natural button width when the banner
   wraps to two lines on narrow viewports, so it stays fully tappable. */
.beta-banner__cta { flex: 0 0 auto; }

.home-section__more { margin-top: var(--space-5); margin-bottom: 0; font-weight: 600; }

.guide { max-width: 72rem; margin-inline: auto; }

.guide-hero { text-align: center; padding-block: var(--space-5) var(--space-6); }
.guide-eyebrow {
  text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
  font-size: var(--fs-sm); color: var(--color-primary); margin: 0 0 var(--space-2);
}
.guide-hero h1 { margin: 0 0 var(--space-3); }
.guide-lead { max-width: 48ch; margin-inline: auto; font-size: var(--fs-lg); }

.guide-flow { padding-block: var(--space-6); }
.guide-flow + .guide-flow { border-top: 1px solid var(--border); }
.guide-flow__head { margin-bottom: var(--space-6); }
.guide-flow__head h2 { margin: 0 0 var(--space-2); }
.guide-flow__head p { margin: 0; max-width: var(--measure); }

/* Flow track --------------------------------------------------------------
   Mobile default: vertical spine. The connector sits in the marker column and
   runs the full step height (into the gap) so it always reaches the next stop,
   regardless of how tall the text wraps. */
.flow { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-5); }
.flow__step { position: relative; display: flex; align-items: flex-start; gap: var(--space-4); }
.flow__marker { flex: 0 0 2.5rem; display: flex; justify-content: center; }
.flow__num {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem; border-radius: var(--radius-pill);
  background: var(--color-primary); color: var(--text-on-primary);
  font-weight: 700; font-size: var(--fs-lg); box-shadow: var(--shadow-sm);
}
.flow__icon { display: block; width: 1.6em; height: 1.6em; color: var(--color-primary); margin-bottom: var(--space-2); }
.flow__title { font-size: var(--fs-lg); font-weight: 600; margin: 0 0 var(--space-1); }
.flow__text { margin: 0; }
.flow__body { padding-bottom: var(--space-2); }

/* Connector line + arrowhead (mobile: vertical) */
.flow__step:not(:last-child)::before {
  content: ""; position: absolute; z-index: 0;
  left: 1.25rem; transform: translateX(-50%);
  top: 2.5rem; bottom: calc(-1 * var(--space-5));
  width: 2px; background: var(--color-primary-100);
}
.flow__step:not(:last-child)::after {
  content: ""; position: absolute; z-index: 1;
  left: 1.25rem; transform: translateX(-50%);
  bottom: calc(-1 * var(--space-5) + 3px);
  border-inline: 5px solid transparent;
  border-top: 6px solid var(--color-primary-100);
}

/* The human moment: handover / pickup in warm terracotta */
.flow__step--meet .flow__num { background: var(--color-secondary); }
.flow__step--meet .flow__icon { color: var(--color-secondary); }

/* Desktop: rotate the path to a horizontal track */
@media (min-width: 860px) {
  .flow { flex-direction: row; align-items: flex-start; gap: 0; }
  .flow__step { flex: 1 1 0; flex-direction: column; align-items: center; text-align: center; gap: var(--space-3); }
  .flow__marker { flex: 0 0 auto; width: 100%; }
  .flow__body { padding-bottom: 0; max-width: 22ch; }
  .flow__step:not(:last-child)::before {
    left: 50%; transform: none;
    top: 1.25rem; bottom: auto; right: auto;
    width: 100%; height: 2px;
  }
  .flow__step:not(:last-child)::after {
    left: auto; right: 0; top: 1.25rem; bottom: auto;
    transform: translate(50%, -50%);
    border-block: 5px solid transparent; border-inline: 0;
    border-left: 6px solid var(--color-primary-100);
  }
}

/* Off-platform money note */
.guide-note {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--surface-muted); border: 1px solid var(--border);
  border-radius: var(--radius-card); padding: var(--space-4);
  margin-block: var(--space-6);
}
.guide-note__icon { flex: 0 0 auto; width: 1.4em; height: 1.4em; color: var(--color-primary-ink); margin-top: 2px; }
.guide-note p { margin: 0; color: var(--text-secondary); }

.guide-cta {
  text-align: center; background: var(--color-primary-50);
  border: 1px solid var(--color-primary-100); border-radius: var(--radius-card);
  padding: var(--space-7) var(--space-5); margin-bottom: var(--space-7);
}
.guide-cta h2 { margin: 0 0 var(--space-2); }
.guide-cta p { margin: 0 0 var(--space-4); }
.guide-cta .cluster { justify-content: center; }
