/* Tools Nearby — Mist design system (locked Oct 6, 2026, Donald's pick).
   Neutral-light blend of the original prototype with Noir's immersive patterns.
   Palette: warm off-white #F7F5F1, ink #1A1D21, muted #6E757D, hairline #E8E4DC,
   brand red #F6040C, navy #023A50, amber #F5A623, sand #FBD184. */

/* Auth-gated nav and any other [hidden] element must stay hidden: class
   selectors like .header-nav a / #bottom-nav a (specificity 0-1-1+) beat the
   UA stylesheet's [hidden]{display:none} (0-1-0). */
[hidden] { display: none !important; }

:root {
  /* Mist palette — matches prototype exactly */
  --mist-bg: #F7F5F1;
  --mist-bg-2: #EFECE6;
  --mist-surface: #FFFFFF;
  --mist-card-2: #F1EEE8;
  --mist-ink: #1A1D21;
  --mist-muted: #6E757D;
  --mist-faint: #9AA0A6;
  --mist-hairline: #E8E4DC;
  --mist-line: rgba(26, 29, 33, 0.12);
  --mist-line-2: rgba(26, 29, 33, 0.07);
  --mist-red: #F6040C;
  --mist-red-dark: #B80309;
  --mist-navy: #023A50;
  --mist-navy-deep: #012A3B;
  --mist-amber: #F5A623;
  --mist-sponsored-bg: #FDF3E0;
  --mist-sponsored-text: #B7791F;
  --mist-sponsored-border: #F0D9A8;
  --mist-sand: #FBD184;
  --mist-glass: rgba(255, 255, 255, 0.72);
  --mist-glass-shadow: 0 24px 70px rgba(38, 35, 30, 0.25);
  --mist-shadow: 0 24px 70px rgba(38, 35, 30, 0.25);
  /* Donald's order (Oct 2026): stronger shadows to make the site pop. */
  --mist-shadow-pop: 0 28px 80px rgba(38, 35, 30, 0.30);
  /* Prototype-smooth easing (Oct 2026): cubic-bezier(.2,.85,.25,1) */
  --mist-ease: cubic-bezier(.2, .85, .25, 1);

  /* Legacy aliases — every view keeps working */
  --red: var(--mist-red);
  --red-dark: var(--mist-red-dark);
  --navy: var(--mist-navy);
  --navy-deep: var(--mist-navy-deep);
  --green: #43A002;
  --orange: #FBA200;
  --teal: var(--mist-navy);
  --leaf: #7BCF25;
  --sand: var(--mist-sand);
  --silver: #E8E4DC;
  --white: #FFFFFF;
  --bg: var(--mist-bg);
  --bg-soft: #FDFCF9;
  --card: var(--mist-surface);
  --text: var(--mist-ink);
  --muted: var(--mist-muted);
  --border: var(--mist-hairline);
  --danger: #D92D20;
  --star: var(--mist-amber);
  --amber-ad: var(--mist-sponsored-bg);
  --amber-border: var(--mist-sponsored-border);
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --radius-pill: 999px;
  --shadow: var(--mist-shadow);
  --shadow-lg: var(--mist-glass-shadow);
  --header-h: 60px;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  padding-top: var(--header-h);
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.5;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
/* Explicit-height images (tool cards, galleries) keep their crop via the
   more specific rules below; this only stops unsized images distorting. */
a { color: var(--navy); }
h1, h2 { letter-spacing: -0.02em; }

/* Focus visibility — keyboard / TV remote navigation */
:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- Header (light glass) ---------- */
#site-header {
  /* Donald's Oct 12, 2026 order: the toolbar always holds its position —
     fixed, locked height, never wraps, never expands. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  height: var(--header-h);
  flex-wrap: nowrap;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
  color: var(--text);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 12px 40px rgba(38, 35, 30, 0.12), 0 2px 8px rgba(38, 35, 30, 0.06);
}
.brand { display: flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.brand-logo { height: 38px; width: auto; display: block; filter: drop-shadow(0 2px 1px rgba(38, 35, 30, 0.42)); }
.header-search { position: relative; flex: 1; max-width: 480px; margin: 0 auto; min-width: 0; }
.header-search input {
  width: 100%;
  height: 42px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0 18px;
  font-size: 15px;
  background: #fff;
  color: var(--text);
  box-shadow: 0 6px 20px rgba(38, 35, 30, 0.10), inset 0 1px 0 #fff;
  transition: border-color .2s var(--mist-ease), box-shadow .2s var(--mist-ease);
}
.header-search input::placeholder { color: var(--muted); }
.header-search input:focus {
  border-color: var(--mist-red);
  outline: none;
  box-shadow: 0 0 0 4px rgba(246, 4, 12, 0.12), 0 10px 28px rgba(246, 4, 12, 0.10);
}
.suggest-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  z-index: 1100;
}
/* Donald's Oct 12, 2026 order: every search prediction is ONE horizontal
   line — small text that fits the dropdown width, no wrapping. */
.suggest-dropdown button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 9px 14px;
  border: none;
  background: none;
  font-size: 6px;
  color: var(--text);
  cursor: pointer;
  min-height: 40px;
  white-space: nowrap;
  overflow: hidden;
}
.suggest-dropdown button:hover, .suggest-dropdown button:focus-visible { background: var(--bg); }
.suggest-dropdown .s-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.suggest-dropdown .s-cat { color: var(--muted); font-size: 6px; flex-shrink: 0; }

.header-nav { display: none; align-items: center; gap: 4px; margin-left: auto; }
.header-nav a {
  color: var(--text);
  text-decoration: none;
  padding: 10px 14px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 600;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-family: 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
  transition: transform .18s var(--mist-ease), background .18s var(--mist-ease), box-shadow .18s var(--mist-ease);
}
.header-nav a:hover { background: rgba(26, 29, 33, 0.06); transform: translateY(-1px); }
.header-nav a:active { transform: scale(0.97); }
.header-nav a.active {
  background: linear-gradient(135deg, #F6040C, #B80309);
  color: #fff;
  box-shadow: 0 8px 24px rgba(246, 4, 12, 0.32), 0 2px 6px rgba(246, 4, 12, 0.22);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
}
#menu-toggle {
  display: inline-flex;
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  padding: 10px;
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 18px rgba(38, 35, 30, 0.12);
  transition: transform .15s var(--mist-ease), box-shadow .15s var(--mist-ease);
}
#menu-toggle:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(38, 35, 30, 0.16); }
#menu-toggle:active { transform: scale(0.95); }
#menu-toggle svg { width: 24px; height: 24px; }
#mobile-menu {
  position: fixed;
  top: var(--header-h);
  right: 12px;
  z-index: 1000;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 70px rgba(38, 35, 30, 0.25), 0 8px 24px rgba(38, 35, 30, 0.15);
  padding: 8px;
  min-width: 240px;
}
#mobile-menu a {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  text-decoration: none;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  font-size: 15px;
  font-weight: 600;
  min-height: 44px;
  font-family: 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
  transition: transform .15s var(--mist-ease), background .15s var(--mist-ease);
}
#mobile-menu a:hover { background: rgba(26, 29, 33, 0.06); transform: translateX(2px); }
#mobile-menu a:active { transform: scale(0.98); }
#mobile-menu .menu-linkbtn {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: 0; cursor: pointer;
  color: var(--text); padding: 12px 16px;
  border-radius: var(--radius-md); font-size: 15px; font-weight: 600; min-height: 44px;
  font-family: 'Inter', system-ui, sans-serif;
}
#mobile-menu .menu-linkbtn:hover { background: rgba(26, 29, 33, 0.06); }
#mobile-menu .menu-linkbtn[hidden] { display: none; }
/* Donald's Oct 12, 2026 order: Install app sticks out — bold red gradient CTA. */
#mobile-menu #menu-install {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
#mobile-menu #menu-install:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 8px 4px 4px;
  padding: 14px 18px;
  background: linear-gradient(135deg, #F6040C, #B80309);
  color: #fff;
  font-weight: 800;
  font-size: 15px;
  border-radius: 999px;
  border: none;
  box-shadow: 0 12px 32px rgba(246, 4, 12, 0.35), 0 3px 8px rgba(246, 4, 12, 0.25);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  letter-spacing: -0.01em;
  transition: transform .15s var(--mist-ease), box-shadow .15s var(--mist-ease);
}
#mobile-menu #menu-install:not([hidden]):hover {
  transform: translateY(-1px) scale(1.02);
  box-shadow: 0 16px 40px rgba(246, 4, 12, 0.45), 0 4px 12px rgba(246, 4, 12, 0.30);
}
#mobile-menu #menu-install:not([hidden]):active { transform: scale(0.97); }

/* ---------- Offline mode (Donald's order, Oct 2026) ---------- */
#offline-bar {
  position: fixed; top: var(--header-h); left: 0; right: 0; z-index: 1500;
  display: flex; justify-content: center; padding: 8px 12px;
  font-size: 13px; font-weight: 600; text-align: center;
  background: #43A002; color: #fff;
  box-shadow: 0 2px 12px rgba(2, 58, 80, 0.18);
}
#offline-bar.is-offline { background: var(--navy); }
#offline-bar span { max-width: 640px; }

/* ---------- Layout ---------- */
#view { min-height: calc(100dvh - var(--header-h)); padding-bottom: 96px; }
#view:has(.discover-layout) { padding-bottom: 0; }
/* Site footer (Oct 16, 2026): one muted legal line under every page; the
   large bottom padding clears the fixed bottom-nav dock (hidden ≥1280px,
   where the padding shrinks — see the 1280px query below). */
#site-footer { padding: 20px 16px 104px; }
#site-footer p { margin: 0; }
.container { max-width: 1200px; margin: 0 auto; padding: 16px; }
.page { animation: fadein 0.18s ease-out; }
@keyframes fadein { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; } }

/* ---------- Bottom nav: 5-item light-glass dock ---------- */
#bottom-nav {
  position: fixed;
  left: 10px; right: 10px;
  bottom: calc(10px + env(safe-area-inset-bottom));
  z-index: 1000;
  display: flex;
  align-items: flex-end;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(22px) saturate(1.5);
  backdrop-filter: blur(22px) saturate(1.5);
  border: 1px solid var(--border);
  border-radius: 28px;
  box-shadow: 0 24px 60px rgba(38, 35, 30, 0.28), 0 8px 20px rgba(38, 35, 30, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  padding: 6px;
}
#bottom-nav a {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 0 6px;
  text-decoration: none;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  min-height: 56px;
  justify-content: center;
  border-radius: 20px;
  transition: transform .18s var(--mist-ease), background .18s var(--mist-ease), color .18s var(--mist-ease), box-shadow .18s var(--mist-ease);
}
#bottom-nav a:active { transform: scale(0.94); }
/* Safety net: a label that still overflows its column on a very narrow
   phone truncates instead of colliding with its neighbor's letters. */
#bottom-nav a span:not(.bn-raise) { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
#bottom-nav a.active {
  color: #fff;
  background: linear-gradient(135deg, #F6040C, #B80309);
  box-shadow: 0 10px 26px rgba(246, 4, 12, 0.38), 0 3px 8px rgba(246, 4, 12, 0.25);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
}
#bottom-nav svg { width: 24px; height: 24px; }
#bottom-nav a.go-live { color: var(--muted); }
#bottom-nav a.go-live.active { color: var(--red); background: transparent; box-shadow: none; text-shadow: none; }
.bn-raise {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: linear-gradient(135deg, #F6040C, #B80309);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: -28px;
  border: 4px solid #fff;
  box-shadow: 0 12px 30px rgba(246, 4, 12, 0.48), 0 4px 10px rgba(246, 4, 12, 0.30);
  transition: transform .18s var(--mist-ease), box-shadow .18s var(--mist-ease);
}
.bn-raise svg { width: 30px; height: 30px; }
#bottom-nav a.go-live:active .bn-raise { transform: scale(0.93); }
/* Go Live button: red by default, green when the user has ≥1 live listing. */
#bottom-nav .bn-raise.is-live {
  background: linear-gradient(135deg, #43A002, #2F7301);
  box-shadow: 0 12px 30px rgba(67, 160, 2, 0.45), 0 4px 10px rgba(67, 160, 2, 0.28);
}

/* Attention blink (Donald's Oct 22, 2026): while the user has unread
   attention notifications (requests, bookings, messages — the
   ATTENTION_TYPES set in app.js), the raised Go Live button blinks
   through the brand palette until the batch is read or the button is
   tapped. Color-only animation (Dynamic Platform law: transform /
   opacity / color only, never delays a tap). The blink wins over the
   live green while it is on — attention outranks state. */
#bottom-nav .bn-raise.attn-blink {
  animation: tn-attn-blink 1.6s ease-in-out infinite;
}
@keyframes tn-attn-blink {
  0%   { background: linear-gradient(135deg, #F6040C, #B80309); box-shadow: 0 12px 30px rgba(246, 4, 12, 0.55), 0 4px 10px rgba(246, 4, 12, 0.35); }
  20%  { background: linear-gradient(135deg, #023A50, #01293A); box-shadow: 0 12px 30px rgba(2, 58, 80, 0.55), 0 4px 10px rgba(2, 58, 80, 0.35); }
  40%  { background: linear-gradient(135deg, #43A002, #2F7301); box-shadow: 0 12px 30px rgba(67, 160, 2, 0.55), 0 4px 10px rgba(67, 160, 2, 0.35); }
  60%  { background: linear-gradient(135deg, #FBA200, #C77F00); box-shadow: 0 12px 30px rgba(251, 162, 0, 0.55), 0 4px 10px rgba(251, 162, 0, 0.35); }
  80%  { background: linear-gradient(135deg, #029DAA, #02707A); box-shadow: 0 12px 30px rgba(2, 157, 170, 0.55), 0 4px 10px rgba(2, 157, 170, 0.35); }
  100% { background: linear-gradient(135deg, #F6040C, #B80309); box-shadow: 0 12px 30px rgba(246, 4, 12, 0.55), 0 4px 10px rgba(246, 4, 12, 0.35); }
}
/* Reduced motion: NO blinking — a steady multi-color ring instead. */
@media (prefers-reduced-motion: reduce) {
  #bottom-nav .bn-raise.attn-blink {
    animation: none;
    border-color: #FBA200;
    box-shadow: 0 0 0 3px #F6040C, 0 0 0 6px #029DAA, 0 12px 30px rgba(20, 26, 34, 0.35);
  }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 700;
  padding: 6px 14px;
  min-height: 30px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font);
  letter-spacing: 0.2px;
  transition: transform 0.06s var(--mist-ease), box-shadow 0.15s ease, background 0.15s ease;
  box-shadow: 0 6px 18px rgba(38, 35, 30, 0.18);
}
.btn-primary { background: var(--red); color: #fff; box-shadow: 0 2px 8px rgba(246,4,12,0.3); }
.btn-primary:hover { background: var(--red-dark); }
.btn-primary:active { transform: scale(0.98); }
.btn-navy { background: var(--navy); color: #fff; }
.btn-navy:hover { background: var(--navy-deep); }
.btn-green { background: var(--green); color: #fff; }
.btn-secondary { background: var(--silver); color: var(--text); }
.btn-outline { background: transparent; border: 2px solid var(--navy); color: var(--navy); }
.btn-sm { padding: 4px 10px; min-height: 22px; font-size: 9px; }
/* Donald's order (Oct 2026): welcome card smaller font, centered. */
.welcome-card { text-align: center; }
.welcome-title { font-size: 16px !important; font-weight: 700; margin: 0 0 6px 0 !important; text-align: center; }
.welcome-sub { font-size: 12px !important; text-align: center; margin: 0 0 12px 0 !important; }
/* Donald's order (Oct 2026): group share pills reduced by 2/3, classy centered. */
.btn-tiny { padding: 3px 8px !important; min-height: 20px !important; font-size: 7px !important; letter-spacing: 0.3px; text-transform: uppercase; }
/* Group share page — centered classy typography. */
#gs-list { text-align: center; }
#gs-list .card { text-align: center; }
#gs-list h2, #gs-list h3 { text-align: center; }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; }
/* Donald's order (Oct 2026): profile quick actions drastically smaller (1/4), centered symmetrical. */
.btn-row.quick-actions { justify-content: center; align-items: center; gap: 10px; }
.btn-xs {
  font-size: 11px !important; font-weight: 700;
  padding: 6px 14px !important; min-height: 28px !important;
  border-radius: 999px !important; letter-spacing: 0.2px;
}

/* ---------- OAuth sign-in (Google / Facebook) ---------- */
.oauth-wrap { margin-top: 2px; }
.oauth-divider { display: flex; align-items: center; gap: 12px; margin: 18px 0 14px; color: var(--muted); font-size: 12px; }
.oauth-divider::before, .oauth-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.btn-google { background: #fff; color: #1a1d21; border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn-google:hover { background: #f4f4f4; }
.btn-google .g-glyph { font-weight: 900; font-size: 18px; color: #4285F4; }
.btn-facebook { display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn-facebook .f-glyph { font-weight: 900; font-size: 18px; }
.btn-facebook { background: #1877F2; color: #fff; }
.btn-facebook:hover { background: #1466ce; }
.btn-facebook:active { transform: scale(0.98); }
#tn-oauth-google { display: flex; justify-content: center; }
.oauth-email-prompt p { margin: 0 0 12px; }

/* ---------- Auth pages: clean, even rhythm (Donald's order, Oct 2026) ---------- */
.auth-card { display: flex; flex-direction: column; gap: 22px; align-items: center; text-align: center; }
.auth-card .field { margin-bottom: 0; width: 100%; text-align: left; }
.auth-card p.center { margin: 0; }

/* Gelato-style signup (Donald's order, Oct 2026): centered logo, big
   heading, social pill buttons, dark email button. Clean and minimal. */
.signup-hero { text-align: center; padding-top: 32px; }
.signup-logo { width: 72px; height: 72px; margin: 0 auto 20px; display: block; }
.signup-title { font-size: 32px; font-weight: 800; margin: 0 0 8px; letter-spacing: -0.5px; }
.signup-sub { color: var(--muted); font-size: 15px; margin: 0 0 28px; }
.social-stack { display: flex; flex-direction: column; gap: 12px; margin-bottom: 4px; }
.social-btn {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  width: 100%; padding: 14px 20px; font-size: 16px; font-weight: 600;
  background: #fff; color: #1a1a1a; border: 1.5px solid #e0e0e0; border-radius: 999px;
  cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
}
.social-btn:hover { border-color: #bdbdbd; box-shadow: 0 1px 4px rgba(0,0,0,0.08); }
.social-btn .g-glyph, .social-btn .f-glyph {
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 18px; flex-shrink: 0;
}
.social-btn .f-glyph { color: #1877F2; }
#s-oauth-google > div { margin: 0 auto; }
/* One centered rail at EVERY width (Donald's Oct 21, 2026 — the Google
   pill "clips off"): below 1024px nothing centered the LOGIN slot's
   Google wrapper, and the stack's three CTAs ran three different
   heights (Google 40 / Facebook 52 / email 38, measured live). The
   Google slot is now a 48px row — the same rhythm §L set on desktop —
   with Google's own fixed 40px pill centered inside it, and the two
   CTAs we control share the 48px height on phone too. (The desktop §L
   block used to repeat these two rules; they live here now, once.) */
.auth-page #l-oauth-google,
.auth-page #s-oauth-google {
  display: flex; align-items: center; justify-content: center; min-height: 48px;
}
.auth-page .social-btn,
.auth-page .btn-dark-pill { height: 48px; }
.or-divider { display: flex; align-items: center; gap: 16px; margin: 20px 0; color: var(--muted); font-size: 14px; }
.or-divider::before, .or-divider::after { content: ''; flex: 1; height: 1px; background: #e0e0e0; }
.btn-dark-pill {
  width: 100%; padding: 11px 16px; font-size: 14px; font-weight: 700;
  background: #1a1a1a; color: #fff; border: none; border-radius: 999px; cursor: pointer;
  text-align: center; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 32px rgba(26, 26, 26, 0.35);
}
.btn-dark-pill:hover { background: #333; }
#s-email-form { margin-top: 24px; text-align: left; }
#s-email-form[hidden] { display: none; }
.auth-card .chip-row { margin-top: 10px; }
.oauth-wrap { display: flex; flex-direction: column; gap: 12px; margin: 0; }
.oauth-divider { margin: 4px 0; }
#tn-oauth-google { display: block; }
/* The Google button is Google's own iframe (fixed 40px tall) — the custom
   social buttons match its height so the pair looks symmetrical. */
.oauth-wrap .btn-google, .oauth-wrap .btn-facebook { min-height: 38px; padding: 8px 16px; font-size: 14px; border-radius: 999px; display: flex; align-items: center; justify-content: center; text-align: center; }

/* "More options" tuck-away (Donald's Oct 4 directive): advanced actions like
   bargaining, waitlist, and recurring bookings stay collapsed by default. */
details.more-options { width: 100%; }
details.more-options > summary { cursor: pointer; list-style: none; }
details.more-options > summary::-webkit-details-marker { display: none; }
details.more-options > summary::marker { content: ''; }
details.more-options .btn-block { margin-top: 12px; }
details.more-options .btn-block:first-child { margin-top: 0; }

/* ---------- Cards ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 16px;
}
.card h2, .card h3 { margin-top: 0; }
.tool-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  display: block;
  position: relative;
  transition: transform 0.12s var(--mist-ease), box-shadow 0.12s ease;
}
.tool-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.tool-card img.tool-photo { width: 100%; height: 180px; object-fit: cover; display: block; background: var(--silver); }
/* Calm Discover: max 2 badges rest quietly on the photo — never in the body. */
.tool-card-badges { position: absolute; top: 10px; left: 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.tool-card-body { padding: 12px 14px; }
.tool-card-title { font-weight: 700; font-size: 16px; margin: 0 0 4px; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tool-card-meta { color: var(--muted); font-size: 12px; margin-top: 2px; }
.tool-card-price { color: var(--red); font-weight: 800; font-size: 17px; margin-top: 6px; }
.tool-card-price small { color: var(--muted); font-weight: 400; font-size: 12px; }
.tool-card-price .rate-per { color: var(--muted); font-weight: 400; font-size: 12px; }

/* ---------- Compass Lab (admin-only ranking inspector) ---------- */
.cl-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.cl-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cl-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.cl-row .input { flex: 1 1 140px; min-width: 0; }
#cl-weights rect { transition: width .6s ease, x .6s ease; }
.cl-rank-row { border-top: 1px solid var(--border); padding: 10px 0; }
.cl-rank-row:first-child { border-top: none; }
.cl-rank-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cl-rank-num { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--navy); color: #fff; font-size: 12px; font-weight: 800; flex: none; }
.cl-factors { margin-top: 8px; display: grid; gap: 4px; }
.cl-factor { display: grid; grid-template-columns: 130px 1fr 64px; gap: 8px; align-items: center; }
.cl-factor-name { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-factor-track { height: 8px; background: var(--silver); border-radius: 4px; overflow: hidden; }
.cl-factor-fill { height: 100%; border-radius: 4px; }
.cl-factor-fill.pos { background: #029DAA; }
.cl-factor-fill.neg { background: #F6040C; }
.cl-factor-val { font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- Group Share — Tool Pool picture archive (classy gallery) ---------- */
.pool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 28px; }
.pool-grid > .ad-card { margin-bottom: 0; }
.pool-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); cursor: pointer; transition: transform .18s var(--mist-ease), box-shadow .18s ease; display: flex; flex-direction: column; }
.pool-card:hover, .pool-card:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-lg); outline: none; }
.pool-photo { position: relative; aspect-ratio: 4 / 3; background: linear-gradient(140deg, #F4F2EC 0%, #E9E5D9 100%); overflow: hidden; }
.pool-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pool-tile { width: 100%; height: 100%; display: grid; place-items: center; font-size: 64px; }
.pool-badge { position: absolute; top: 14px; left: 14px; font-size: 10px; font-weight: 800; letter-spacing: .3px; text-transform: uppercase; padding: 3px 8px; border-radius: var(--radius-pill); background: rgba(255,255,255,.94); box-shadow: var(--shadow); }
.pool-badge.ok { color: var(--green); }
.pool-badge.out { color: var(--red); }
.pool-count { position: absolute; bottom: 14px; right: 14px; font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: var(--radius-pill); background: rgba(26,29,33,.62); color: #fff; }
.pool-body { padding: 22px 22px 24px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.pool-name { font-size: 18px; font-weight: 750; letter-spacing: -0.015em; margin: 0; line-height: 1.3; }
.pool-meta { font-size: 12px; color: var(--muted); }
.pool-specs { margin-top: 8px; display: grid; gap: 3px; }
.pool-spec { display: flex; gap: 10px; font-size: 12px; color: var(--muted); }
.pool-spec .k { color: var(--muted); min-width: 110px; flex-shrink: 0; }
.pool-actions { margin-top: auto; padding-top: 16px; }
.pool-hero { border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 16 / 10; background: linear-gradient(140deg, #F4F2EC 0%, #E9E5D9 100%); }
.pool-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pool-thumbs { display: flex; gap: 10px; overflow-x: auto; margin-top: 12px; padding-bottom: 4px; }
.pool-thumbs img { width: 76px; height: 76px; object-fit: cover; border-radius: 12px; cursor: pointer; border: 2px solid transparent; flex-shrink: 0; }
.pool-thumbs img.active { border-color: var(--red); }
.pool-detail-title { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; margin: 18px 0 4px; }
@media (max-width: 640px) { .pool-grid { gap: 20px; } .pool-body { padding: 18px 18px 20px; } }
.badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.badge-plus { background: var(--navy); color: #fff; }
.badge-boost { background: var(--orange); color: #fff; }
.badge-business { background: var(--navy); color: #fff; }
.badge-reliable { background: var(--green); color: #fff; }
.badge-trusted { background: var(--navy); color: #fff; }
.badge-campaign { background: var(--mist-navy); color: #fff; }
.badge-auction { background: var(--navy); color: #fff; }
.badge-contractor-pro { background: var(--navy); color: #F5A623; border: 1px solid #F5A623; }
.badge-sponsored { background: var(--amber-ad); color: var(--mist-sponsored-text); border: 1px solid var(--amber-border); white-space: nowrap; }
.badge-toolmaster { background: var(--mist-amber); color: #1A1D21; }
/* Tool Helper (Donald's Oct 14, 2026): same badge family as the Tool
   Master, visibly lesser rank — outline instead of the solid fill. */
.badge-helper { background: transparent; color: #8a6d00; border: 1px solid var(--mist-amber); }
.badge-approved { background: var(--green); color: #fff; }
.badge-requested { background: var(--orange); color: #fff; }
/* Ad cards (Donald's Oct 13, 2026, esthetic standard): classy and calm —
 * warm amber wash, soft layered drop shadow, generous radius, never
 * crowded against neighboring content. One per surface, always. */
.ad-card {
  background: var(--amber-ad);
  border: 1px solid var(--amber-border);
  border-radius: 16px;
  /* Darker shadow so sponsored cards pop (Donald's Oct 13, 2026 order). */
  box-shadow: 0 2px 4px rgba(120, 84, 10, 0.20), 0 18px 42px rgba(120, 84, 10, 0.36);
  margin: 14px 0;
}
/* MP4 video ad creatives: show the FULL video, never cropped (Donald's
 * Oct 13, 2026 order). The frame is a true 16:9 stage with contain fit —
 * a 16:9 video fills it exactly; any other ratio letterboxes on navy. */
.tool-card video.tool-photo { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: contain; display: block; background: #10181c; }
.pool-grid video.tool-photo { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: contain; display: block; background: #10181c; border-radius: 10px; }
/* Speaker toggle on videos (Donald's Oct 13–14, 2026): sound is ON by
 * default — VideoSound in app.js handles the browser's first-gesture
 * unlock and the muted autoplay fallback before it. The icon always
 * shows the true state (🔊 on, 🔇 muted), bottom-right in a navy
 * circle; on players with native controls it rides above the
 * control bar instead of covering it. */
.ad-video-wrap { position: relative; display: block; }
.ad-video-wrap video { display: block; }
.ad-audio-btn {
  position: absolute; right: 8px; bottom: 8px; z-index: 3;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(2, 32, 71, 0.78); color: #fff; border: 1px solid rgba(255,255,255,0.35);
  font-size: 15px; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
  box-shadow: 0 2px 8px rgba(2, 32, 71, 0.35);
}
.ad-audio-btn:hover { background: rgba(2, 32, 71, 0.92); }
.ad-video-wrap.has-controls .ad-audio-btn { bottom: 38px; }

/* Ad description (Donald's Oct 13, 2026): one short line an advertiser
 * may add under the headline — shown under the title wherever the ad
 * appears. Calm by design: 12px muted. */
/* Perimeter law (Donald's Oct 13, 2026: "Govern the perimeter — no
 * description should go past the boundary of the card"): an ad card
 * CLIPS at its own border, and everything inside it — grid/flex items,
 * rotator layers, text blocks — can shrink, so nothing ever stretches
 * or spills out of the card. Covers every ad surface (feed, pools,
 * drawer, groups, storefronts, merch) because they all share these
 * classes.
 * FINAL shrink-to-fit rule (Donald's Oct 14, 2026, 11:16 AM CDT:
 * "Don't distort the cards — if the text is too long, reduce the
 * font to make it fit... I don't want to sacrifice esthetic"): this
 * supersedes BOTH earlier mechanisms — the Oct 13 ellipsis (it
 * clipped words) and this morning's wrap-and-grow full-fit (it
 * distorted cards). Now: the containment above stays, ad text still
 * WRAPS completely and is never clipped, AND every card keeps its
 * designed proportions — the copy lives in a fixed-size zone (see
 * .ad-copy / .tool-card-body / pool rules below) and AdFit in app.js
 * steps the FONT down (.ad-fit-1..4: title 16→11px floor,
 * description 12→9px floor, line-height tightened only at the last
 * step) until the complete text fits the zone. The SPONSORED badge
 * never shrinks. overflow-wrap:anywhere (inherited) still breaks
 * even a single unbroken word across lines rather than letting it
 * reach the border. Input caps are title 25 / description 75 chars;
 * longer grandfathered ads are fitted by the same steps. */
.ad-card { overflow: hidden; min-width: 0; overflow-wrap: anywhere; }
.ad-rot, .ad-rot-layer { min-width: 0; }
.ad-rot-layer { overflow: hidden; }
.ad-card > div, .ad-rot-layer > div { min-width: 0; }
.ad-card:has(.ad-desc), .tool-card:has(.ad-desc) { min-width: 0; overflow: hidden; }
.ad-desc { display: block; font-size: 12px; color: var(--muted); line-height: 1.45; white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; max-width: 100%; min-width: 0; }
/* Ad headlines wrap fully too. Scoped to ad cards: ordinary tool
 * cards keep their designed one-line titles. */
.ad-card .tool-card-title { white-space: normal; overflow: visible; text-overflow: clip; }
/* Shrink-to-fit copy zones (Donald's Oct 14, 2026 FINAL rule): each
 * surface's copy zone carries the surface's STANDARD height — the
 * generic slot's text column matches its 72px creative, the
 * Discover/drawer card body is a fixed 80px, the group pool card's
 * copy block a fixed 118px. AdFit (js/app.js) steps the zone's
 * .ad-fit-N class until badge + title + description fit inside;
 * the zones clip at their own box as the perimeter safety net. */
.ad-copy { display: block; max-height: 72px; overflow: hidden; }
.ad-card .tool-card-body { height: 92px; overflow: hidden; }
.pool-grid a.ad-card > div, .pool-grid .ad-rot-layer > div { height: 118px; overflow: hidden; }
/* Ad titles lead at headline leading (1.25), not the 1.5 paragraph
 * leading they would otherwise inherit — part of the designed copy
 * block on every surface (real tool cards keep their own titles). */
.ad-fit-title { font-size: 16px; line-height: 1.25; }
/* The font ladder AdFit applies (title floor 11px, description
 * floor 9px; line-height tightens only at the last step). */
.ad-fit-1 .ad-fit-title { font-size: 14.5px; }
.ad-fit-1 .ad-desc { font-size: 11px; }
.ad-fit-2 .ad-fit-title { font-size: 13px; }
.ad-fit-2 .ad-desc { font-size: 10px; }
.ad-fit-3 .ad-fit-title { font-size: 12px; }
.ad-fit-3 .ad-desc { font-size: 9.5px; }
.ad-fit-4 .ad-fit-title { font-size: 11px; }
.ad-fit-4 .ad-desc { font-size: 9px; line-height: 1.25; }
/* Admin ad review (Oct 13): the creative preview is a true 16:9 stage the
 * reviewer can actually see, and review rows obey the same perimeter law --
 * a long ad description inside the flex row can never stretch the card or
 * the page past the phone boundary. */
.ad-review-video { width: 100%; max-width: 320px; aspect-ratio: 16 / 9; height: auto; object-fit: contain; background: #10181c; border-radius: 10px; display: block; }
.review { min-width: 0; overflow: hidden; overflow-wrap: anywhere; }
.review > div { min-width: 0; }
.review-info { min-width: 0; overflow: hidden; }
.review .ad-desc { max-width: 100%; }
/* Studio "Your ads" rows: list rows, not proportioned cards — the
 * copy wraps inside the row under the perimeter law (Oct 14, 2026). */
#ad-mine { overflow-wrap: anywhere; }

/* Ad rotator card motion (Donald's Oct 13–14, 2026): several ads share
 * ONE card — the frame (amber wash, border, shadow, Sponsored
 * treatment) never moves; the card CONTENT (photo + text as one layer)
 * glides through it as a TRUE CROSSFADE (Donald's Oct 14, 2026:
 * "make the transition more smooth — it's too jumpy"): no sideways
 * travel at all — the incoming layer fades in on top with only a
 * whisper of rise (4px) while the outgoing layer fades out in place,
 * so the frame is never empty mid-swap and nothing ever lurches. One
 * 1100ms pass, cubic-bezier(.4,0,.2,1) — gentle at both ends. Layers
 * stack in a single grid cell; inactive layers are inert (no clicks,
 * hidden from assistive tech) and display:none once the swap lands.
 * Reduced motion: no sliding — an instant swap. */
div.ad-rot { display: grid; }
.ad-rot-layer { grid-area: 1 / 1; opacity: 0; visibility: hidden; pointer-events: none; transform: translate(0, 4px); transition: opacity 1.1s cubic-bezier(.4,0,.2,1), transform 1.1s cubic-bezier(.4,0,.2,1), visibility 0s linear 1.1s; }
.ad-rot-layer.on { opacity: 1; visibility: visible; pointer-events: auto; z-index: 2; transform: translate(0, 0); transition: opacity 1.1s cubic-bezier(.4,0,.2,1), transform 1.1s cubic-bezier(.4,0,.2,1), visibility 0s; }
.ad-rot-layer.exit { opacity: 0; visibility: visible; pointer-events: none; z-index: 1; transform: translate(0, 0); transition: opacity 1.1s cubic-bezier(.4,0,.2,1), visibility 0s linear 1.1s; }
@media (prefers-reduced-motion: reduce) { .ad-rot-layer, .ad-rot-layer.exit { transition: none; transform: none; } }

/* Storefront cards (Donald's Oct 13, 2026): classy elevated treatment —
 * soft navy-tinted layered drop shadow and a gentle lift on hover for
 * the clickable ones. Used on user/group storefronts + the directory. */
.storefront-card {
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 14px 34px rgba(2, 32, 71, 0.13);
}
a.storefront-card { transition: box-shadow .18s ease, transform .18s ease; }
a.storefront-card:hover {
  box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 20px 44px rgba(2, 32, 71, 0.18);
  transform: translateY(-2px);
}

/* AI agents section (Profile → 🤖 AI agents, redesigned Oct 14, 2026 at
 * Donald's word — "the ai agent key design doesn't fit my esthetics"):
 * the whole section is ONE framed card in the storefront-card shadow
 * language — centered titles, muted 12px notes, a tidy equal-column
 * form, divided rows, and soft tinted sub-cards for holds and the
 * one-time key reveal. All styling lives here; the markup in
 * js/views/profile.js (loadAgents) carries no inline styles. */
.agents-card {
  background: var(--card);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 14px 34px rgba(2, 32, 71, 0.13);
  padding: 16px;
  margin-top: 16px;
  min-width: 0;
}
.agents-title { font-weight: 700; font-size: 16px; text-align: center; }
.agents-note { text-align: center; margin-top: 4px; }
.agents-sub { font-weight: 700; text-align: center; margin-top: 18px; }
.agents-subcard {
  border-radius: 12px;
  padding: 12px;
  margin-top: 10px;
  min-width: 0;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.05), 0 8px 20px rgba(2, 32, 71, 0.08);
}
.agents-subcard-amber { background: #FDF6E9; border: 1px solid #F0D9A8; }
.agents-subcard-green { background: #F2F9EC; border: 1px solid #CBE5B4; }
.agents-subcard-title { font-weight: 700; }
.agents-line { margin-top: 2px; }
.agents-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; margin-top: 10px; }
.agents-keyrow-input { display: flex; gap: 8px; align-items: stretch; margin-top: 8px; }
.agents-keyrow-input .input { flex: 1; min-width: 0; }
.agents-keyrow-input .btn { flex: none; }
.agents-saved { margin-top: 8px; }
.agents-field { margin-top: 10px; min-width: 0; }
.agents-field label { display: block; margin-bottom: 4px; }
.agents-field .input { width: 100%; }
.agents-fields { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-top: 10px; }
.agents-fields .agents-field { margin-top: 0; }
@media (max-width: 560px) { .agents-fields { grid-template-columns: 1fr; } }
.agents-create { width: 100%; margin-top: 12px; }
.agents-list { margin-top: 8px; }
.agents-keyrow { padding: 10px 0; border-top: 1px solid var(--border); min-width: 0; }
.agents-keyhead { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.agents-keyname { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.agents-keymeta { margin-top: 2px; }
.agents-keyfoot { margin-top: 8px; }
.agents-keyrow-quiet .agents-keyname, .agents-keyrow-quiet .agents-keymeta { opacity: .55; }
.agents-chip { flex: none; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: var(--radius-pill); }
.agents-chip-active { background: #EDF7E0; color: #3F7D02; }
.agents-chip-expired { background: #F1EEE8; color: var(--muted); }
.agents-chip-revoked { background: #FDECEC; color: var(--red-dark); }
.agents-activity-row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 7px 0; border-top: 1px solid var(--border); }
.agents-activity-what { min-width: 0; overflow-wrap: anywhere; }
.agents-activity-when { flex: none; }
.agents-empty { text-align: center; margin-top: 8px; }

/* ---------- Security Watch (admin) ---------- */
.sec-h { text-align: center; }
.sec-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 10px; margin-top: 6px; }
.sec-stat { text-align: center; min-width: 0; }
.sec-stat-num { font-size: 26px; font-weight: 800; color: var(--navy); line-height: 1.15; }
.sec-chart { display: flex; align-items: flex-end; gap: 1px; height: 120px; border-bottom: 1px solid var(--border); }
.sec-bar-col { flex: 1 1 0; min-width: 2px; height: 100%; display: flex; align-items: flex-end; }
.sec-bar { width: 100%; background: var(--navy); border-radius: 2px 2px 0 0; position: relative; min-height: 0; }
.sec-bar-err { position: absolute; left: 0; right: 0; bottom: 0; background: var(--danger); border-radius: 0 0 0 0; }
.sec-axis { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; font-size: 12px; color: var(--muted); }
.sec-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-top: 14px; border-top: 1px solid var(--border); padding-top: 14px; }
.sec-form .field { flex: 1 1 150px; margin-bottom: 0; }
/* Security Watch standalone page (#/security-watch) — its own window with
   room to breathe (Donald's Oct 14, 2026 order). Wider container than the
   admin column; phones keep the calm single-column stack. */
.secw-container { max-width: 1440px; }
.secw-back { margin: 0 0 12px; }
/* Admin grouped windows (Donald's Oct 14, 2026 order): the Admin home
   is a launcher — one calm card per group of tools, each opening its
   own window. Same layered navy shadow as the standalone watch page. */
.admin-groups { display: grid; grid-template-columns: 1fr; gap: 16px; align-items: stretch; }
@media (min-width: 700px) { .admin-groups { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .admin-groups { grid-template-columns: repeat(3, 1fr); } }
.admin-groups .card { margin-bottom: 0; height: 100%; box-shadow: 0 1px 2px rgba(2,32,71,.07), 0 14px 34px rgba(2,32,71,.13); }
.admin-group-icon { text-align: center; font-size: 34px; line-height: 1.15; margin-bottom: 6px; }
.secw-page .card { box-shadow: 0 1px 2px rgba(2,32,71,.07), 0 14px 34px rgba(2,32,71,.13); }
.secw-pulse { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 16px; }
.secw-pulse .card, .secw-cols .card { margin-bottom: 0; }
.secw-cols { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 900px) {
  .secw-pulse { grid-template-columns: repeat(3, 1fr); }
  .secw-cols { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; }
  .secw-page .sec-chart { height: 200px; }
  .secw-table th, .secw-table td { padding: 6px 8px; }
}
/* Bot Watch (Donald's Oct 14, 2026): bot-traffic sub-lists + agent-key
   rows inside the standalone Security Watch page. */
.sec-sub { text-align: center; font-size: 14px; margin: 16px 0 4px; }
.secw-botlists { display: grid; grid-template-columns: 1fr; gap: 0 24px; }
@media (min-width: 900px) { .secw-botlists { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.secw-listrow { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 6px 0; border-top: 1px solid var(--border); }
.secw-route { font-size: 12px; overflow-wrap: anywhere; min-width: 0; }
/* Attack & bot source map (Security Watch) — dots sized by volume, red
   for attack-dominant sources, slate blue for bot-dominant ones. */
.secw-map { height: 340px; border-radius: 12px; overflow: hidden; margin-top: 4px; }
@media (max-width: 700px) { .secw-map { height: 260px; } }
.secw-map-dot { border-radius: 50%; border: 2px solid #fff; box-shadow: 0 1px 6px rgba(2,32,71,.45); cursor: pointer; opacity: .9; }
.secw-map-dot-attack { background: var(--danger); }
.secw-map-dot-bot { background: #38618c; }
.secw-map-legend { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; margin-top: 8px; }
.secw-map-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 5px; }
.secw-map-pop { font-size: 12px; line-height: 1.55; min-width: 180px; }
.secw-map .maplibregl-popup { max-width: min(260px, 82vw); }
@media (max-width: 700px) { .secw-map-pop { min-width: 0; } }
.secw-map-pop-title { font-weight: 800; font-size: 13px; margin-bottom: 2px; }
.secw-map-iprow { display: flex; justify-content: space-between; gap: 10px; }
.secw-map-ip { font-family: ui-monospace, Menlo, monospace; font-size: 12px; }

/* ---------- Auctions Nearby promo card (Discover feed) ---------- */
.auction-promo-card {
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%);
  border: none;
  color: var(--white);
  text-decoration: none;
  display: flex;
  align-items: stretch;
}
.auction-promo-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.auction-promo-body {
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  min-height: 180px;
}
.auction-promo-title { font-weight: 800; font-size: 18px; color: var(--white); }
.auction-promo-text { font-size: 14px; color: rgba(255, 255, 255, 0.85); line-height: 1.45; }
.btn-promo {
  align-self: flex-start;
  margin-top: 4px;
  background: var(--white);
  color: var(--navy);
  font-weight: 700;
  border-radius: var(--radius-pill);
  padding: 10px 18px;
  font-size: 14px;
  display: inline-block;
}

/* ---------- Forms ---------- */
.field { margin-bottom: 16px; }
.field label { display: block; font-weight: 600; margin-bottom: 6px; font-size: 15px; }
.field input, .field select, .field textarea {
  width: 100%;
  min-height: 48px;
  border: 2px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 16px;
  font-family: var(--font);
  background: #fff;
  color: var(--text);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--navy);
  outline: none;
}
.field .hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
.field .error { font-size: 12px; color: var(--danger); margin-top: 4px; }
/* ---------- Upload button (house file picker) ----------
   One treatment for every native file input (DA-01): the input keeps
   its id/name/accept/multiple and its behavior exactly — only the face
   changes. A navy outline pill (mirrors .btn-outline) replaces the OS
   "Choose File" widget, and the chosen file name reads in house text.
   Add class="upload-input" to any <input type="file">. */
input[type="file"].upload-input {
  font-family: var(--font);
  font-size: 14px;
  color: var(--mist-muted);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  padding: 4px 0;
  min-height: 0;
  width: 100%;
  cursor: pointer;
}
input[type="file"].upload-input::file-selector-button {
  font-family: var(--font);
  font-weight: 700;
  font-size: 14px;
  color: var(--navy);
  background: #fff;
  border: 2px solid var(--navy);
  border-radius: var(--radius-pill);
  padding: 9px 16px;
  margin-right: 12px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
input[type="file"].upload-input::file-selector-button:hover { background: var(--navy); color: #fff; }
input[type="file"].upload-input:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.checkbox-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; }
.checkbox-row input { width: 24px; height: 24px; margin-top: 2px; flex-shrink: 0; }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* Result filter bar (Donald's Oct 13, 2026): one calm scrollable row
   of small chips — kind, distance, and owner-kind toggles. Shared by
   the header results, the Discover slide, and the storefront
   directory. */
.filter-bar { display: flex; gap: 6px; align-items: center; overflow-x: auto; padding: 5px 2px; scrollbar-width: none; }
.filter-bar::-webkit-scrollbar { display: none; }
.f-chip { flex: 0 0 auto; border: 1px solid rgba(2, 32, 71, 0.18); background: #fff; color: var(--text); border-radius: 999px; padding: 3px 9px; font: 600 11px 'Inter', system-ui, sans-serif; min-height: 20px; cursor: pointer; }
.f-chip.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.f-sep { flex: 0 0 auto; width: 1px; height: 16px; background: rgba(2, 32, 71, 0.14); }
.chip {
  border: 2px solid var(--border);
  background: #fff;
  border-radius: var(--radius-pill);
  padding: 10px 18px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  min-height: 44px;
  color: var(--text);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.chip.selected { border-color: var(--red); background: #FFF0F0; color: var(--red); }

/* ---------- Steps wizard ---------- */
.steps-bar { display: flex; gap: 6px; margin-bottom: 20px; }
.steps-bar .step-dot { flex: 1; height: 6px; border-radius: 3px; background: var(--border); }
.steps-bar .step-dot.done { background: var(--green); }
.steps-bar .step-dot.current { background: var(--red); }

/* ---------- Trip progress card (Uber-style, Oct 2026) ---------- */
/* Live trip progress before fulfillment — same numbers on the booking
   detail and the tracking page, matching the app card word for word. */
.trip-card { box-shadow: var(--shadow); }
.trip-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.trip-phase { font-weight: 700; font-size: 13px; }
.trip-warn {
  background: var(--amber-ad); border: 1px solid var(--amber-border);
  color: var(--mist-sponsored-text); border-radius: 10px;
  padding: 8px 12px; font-size: 13px; font-weight: 600; margin-top: 10px;
}
.trip-main { text-align: center; margin: 12px 0 4px; }
.trip-big { font-size: 34px; font-weight: 800; line-height: 1.1; }
.trip-big span { font-size: 16px; font-weight: 600; color: var(--muted); }
.trip-steps { margin: 12px 0 4px; }
.trip-step-labels { display: flex; }
.trip-step-labels span { flex: 1; text-align: center; font-size: 10px; color: var(--muted); }
.trip-step-labels span.on { color: var(--text); font-weight: 700; }
.trip-exch-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.trip-exch-chip {
  background: var(--navy); color: #fff; border-radius: var(--radius-pill);
  padding: 6px 14px; font-weight: 700; font-size: 13px;
}
/* Trip mode pill + progress bar (Oct 2026): the readout names the
   travel mode (🚶 Walking / 🚗 Driving) as a small navy pill, and a
   house-style progress bar — navy fill on a light track, rounded,
   sitting in the card's soft shadow language — tracks the trip
   toward the pin, above the status steps. */
.trip-mode-pill, .mode-pill {
  display: inline-block; background: var(--navy); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1.5;
  padding: 1px 9px; border-radius: var(--radius-pill);
  vertical-align: 1px; white-space: nowrap;
}
.trip-progress {
  height: 8px; border-radius: 999px; background: var(--mist-bg-2);
  box-shadow: inset 0 1px 2px rgba(38, 35, 30, 0.10);
  overflow: hidden; margin: 10px 0 2px;
}
.trip-progress-fill {
  height: 100%; border-radius: 999px; background: var(--navy);
  transition: width 0.6s var(--mist-ease);
}
/* Tracking page (dynamic map, Oct 2026): the traveler dot, its stale
   dimming, and the share row with the walking/driving segmented
   control in the house scope-toggle style. */
.trk-dot, .liveloc-dot {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--navy); border: 3px solid #fff;
  box-shadow: 0 1px 6px rgba(2, 32, 71, 0.40);
  transition: opacity 0.4s ease, filter 0.4s ease;
}
.trk-dot.stale, .liveloc-dot.stale { opacity: 0.45; filter: grayscale(0.5); }
/* Tracking backups (Oct 17, 2026): the WENT DARK treatment — the
   last-known dot sits fainter than merely stale, with a dashed ring
   so it never reads as a live fix; the trip card's paused banner
   wears the amber warn language; the manual check-in row centers
   its pill buttons under the card (centering law). */
.trk-dot.dark { opacity: 0.3; filter: grayscale(0.8); outline: 2px dashed var(--muted); outline-offset: 2px; }
.trip-dark {
  background: var(--amber-ad); border: 1px solid var(--amber-border);
  color: var(--mist-sponsored-text); border-radius: 10px;
  padding: 8px 12px; font-size: 13px; margin-top: 10px; text-align: center;
}
.trip-checkins {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; flex-wrap: wrap; margin-top: 12px;
}
.trk-share-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
/* Live location in messages (Oct 2026): the share controls, the
   sharer's own always-visible bar, the other party's live map card,
   and the calm ended card. Inter, navy, muted 12px notes, classy
   cards — the house language throughout. */
.liveloc-controls { margin-bottom: 12px; }
.liveloc-mybar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: rgba(2, 58, 80, 0.06); border: 1px solid rgba(2, 58, 80, 0.20);
  border-radius: 12px; padding: 10px 12px; margin-bottom: 12px;
  font-size: 13px; font-weight: 600;
}
.liveloc-mybar-text { flex: 1; min-width: 180px; }
.liveloc-card { padding: 14px 16px; }
.liveloc-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.liveloc-map { height: 240px; border-radius: 12px; overflow: hidden; margin-top: 10px; background: #EDE9E1; }
.liveloc-updated { margin: 8px 0 0; }
.liveloc-updated.stale { color: var(--danger); }
.liveloc-ended { box-shadow: none; }
.liveloc-ended-row { display: flex; gap: 10px; align-items: flex-start; }

/* Rental flow timeline (Oct 2026): the approved journey both parties
   watch — Requested → Confirmed → Getting ready → Ready ✓ → On the
   way → Arrived → Exchanging → Out now → Ready to receive → On the
   way back → Arrived → Exchanging → Done. Same words as the app.
   Compact: the steps-bar dots plus one calm caption line. */
.flow-steps { margin: 2px 0 6px; }
.flow-caption { font-size: 12px; color: var(--muted); }
.flow-caption strong { color: var(--text); font-size: 12px; }

/* Tools Now! (Oct 2026): the last-minute request — the live owner is
   pinged (ring + vibrate on their phone) with 1 minute per ping.
   Owner card is loud but classy: amber Mist card, classy shadow,
   brand-red countdown bar, gentle pulse while unanswered. */
.tnow-card {
  background: var(--amber-ad);
  border: 1.5px solid var(--red);
  border-radius: var(--radius-lg, 16px);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 16px;
  animation: tnow-pulse 1.6s ease-in-out infinite;
}
@keyframes tnow-pulse {
  0%, 100% { border-color: var(--red); }
  50% { border-color: #B00309; }
}
.tnow-title { font-size: 17px; font-weight: 800; margin: 0 0 4px; }
.tnow-body { font-size: 14px; font-weight: 600; margin: 0 0 4px; }
.tnow-meta { font-size: 12px; color: var(--muted); margin: 0 0 10px; }
.tnow-bar { height: 8px; border-radius: 4px; background: var(--border); overflow: hidden; }
.tnow-bar-fill { height: 8px; border-radius: 4px; background: var(--red); transition: width 1s linear; }
.tnow-count { font-size: 26px; font-weight: 800; color: var(--red); text-align: center; margin: 8px 0; }
.tnow-actions { display: flex; gap: 8px; }
.tnow-wait {
  background: var(--amber-ad); border: 1px solid var(--amber-border);
  border-radius: var(--radius-lg, 16px); padding: 12px 14px; margin-bottom: 16px;
  font-size: 13px; font-weight: 600;
}
.tnow-outcome {
  border: 1px solid var(--border); border-radius: var(--radius-lg, 16px);
  padding: 12px 14px; margin-bottom: 16px; font-size: 13px; font-weight: 600;
  color: var(--muted);
}
.ready-note { font-size: 13px; font-weight: 700; color: var(--green); }

/* ---------- Booking bottom sheets (Mist) ---------- */
.card.sheet {
  border-radius: var(--radius-lg);
  padding-top: 12px;
}
.card.sheet::before {
  content: "";
  display: block;
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  margin: 0 auto 12px;
}

/* ---------- Map / Discover: full-screen light map + floating pill + bottom sheet ---------- */
.discover-layout {
  position: relative;
  display: block;
  height: calc(100dvh - var(--header-h));
  height: calc(100dvh - var(--header-h));
  overflow: hidden;
}
.map-wrap { position: absolute; inset: 0; height: auto; min-height: 0; }
#map { height: 100%; width: 100%; z-index: 1; background: #EDE9E1; }
/* Muted warm-gray map tiles (Mist) */
#map .maplibregl-canvas { filter: grayscale(0.35) sepia(0.18) saturate(0.75) brightness(1.03); }

/* Standalone filter bar (garages, services views) */
.filter-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 7px 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
  margin-bottom: 12px;
}
.filter-bar .chip { white-space: nowrap; flex: none; }
.filter-bar select, .filter-bar input {
  border: 2px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  font-size: 14px;
  min-height: 44px;
  flex-shrink: 0;
  font-family: var(--font);
  background: #fff;
  color: var(--text);
}

/* Header search filters dropdown (Discover): calm, labeled groups —
   "What's this for?" intent chips + Filters. Donald's order: the header
   search is the single search entry point; nothing floats over the map. */
.filters-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--mist-glass, var(--card));
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 16px;
  z-index: 1100;
  max-height: min(70vh, 560px);
  overflow-y: auto;
  text-align: left;
}
.filters-panel .search-group + .search-group { margin-top: 20px; }
.search-group-label {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 8px;
}
.filters-panel .chip-row { gap: 12px; align-items: center; }
.filters-panel .chip-row + .chip-row { margin-top: 12px; }
.filters-panel .chip { min-height: 40px; font-size: 13px; padding: 8px 14px; }
/* Donald's order (Oct 2026): no dropdown bar under the header — filters live
   at the top of the slide-out results drawer. Static flow, no glass card of
   its own; the drawer behind it is already glass. */
#drawer-filters { padding: 4px 4px 0; }
#drawer-filters:empty { display: none; }
#drawer-filters:empty + .drawer-filters-div { display: none; }
#drawer-filters .search-group + .search-group { margin-top: 16px; }
/* No pills in the search results (Donald's Oct 22, 2026 order): the
   drawer filters are clean form rows — a label + select on one line,
   checkbox rows for booleans, plain text links for shortcuts. */
#drawer-filters .filter-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
#drawer-filters .filter-row:first-child { margin-top: 0; }
#drawer-filters .filter-row label { font-size: 13px; font-weight: 600; color: var(--text); }
#drawer-filters .filter-check { display: flex; gap: 10px; align-items: center; margin-top: 12px; font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer; }
#drawer-filters .filter-check input { width: 20px; height: 20px; flex-shrink: 0; }
#drawer-filters .filter-links { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 12px; }
#drawer-filters .filter-links a { font-size: 13px; font-weight: 600; color: var(--navy, #023A50); }
#drawer-filters select, #drawer-filters input[type="date"] {
  min-height: 36px; font-size: 13px; border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 6px 10px; background: #fff;
  color: var(--text); max-width: 100%;
}
#drawer-filters .drawer-filters-div { margin: 14px 0 4px; border-top: 1px solid var(--border); }
.filters-panel select {
  border: 2px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  font-size: 14px;
  min-height: 44px;
  font-family: var(--font);
  background: #fff;
  color: var(--text);
}
.filters-panel input[type="date"] {
  border: 2px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 8px 12px;
  font-size: 14px;
  min-height: 44px;
  font-family: var(--font);
  background: #fff;
  color: var(--text);
}
/* Quieter chips for the "I have a project / Tool broken?" quick links. */
.filters-panel .chip-quiet { font-weight: 500; border-width: 1px; }

/* Drawer pull-tab: floating glass pill on the map edge (Donald's pattern) */
.drawer-toggle {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 550;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  border-top-right-radius: 6px;
  border-bottom-right-radius: 6px;
  padding: 14px 16px 14px 14px;
  font-weight: 700;
  font-size: 15px;
  color: var(--text);
  box-shadow: var(--mist-glass-shadow);
  cursor: pointer;
  min-height: 52px;
  font-family: var(--font);
}
.drawer-toggle svg { width: 22px; height: 22px; }
.drawer-toggle .drawer-count {
  background: var(--red);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  min-width: 26px;
  text-align: center;
}
.drawer-toggle:active { transform: translateY(-50%) scale(0.97); }

/* Tool list slide-out drawer: hidden off-canvas until pulled out */
.list-panel.tool-drawer {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(400px, 94vw);
  z-index: 600;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border-left: 1px solid var(--border);
  border-radius: 24px 0 0 24px;
  box-shadow: -8px 0 32px rgba(26, 29, 33, 0.10);
  transform: translateX(105%);
  transition: transform 0.28s ease;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.list-panel.tool-drawer.open { transform: translateX(0); }
.drawer-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 12px 10px 16px;
  flex-shrink: 0;
}
.drawer-head h2 { margin: 0; font-size: 18px; flex: 1; letter-spacing: -0.01em; }
.drawer-head .drawer-count {
  background: rgba(246, 4, 12, 0.10);
  color: var(--red);
  font-size: 13px;
  font-weight: 800;
  border-radius: var(--radius-pill);
  padding: 3px 10px;
}
.drawer-head .drawer-count:empty { display: none; }
.drawer-close {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: var(--mist-shadow);
}
.drawer-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2px 12px calc(12px + env(safe-area-inset-bottom));
}
.drawer-body .tool-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.drawer-scrim {
  position: absolute;
  inset: 0;
  z-index: 590;
  background: rgba(26, 29, 33, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s ease;
}
.drawer-scrim.open { opacity: 1; pointer-events: auto; }

/* (drawer styles above replace the old bottom-sheet pattern) */

.price-pin {
  background: var(--red);
  color: #fff;
  font-weight: 800;
  font-size: 13px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.28);
  white-space: nowrap;
  cursor: pointer;
  font-family: var(--font);
}

/* Tool-outline map pins: icon badge + price pill beneath (Donald's order).
   Mist language kept — red ring badge, navy line-art tool, red price pill.
   Small base size; --pin-scale (set from map zoom) grows/shrinks the whole pin. */
.tool-pin {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.30));
  transform: scale(var(--pin-scale, 1));
  transform-origin: center;
}
.tool-pin-badge {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--navy);
  border: 2px solid #fff;
  display: grid;
  place-items: center;
  color: #fff;
  position: relative;
}
/* Map pin parties (Donald's Oct 13, 2026): the badge COLOR names the
   owner kind at a glance — navy = individual neighbor, gold = Plus
   member (paid), teal = Contractor Pro, green = business. The glyph
   still says WHAT it is (tool category, garage, group). */
.tool-pin.party-plus .tool-pin-badge { background: #FBA200; color: var(--navy); }
.tool-pin.party-pro .tool-pin-badge { background: #029DAA; }
.tool-pin.party-biz .tool-pin-badge { background: #43A002; }
/* Auction pins (Donald's Oct 13, 2026): the gavel badge wears a gold
   ring so an auction stands out at a glance; the fill still names the
   owner party underneath it. */
.tool-pin.auction .tool-pin-badge { box-shadow: 0 0 0 2.5px #FBA200, 0 4px 10px rgba(2, 32, 71, 0.25); }
/* Live glow (Donald's Oct 14, 2026): a soft radiant halo BEHIND the badge
   of a member whose shop is open now — a pseudo-element, so 100 glowing
   pins cost no extra DOM and no filters. It sits outside the badge, so
   the party fill and the auction gold ring stay fully visible on top of
   it. Closed shops get no .live class: the flat pin, unchanged. */
.tool-pin.live .tool-pin-badge { position: relative; z-index: 0; }
.tool-pin.live .tool-pin-badge::before {
  content: ''; position: absolute; inset: -14px; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(251,162,0,.8) 0%, rgba(251,162,0,.4) 45%, rgba(251,162,0,0) 75%);
  box-shadow: 0 0 26px 12px rgba(251,162,0,.65);
  animation: tnPinGlowPulse 1.4s ease-in-out infinite;
}
@keyframes tnPinGlowPulse {
  0%, 100% { opacity: .7; transform: scale(.92); }
  50% { opacity: 1; transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .tool-pin.live .tool-pin-badge::before { animation: none; }
  .group-pin.live .group-pin-badge::before { animation: none; }
}
/* Map-key legend dot wearing the same halo. */
.map-key-dot.glow {
  background: radial-gradient(circle, rgba(251,162,0,.85) 0%, rgba(251,162,0,.35) 55%, rgba(251,162,0,.08) 100%);
  box-shadow: 0 0 10px 3px rgba(251,162,0,.55);
}
.tool-pin .pin-trusted {
  position: absolute; top: -5px; right: -5px;
  width: 13px; height: 13px; border-radius: 50%;
  background: #fff; color: var(--navy);
  font-size: 9px; font-weight: 900; line-height: 13px; text-align: center;
  border: 1px solid rgba(2,58,80,.3);
}
/* Map key (legend) — small glass button + panel over the Discover map. */
.map-key-btn {
  position: absolute; left: 12px; top: 12px; z-index: 550;
  background: var(--mist-glass); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  font: 600 12px var(--font); color: var(--navy);
  padding: 6px 12px; cursor: pointer;
  box-shadow: 0 4px 14px rgba(23,32,38,.14);
}
.map-key-panel {
  position: absolute; left: 12px; top: 52px; z-index: 551;
  background: var(--mist-glass); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 10px 12px; box-shadow: 0 10px 28px rgba(23,32,38,.18);
  min-width: 208px;
}
.map-key-panel h4 { margin: 0 0 6px; font-size: 12px; text-align: center; }
.map-key-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12px; }
/* W5: the key folds to ONE legend line. */
.map-key-line { margin: 0; font-size: 12px; line-height: 1.55; color: var(--ink, #26231e); }
.map-key-live { color: #C4040B; font-weight: 700; }
.map-key-dot {
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  display: grid; place-items: center; color: #fff; font-size: 11px;
  border: 1.5px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.25);
}
.map-key-dot.navy { background: var(--navy); }
.map-key-dot.gold { background: #FBA200; color: var(--navy); }
.map-key-dot.teal { background: #029DAA; }
.map-key-dot.green { background: #43A002; }
.map-key-dot.red { background: var(--red); }
/* Map-key LIVE-group dot: the same static amber halo as .map-key-dot.glow,
   so the legend's red group reads as glowing too. Scoped to the live-group
   row via this modifier — every other red dot is untouched. */
.map-key-dot.red.live-glow { box-shadow: 0 0 12px 5px rgba(251,162,0,.7), 0 1px 4px rgba(0,0,0,.25); }
.tool-pin-badge svg {
  width: 18px;
  height: 18px;
  display: block;
}
.tool-pin-price {
  margin-top: -6px;
  background: var(--red);
  color: #fff;
  font-weight: 800;
  font-size: 9.5px;
  line-height: 1;
  padding: 3.5px 8px;
  border-radius: var(--radius-pill);
  border: 1.5px solid #fff;
  white-space: nowrap;
  font-family: var(--font);
}
.maplibregl-popup-content { font-family: var(--font); }

/* ---------- Group Share neighborhoods ---------- */
.gs-hood-map { height: 200px; border-radius: 12px; overflow: hidden; border: 1px solid var(--hairline); }
.gs-hood-map .maplibregl-canvas { filter: sepia(0.12) saturate(0.92); }

/* Donald's Oct 12, 2026 order: visually impressive Group Share pages.
   Premium Mist treatment — glowing centered headers, lifted cards, smooth motion. */
.page-head-centered { position: relative; }
.page-head-centered::before {
  content: ''; position: absolute; inset: -30px -60px auto; height: 180px;
  background: radial-gradient(ellipse 60% 100% at 50% 0%, rgba(246, 4, 12, 0.07), transparent 70%);
  pointer-events: none;
}
#gs-list .card, #gs-search-results .card, #gs-browse-results .card {
  transition: transform .25s var(--mist-ease), box-shadow .25s var(--mist-ease);
}
#gs-list .card:hover, #gs-search-results .card:hover, #gs-browse-results .card:hover {
  transform: translateY(-3px);
  box-shadow: 0 24px 50px rgba(38, 35, 30, 0.16), 0 6px 16px rgba(38, 35, 30, 0.10);
}
#gs-search-q, #gs-browse-zip, #gs-zip {
  transition: border-color .2s var(--mist-ease), box-shadow .2s var(--mist-ease);
}
#gs-search-q:focus, #gs-browse-zip:focus, #gs-zip:focus {
  border-color: var(--mist-red);
  box-shadow: 0 0 0 4px rgba(246, 4, 12, 0.12), 0 8px 24px rgba(246, 4, 12, 0.08);
  outline: none;
}
@keyframes gsPinPulse {
  0% { box-shadow: 0 0 0 0 rgba(246, 4, 12, 0.30); }
  70% { box-shadow: 0 0 0 22px rgba(246, 4, 12, 0); }
  100% { box-shadow: 0 0 0 0 rgba(246, 4, 12, 0); }
}
.gs-pin-hero {
  display: inline-flex; align-items: center; justify-content: center;
  width: 84px; height: 84px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, #F6F1E7);
  box-shadow: 0 16px 40px rgba(38, 35, 30, 0.18), inset 0 1px 0 #fff;
  font-size: 40px;
  animation: gsPinPulse 2.4s ease-out infinite;
}
.gs-step { box-shadow: 0 24px 70px rgba(38, 35, 30, 0.14), 0 6px 20px rgba(38, 35, 30, 0.08); }
/* Navy group tags for Group Share groups — the group's name sits in a pill
   beneath the badge so groups are easy to spot on the map (Donald's order,
   Oct 2026), mirroring the tool pins' price pill. */
.group-pin {
  display: flex; flex-direction: column; align-items: center;
  cursor: pointer; font-family: var(--font);
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.30));
  transform: scale(var(--pin-scale, 1));
  transform-origin: center;
}
.group-pin-badge {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--navy); color: #fff;
  display: grid; place-items: center; font-size: 15px;
  border: 2px solid #fff;
}
.group-pin-name {
  margin-top: -6px;
  background: var(--navy); color: #fff;
  font-weight: 700; font-size: 9.5px; line-height: 1;
  padding: 3.5px 8px; border-radius: var(--radius-pill);
  border: 1.5px solid #fff; white-space: nowrap;
  max-width: 140px; overflow: hidden; text-overflow: ellipsis;
}
/* LIVE groups sell on the market — their map icon turns RED so a live
   group is unmistakable next to private (navy) groups (Donald's order,
   Oct 13, 2026). */
.group-pin.live .group-pin-badge { background: var(--red); }
.group-pin.live .group-pin-name { background: var(--red); }
/* Live glow for groups (Donald's Oct 16, 2026 — "no pulse around my
   groupshare icon"): a LIVE group breathes with the SAME amber halo as a
   live tool pin — identical gradient, shadow, timing and keyframes
   (tnPinGlowPulse above), behind the badge so the RED live fill and the
   name pill stay fully visible on top of it. Private (navy) groups get
   no .live class: the flat pin, unchanged. */
.group-pin.live .group-pin-badge { position: relative; z-index: 0; }
.group-pin.live .group-pin-badge::before {
  content: ''; position: absolute; inset: -14px; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(251,162,0,.8) 0%, rgba(251,162,0,.4) 45%, rgba(251,162,0,0) 75%);
  box-shadow: 0 0 26px 12px rgba(251,162,0,.65);
  animation: tnPinGlowPulse 1.4s ease-in-out infinite;
}
.dgc-live { color: var(--red); font-weight: 800; font-size: 10px; letter-spacing: .4px; }
.live-badge-red {
  background: #fdecec; color: var(--red);
  border: 1px solid #f5b8ba; font-weight: 700;
}
.group-pin-picker { width: 26px; height: 26px; font-size: 13px; }
.maplibregl-popup .group-popup { font-family: var(--font); min-width: 150px; }
.tool-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }

/* ---------- Detail: full-bleed hero + floating glass card + sticky CTA ---------- */
.tool-detail .tool-top { padding-bottom: 0; }
.tool-hero { margin: 0; }
.tool-hero .photo-gallery {
  display: flex; gap: 8px; overflow-x: auto;
  margin: 0; padding: 0;
  scroll-snap-type: x mandatory;
}
.tool-hero .photo-gallery img {
  height: 320px;
  border-radius: 0;
  flex-shrink: 0;
  scroll-snap-align: center;
  background: var(--silver);
}
.tool-hero .photo-gallery img:first-child { width: 100%; object-fit: cover; }
.tool-glass-card {
  position: relative;
  z-index: 2;
  margin: -64px 16px 0;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--mist-glass-shadow);
  padding: 20px;
}
.tool-glass-card h1 { margin: 0 0 8px; font-size: 24px; }
.tool-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.sticky-cta {
  position: sticky;
  bottom: calc(96px + env(safe-area-inset-bottom));
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 16px;
  padding: 12px 12px 12px 20px;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--mist-glass-shadow);
}
.sticky-cta .price-line { font-size: 22px; }
.sticky-cta .btn { flex-shrink: 0; }

/* Legacy detail bits (kept for other views) */
.photo-gallery { display: flex; gap: 8px; overflow-x: auto; margin: 0 -16px; padding: 0 16px 8px; }
.photo-gallery img { height: 240px; border-radius: var(--radius-md); flex-shrink: 0; }
.price-line { font-size: 28px; font-weight: 800; color: var(--red); letter-spacing: -0.02em; }
.price-line small { font-size: 15px; color: var(--muted); font-weight: 400; }
.owner-row { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; }
/* Glitch fix (Oct 22, 2026, G3): the rail is OUTSIDE #tab-body, so
   the settle gate never covers it — the public-profile fill swaps
   the bare face for the ringed face (bigger: 4px ring padding +
   border) and the swap visibly grew the identity card and shoved
   the page (measured CLS 0.0135). The ring slot now reserves its
   final geometry from the first paint: a fixed 106×106 box (the
   92px face + ring chrome) that the fill lands INSIDE. The name
   line's bits slot (#me-kit-line) reserves its width inline in the
   markup, the Oct-20 pattern extended to the slots it missed. */
#me-kit-ring { display: inline-flex; align-items: center; justify-content: center; width: 106px; height: 106px; flex: none; }
/* Donald's order (Oct 2026): drop shadow to make the name pop. */
.owner-row h2 { text-shadow: 0 2px 12px rgba(38, 35, 30, 0.18); margin: 0; }
/* Donald's order (Oct 2026): all designs centered where needed. */
.owner-row > div { display: flex; flex-direction: column; align-items: center; }
/* Verification checklist — Donald's order (Oct 2026): smaller, centered, classy. */
.verify-checklist {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 8px 16px; margin-top: 16px; padding: 12px 0;
}
.verify-item {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 6px; font-weight: 700; letter-spacing: 0.15px;
  color: var(--mist-faint); text-transform: uppercase;
}
.verify-item .verify-dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: #D8D4CC; flex-shrink: 0;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.12);
}
.verify-item.done { color: var(--mist-ink); }
.verify-item.done .verify-dot {
  background: #43A002;
  box-shadow: 0 0 0 3px rgba(67, 160, 2, 0.18), 0 0 12px rgba(67, 160, 2, 0.65), 0 2px 6px rgba(67, 160, 2, 0.5);
}
/* Step dot (Donald's Oct 13, 2026): a small point beside each verification
   step — green (#43A002) once the step is complete, light gray until then.
   Turns green one by one as the user verifies; admins read all green. */
.vfy-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #D8D4CC; display: inline-block; flex-shrink: 0;
}
.vfy-dot.on { background: #43A002; box-shadow: 0 0 6px rgba(67, 160, 2, 0.55); }
.verification-checklist .vfy-dot { margin-right: 7px; vertical-align: 2px; }
/* Public verification status (Donald's Oct 13, 2026): visitors see the same
   step dots on a storefront — calm, small, centered under the trust badge. */
.pub-verify { margin-top: 10px; }
.pub-verify-title {
  font-size: 12px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.6px; text-align: center;
}
.pub-verify-row {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 6px 14px; margin-top: 6px;
}
.pub-verify-item {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--muted);
}
.avatar { width: 69px; height: 69px; border-radius: 50%; object-fit: cover; background: var(--silver); box-shadow: 0 12px 28px rgba(38, 35, 30, 0.45), 0 3px 8px rgba(38, 35, 30, 0.30); }
.stars { color: var(--star); letter-spacing: 2px; }
/* Donald's order (Oct 2026): 5 gray stars when no ratings yet. */
.stars-empty { color: #CECFD4; }
/* Functioning AVERAGE stars (app reviews, Oct 15, 2026): silver row
   beneath, amber row clipped to average/5 width on top, so a 4.3
   average renders 4 full stars + a partial fifth. */
.avg-stars { position: relative; display: inline-block; line-height: 1; letter-spacing: 2px; font-size: 22px; }
.avg-stars-base { color: #CECFD4; }
.avg-stars-fill { color: var(--star); position: absolute; left: 0; top: 0; overflow: hidden; white-space: nowrap; }
.apprev-summary { text-align: center; }
.apprev-big { font-size: 38px; font-weight: 800; line-height: 1.1; }
.apprev-avgrow { margin-top: 2px; }
.apprev-editor .ar-pick { font-size: 30px; cursor: pointer; padding: 0 2px; }
.apprev-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.apprev-date { margin-left: auto; }
.apprev-comment { margin: 8px 0 0; }
.apprev-prompt h3 { margin-top: 0; }
.kv { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border); }
.kv:last-child { border-bottom: none; }
.kv .k { color: var(--muted); }
.kv .v { font-weight: 600; text-align: right; }
.kv.total .v { color: var(--red); font-size: 20px; font-weight: 800; }

/* ---------- Chat ---------- */
#chat-fab {
  position: fixed;
  bottom: 100px;
  right: 16px;
  z-index: 1200;
  width: 60px; height: 60px;
  border-radius: 50%;
  border: none;
  background: linear-gradient(135deg, #023A50, #012A3B);
  color: #fff;
  cursor: pointer;
  /* Classy layered drop shadow (Donald's Oct 13, 2026 helper redesign). */
  box-shadow: 0 2px 6px rgba(2, 58, 80, 0.28), 0 16px 34px rgba(2, 58, 80, 0.40);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
#chat-fab:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(2, 58, 80, 0.28), 0 22px 44px rgba(2, 58, 80, 0.46); }
#chat-fab svg { width: 26px; height: 26px; }
#chat-panel[hidden] {
  display: none !important;
}
#chat-panel {
  position: fixed;
  bottom: 172px;
  right: 16px;
  z-index: 1200;
  width: min(380px, calc(100vw - 32px));
  height: min(560px, calc(100dvh - 240px));
  background: var(--card);
  border: 1px solid rgba(2, 58, 80, 0.10);
  border-radius: var(--radius-lg);
  /* Classy layered drop shadow (Donald's Oct 13, 2026 helper redesign):
     deep, soft, navy-tinted — the storefront-card treatment, floating. */
  box-shadow: 0 4px 10px rgba(2, 58, 80, 0.10), 0 24px 54px rgba(2, 58, 80, 0.30), 0 44px 96px rgba(2, 58, 80, 0.14);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: chat-panel-in 0.22s ease;
}
@keyframes chat-panel-in { from { opacity: 0; transform: translateY(10px) scale(0.985); } to { opacity: 1; transform: none; } }
.chat-header {
  background: linear-gradient(135deg, #023A50, #012A3B);
  box-shadow: 0 6px 18px rgba(2, 58, 80, 0.25);
  color: #fff;
  padding: 14px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.chat-header button { background: none; border: none; color: #fff; font-size: 18px; cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; }
.chat-messages { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.chat-msg { max-width: 85%; padding: 10px 14px; border-radius: var(--radius-md); font-size: 15px; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.chat-msg.bot { background: #fff; align-self: flex-start; border: 1px solid rgba(2, 58, 80, 0.08); box-shadow: 0 1px 3px rgba(2, 58, 80, 0.10), 0 8px 20px rgba(2, 58, 80, 0.07); }
.chat-msg.user { background: var(--navy); color: #fff; align-self: flex-end; box-shadow: 0 1px 3px rgba(2, 58, 80, 0.18), 0 8px 20px rgba(2, 58, 80, 0.14); }
.chat-msg .chat-action { display: block; margin-top: 8px; color: var(--red); font-weight: 700; }
/* Helper destination buttons + hub (Oct 14, 2026) — small, tidy, house style. */
.chat-links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.chat-link-btn { display: inline-block; padding: 6px 12px; border: 1px solid var(--navy); border-radius: var(--radius-pill); color: var(--navy); background: #fff; font-size: 13px; font-weight: 600; text-decoration: none; }
.chat-link-btn:hover { background: var(--navy); color: #fff; }
.chat-hub { align-self: stretch; background: #fff; border: 1px solid rgba(2, 58, 80, 0.08); border-radius: var(--radius-md); box-shadow: 0 1px 3px rgba(2, 58, 80, 0.10), 0 8px 20px rgba(2, 58, 80, 0.07); padding: 10px 12px; }
.chat-hub-cat { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted, #6b7280); margin: 10px 0 6px; }
.chat-hub-cat:first-child { margin-top: 0; }
.chat-hub-row { display: flex; flex-wrap: wrap; gap: 6px; }
.chat-hub-item { display: inline-flex; align-items: center; gap: 2px; }
.chat-hub-chip { border: 1px solid var(--navy); color: var(--navy); background: #fff; border-radius: var(--radius-pill); padding: 6px 11px; font-size: 13px; cursor: pointer; font-family: inherit; }
.chat-hub-chip:hover { background: var(--navy); color: #fff; }
.chat-hub-open { color: var(--red); font-weight: 700; text-decoration: none; padding: 4px 5px; font-size: 14px; }
.chat-chips { display: flex; gap: 6px; overflow-x: auto; padding: 8px 12px; }
.chat-chips button {
  flex-shrink: 0;
  border: 1px solid var(--navy);
  color: var(--navy);
  background: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  min-height: 40px;
}
.chat-form { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--border); }
.chat-form input { flex: 1; border: 2px solid var(--border); border-radius: var(--radius-pill); padding: 10px 16px; font-size: 15px; min-height: 44px; }

/* ---------- Toast / modal ---------- */
#toast-root { position: fixed; bottom: 110px; left: 50%; transform: translateX(-50%); z-index: 2000; display: flex; flex-direction: column; gap: 8px; width: min(420px, calc(100vw - 32px)); }
.toast { background: var(--navy); color: #fff; padding: 14px 18px; border-radius: var(--radius-md); box-shadow: var(--shadow-lg); font-size: 15px; animation: fadein 0.2s; }
.toast.error { background: var(--danger); }
.toast.success { background: var(--green); }
#modal-root .modal-backdrop { position: fixed; inset: 0; background: rgba(1,30,44,.55); backdrop-filter: blur(8px) saturate(1.05); -webkit-backdrop-filter: blur(8px) saturate(1.05); z-index: 1500; display: flex; align-items: center; justify-content: center; padding: 16px; }
.modal { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 24px; width: min(520px, 100%); max-height: 90vh; overflow-y: auto; box-shadow: var(--shadow-lg); }

/* ---------- Misc ---------- */
.loading { text-align: center; padding: 48px 16px; color: var(--muted); }
.spinner { width: 40px; height: 40px; border: 4px solid var(--border); border-top-color: var(--red); border-radius: 50%; margin: 0 auto 16px; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.empty { text-align: center; padding: 48px 16px; color: var(--muted); }
.empty .big { font-size: 44px; margin-bottom: 12px; }
.empty p { font-size: 12px; line-height: 1.5; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
.center { text-align: center; }
.mt { margin-top: 16px; }
.verification-checklist { list-style: none; padding: 0; margin: 0; }
.verification-checklist li { display: flex; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--border); min-height: 56px; }
.verification-checklist li:last-child { border-bottom: none; }
.check-icon { width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; flex-shrink: 0; }
.check-icon.done { background: var(--green); color: #fff; }
.check-icon.todo { background: var(--silver); color: var(--muted); }
/* ---------- Verification flow (Donald's Oct 20, 2026) ----------
   One step at a time: the current step's card animates in, finished
   steps collapse into the green-dot summary above it, and the bar
   shows percent complete. Same treatment as the list-a-tool flow. */
.vfy-progress-track { height: 8px; border-radius: 99px; background: var(--line, #e3e7ec); overflow: hidden; margin: 8px 0 4px; }
.vfy-progress-fill { height: 100%; background: var(--navy, #023A50); border-radius: 99px; transition: width .45s ease; }
.vfy-progress-fill.all-done { background: #43A002; }
@keyframes vfy-step-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.vfy-step-card { animation: vfy-step-in .32s ease both; }
.vfy-done-list li { min-height: 0; padding: 7px 0; }
.vfy-just-done { animation: vfy-step-in .32s ease both; }
.vfy-upnext { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.vfy-upnext .vfy-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); border: 1px solid var(--border); border-radius: 99px; padding: 4px 10px; }
@media (prefers-reduced-motion: reduce) {
  .vfy-step-card, .vfy-just-done { animation: none; }
  .vfy-progress-fill { transition: none; }
}
.review { border-bottom: 1px solid var(--border); padding: 12px 0; }
.review:last-child { border-bottom: none; }
.msg-list { display: flex; flex-direction: column; gap: 8px; width: 100%; min-width: 0; }
/* Donald's Oct 12, 2026 fix: the Messages page kept expanding past the device.
   Long unbroken message text forced the bubbles (and page) wider than the
   screen. Bubbles now wrap anywhere and can never exceed the card. */
.msg { max-width: 80%; padding: 10px 14px; border-radius: var(--radius-md); font-size: 15px; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.msg.mine { background: var(--navy); color: #fff; align-self: flex-end; }
.msg.theirs { background: var(--bg); border: 1px solid var(--border); align-self: flex-start; }
.msg .msg-time { font-size: 11px; opacity: 0.7; margin-top: 4px; }
.msg img { max-width: 100%; height: auto; }
.thread-row { display: flex; gap: 12px; padding: 14px; border-bottom: 1px solid var(--border); text-decoration: none; color: var(--text); align-items: center; min-height: 72px; min-width: 0; max-width: 100%; }
.thread-row > * { min-width: 0; }
.thread-row a { min-width: 0; }
.thread-row a > div { min-width: 0; overflow-wrap: anywhere; }
.thread-row .thread-main { flex: 1; min-width: 0; overflow: hidden; }
.thread-row .thread-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Messages page hard guard: never wider than the device (Donald's Oct 12 fix). */
#view:has(#msg-list) .page, #view:has(.thread-row) .page { overflow-x: clip; }
.chat-form input { min-width: 0; }
.thread-row:hover { background: var(--bg); }
table.data { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th, table.data td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--border); }
table.data th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.agreement-box { border: 2px solid var(--border); border-radius: var(--radius-md); padding: 16px; max-height: 300px; overflow-y: auto; font-size: 14px; background: #fff; margin-bottom: 12px; }
.agreement-box .agreement-full { white-space: pre-wrap; font-size: 13.5px; line-height: 1.55; }
.tabs { display: flex; gap: 4px; overflow-x: auto; border-bottom: 2px solid var(--border); margin-bottom: 16px; }
.tabs button { border: none; background: none; padding: 12px 18px; font-size: 15px; font-weight: 600; color: var(--muted); cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px; min-height: 48px; white-space: nowrap; }
.tabs button.active { color: var(--red); border-bottom-color: var(--red); }

/* Profile 7-section IA (Oct 2026): vertical section nav on desktop, horizontal scroll tabs on mobile */
.stat-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.stat-tiles .tile { text-align: center; }

/* Shared chart primitives (js/charts.js) — Mist style. */
.chart-legend { display: flex; flex-wrap: wrap; gap: 12px; margin: 6px 0 8px; font-size: 12px; color: var(--ink-soft, #4a5a64); }
.chart-legend span { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; }
.chart-legend-list { flex-direction: column; align-items: flex-start; gap: 6px; flex: 1; min-width: 180px; }
.funnel-step { margin-bottom: 10px; }
.avail-strip { display: grid; grid-template-columns: repeat(14, 1fr); gap: 4px; margin: 8px 0; }
.avail-cell { aspect-ratio: 1; border-radius: 4px; opacity: 0.85; }
.chart-cond { display: inline-flex; align-items: center; }
@media (min-width: 1024px) {
  .profile-body { display: grid; grid-template-columns: 200px 1fr; gap: 24px; align-items: start; }
  /* Column placement (Donald's Oct 16, 2026 laptop report): the DOM
     order in .profile-body is content first, section tabs second, so
     grid auto-placement was crushing ALL profile content into the
     200px column and sprawling the tabs across the wide one. Pin the
     tabs to the 200px rail they are styled for and give the content
     the flexible column. Desktop-only — phone/tablet never see this
     query, so their stacked layout is untouched. */
  .profile-body .profile-sections { grid-column: 1; grid-row: 1; }
  .profile-body > div:first-child { grid-column: 2; grid-row: 1; min-width: 0; }
  .profile-body #tab-body { min-width: 0; }
  .profile-sections { flex-direction: column; align-items: stretch; border-bottom: none; border-right: 2px solid var(--border); overflow-x: visible; margin-bottom: 0; }
  .profile-sections button { text-align: left; border-bottom: none; border-left: 3px solid transparent; margin-bottom: 0; margin-right: -2px; }
  .profile-sections button.active { border-bottom-color: transparent; border-left-color: var(--red); }
}

/* ==================== Responsive ==================== */

/* Tablet: 640px+ */
@media (min-width: 640px) {
  .tool-grid { grid-template-columns: repeat(2, 1fr); }
  .header-search { max-width: 560px; }
  #chat-panel { bottom: 96px; }
  #chat-fab { bottom: 24px; }
}
/* Widths where the bottom nav is still visible: lift the chat FAB
   above it so they never overlap. */
@media (min-width: 640px) and (max-width: 1279px) {
  #chat-fab { bottom: 112px; }
  #chat-panel { bottom: 188px; }
}

/* Desktop: 1024px+ — drawer overlays the full-screen map (Donald's pattern) */
@media (min-width: 1024px) {
  .list-panel.tool-drawer { width: min(440px, 94vw); }

  .tool-grid { grid-template-columns: repeat(2, 1fr); }
  .container { padding: 24px; }
  .tool-glass-card { margin: -64px 24px 0; }
  .sticky-cta { bottom: 16px; margin: 24px; }
  .tool-hero .photo-gallery img { height: 420px; }
  .detail-layout { display: grid; grid-template-columns: 1.4fr 1fr; gap: 24px; align-items: start; }
  .booking-layout { display: grid; grid-template-columns: 1fr 380px; gap: 24px; align-items: start; }
  .profile-layout { display: grid; grid-template-columns: 300px 1fr; gap: 24px; align-items: start; }
  .admin-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
/* Donald's order (Oct 2026): admin pages more user-friendly with visual data. */
.admin-section h2 { font-size: 18px; font-weight: 800; color: var(--mist-ink); letter-spacing: -0.02em; }
.kpi-card { transition: transform .18s var(--mist-ease), box-shadow .18s var(--mist-ease); }
.kpi-card:hover { transform: translateY(-2px); }
/* Donald's order (Oct 2026): admin uniform with profile page — centered,
   profile-style fonts, drop shadows that pop. */
#admin-body .card {
  box-shadow: 0 12px 32px rgba(38, 35, 30, 0.14), 0 3px 8px rgba(38, 35, 30, 0.10);
  transition: transform .18s var(--mist-ease), box-shadow .18s var(--mist-ease);
}
#admin-body .card:hover {
  box-shadow: 0 18px 44px rgba(38, 35, 30, 0.20), 0 4px 12px rgba(38, 35, 30, 0.12);
}
#admin-body h2, #admin-body h3 {
  text-shadow: 0 2px 12px rgba(38, 35, 30, 0.12);
  letter-spacing: -0.02em;
}
#admin-body .kpi-card {
  text-align: center;
  box-shadow: 0 14px 36px rgba(38, 35, 30, 0.16), 0 4px 10px rgba(38, 35, 30, 0.10);
}
#admin-body .btn-row { justify-content: center; }
#admin-body .admin-section > h2 { text-align: center; }
/* Donald's order (Oct 2026): merch/group-share page template — use for all
   pages except profile. Centered title, 12px description, tiny pills. */
.page-head-centered {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 12px; margin-bottom: 24px; width: 100%;
}
.page-head-centered h1 {
  margin: 0; width: 100%; text-align: center;
  text-shadow: 0 2px 12px rgba(38,35,30,.18);
}
.page-head-centered .page-desc {
  margin: 8px 0 0; font-size: 12px; text-align: center; color: var(--muted);
}
.page-head-centered .btn-row { justify-content: center; margin-top: 8px; }
/* Donald's order (Oct 2026): slide-out search pills smaller, organized,
   uniform font — 1/3 smaller than base. */
#hdr-search-panel .chip,
.search-group .chip {
  font-size: 10px;
  font-weight: 600;
  padding: 4px 10px;
  min-height: 24px;
  font-family: 'Inter', system-ui, sans-serif;
  letter-spacing: 0;
}
#hdr-search-panel .chip-row,
.search-group .chip-row {
  gap: 6px;
  align-items: center;
}
#hdr-search-panel .search-group-label,
.search-group .search-group-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 6px;
  font-family: 'Inter', system-ui, sans-serif;
}
#hdr-search-panel select,
.search-group select {
  font-size: 10px;
  padding: 4px 8px;
  border-radius: 999px;
  font-family: 'Inter', system-ui, sans-serif;
}
.page:not(.profile-page) > h1,
.page > div > h1:first-child {
  text-align: center;
  text-shadow: 0 2px 12px rgba(38,35,30,.18);
  letter-spacing: -0.02em;
}
.page:not(.profile-page) .page-desc { font-size: 12px; text-align: center; }
.garages-page h1 { font-size: 32px; } /* uniform title size (Donald's Oct 12, 2026 order) */
.garages-page p, .garages-page .muted { font-size: 11px; } /* was ~16px */
.garages-page .tool-card-title { font-size: 11px; }
.garages-page .tool-card-meta { font-size: 10px; }
.garages-page .tool-card-price { font-size: 12px; }
.garages-page input[type="search"] { font-size: 12px; }
/* Pills 60% smaller: base .btn 11px/6px14px/30px → ~4px/2px6px/12px */
.garages-page .btn { font-size: 4.5px; padding: 2px 6px; min-height: 12px; border-radius: 999px; line-height: 1.2; }
.garages-page .chip { font-size: 4.5px; padding: 2px 6px; border-radius: 999px; line-height: 1.2; }
.garages-page .badge { font-size: 4px; padding: 1px 4px; border-radius: 999px; }
}

/* Full header nav: 1280px+ — below this the header nav would crowd (10 items),
   so tablet-landscape keeps the hamburger + bottom nav instead. */
@media (min-width: 1280px) {
  #menu-toggle { display: none; }
  .header-nav { display: inline-flex; }
  #bottom-nav { display: none; }
  #view { padding-bottom: 0; }
  #site-footer { padding-bottom: 24px; }
}

/* Large desktop: 1440px+ */
@media (min-width: 1440px) {
  .container { max-width: 1360px; }
  .tool-grid { grid-template-columns: repeat(3, 1fr); }
  .list-panel.tool-drawer { width: min(480px, 94vw); }
  .admin-grid { grid-template-columns: repeat(3, 1fr); }
  body { font-size: 17px; }
}

/* TV: 1920px+ — readable from the couch */
@media (min-width: 1920px) {
  :root { --header-h: 76px; }
  body { font-size: 20px; }
  .container { max-width: 1600px; padding: 32px; }
  .brand-logo { height: 52px; }
  .header-nav a { font-size: 19px; padding: 14px 20px; }
  .header-search input { height: 54px; font-size: 19px; }
  .tool-grid { grid-template-columns: repeat(4, 1fr); gap: 20px; }
  .tool-card-title { font-size: 20px; }
  .tool-card-price { font-size: 22px; }
  .btn { font-size: 20px; padding: 18px 36px; min-height: 60px; }
  .btn-sm { font-size: 17px; min-height: 52px; }
  .card { padding: 24px; }
  .field label { font-size: 18px; }
  .field input, .field select, .field textarea { font-size: 19px; min-height: 60px; }
  .list-panel.tool-drawer { width: min(520px, 94vw); }
  .price-line { font-size: 36px; }
  h1 { font-size: 32px; }
  h2 { font-size: 30px; }
  /* TV remote/keyboard: extra-clear focus */
  :focus-visible { outline-width: 5px; outline-offset: 4px; }
}

/* Coarse pointers (touch): roomy targets, no hover-only content */
@media (pointer: coarse) {
  .btn, .chip, .tabs button { min-height: 48px; }
  .tool-card:hover { transform: none; }
}
/* Fine pointers: hover states */
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: var(--red-dark); }
  .thread-row:hover { background: var(--bg); }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Small phones: tighten */
@media (max-width: 380px) {
  .header-search input { font-size: 14px; }
  .btn { padding: 12px 20px; }
  .tool-hero .photo-gallery img { height: 260px; }
}

/* In-app voice calls */
.btn-danger { background: #D92D20; color: #fff; }
.btn-danger:hover { background: #b32519; }
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(1,30,44,.55); z-index: 1500;
  backdrop-filter: blur(8px) saturate(1.05); -webkit-backdrop-filter: blur(8px) saturate(1.05);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}

/* "More features" toggle rows */
.feat-row { display: flex; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--border); cursor: pointer; }
.feat-row:first-of-type { border-top: none; }
.feat-icon { font-size: 24px; flex-shrink: 0; }
.feat-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.switch { position: relative; display: inline-block; width: 48px; height: 28px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .knob { position: absolute; inset: 0; border-radius: 14px; background: #cdd5dc; transition: background .2s; }
.switch .knob::before { content: ""; position: absolute; width: 22px; height: 22px; left: 3px; top: 3px; border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.25); }
.switch input:checked + .knob { background: #43A002; }
.switch input:checked + .knob::before { transform: translateX(20px); }
.switch input:disabled + .knob { opacity: .5; }

/* Print: clean admin reports (and any page). Hidden on screen. */
.print-only { display: none; }
@media print {
  /* Hide chrome: site header/nav, tab bars, all buttons, chat, toasts, modals */
  #site-header, .tabs, button, .btn, #chat-fab, #chat-panel, #toast-root, .modal-backdrop { display: none !important; }
  /* Printed report header line */
  .print-only { display: block !important; font-size: 15px; font-weight: 700; color: #000; margin-bottom: 12px; border-bottom: 2px solid #000; padding-bottom: 8px; }
  /* Dark text on white, no shadows */
  body, .container, .page, .card { background: #fff !important; color: #000 !important; box-shadow: none !important; }
  .page, .page * { color: #000 !important; }
  .card { border: 1px solid #ccc; break-inside: avoid; margin-bottom: 12px; }
  h1, h2, h3 { color: #000 !important; }
  a { color: #000 !important; text-decoration: none; }
  /* Tables: full width, never clip, never split a row across pages */
  .table-scroll { overflow: visible; }
  table.data { width: 100%; font-size: 12px; }
  table.data tr { break-inside: avoid; }
  table.data th, table.data td { border-bottom: 1px solid #ccc; }
  /* KPI grid prints as columns */
  .kpi-row { break-inside: avoid; }
}

/* Icon button (phone on public profiles, etc.) */
.icon-btn { display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px; border-radius:20px; background:var(--mist-card,#fff); border:1px solid var(--hairline,#E8E4DC); text-decoration:none; }
.icon-btn:hover { background:var(--bg,#F7F5F1); }

/* Notifications center */
.bell-link { position: relative; }
.notif-badge {
  position: absolute; top: -6px; right: -8px;
  min-width: 18px; height: 18px; padding: 0 5px;
  background: #F6040C; color: #fff; border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}
/* Phone bell (Oct 18, 2026): header-level notifications bell shown only
   below 1024px — the nav bell's parent (.header-nav) is display:none
   there. At ≥1024px the nav bell serves, so this one stays display:none.
   The [hidden] auth gate (display:none !important) still wins whenever
   the member is signed out. */
.phone-bell { display: none; }
@media (max-width: 1023px) {
  .phone-bell {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; min-width: 44px; min-height: 44px; flex-shrink: 0;
    border-radius: var(--radius-pill);
    font-size: 19px; line-height: 1; text-decoration: none; color: var(--text);
  }
  .phone-bell:active { background: rgba(26, 29, 33, 0.06); }
}
.notif-card { cursor: pointer; }
.notif-card .notif-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: #cdd5dc; margin-top: 4px; flex-shrink: 0;
}
.notif-card.unread .notif-dot { background: #F6040C; }
.notif-card.unread { border-left: 3px solid #F6040C; }
/* Per-notification clear (✕) — Oct 18, 2026: every member can clear
   their own notifications, one at a time or all at once. */
.notif-clear {
  flex: none; width: 26px; height: 26px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid #dfe5ea; border-radius: 50%;
  background: rgba(255, 255, 255, .92); color: var(--muted);
  font-size: 12px; line-height: 1; cursor: pointer;
}
.notif-clear:hover { color: var(--red); border-color: var(--red); }
.notif-welcome { position: relative; }
.notif-welcome .notif-clear { position: absolute; top: 10px; right: 10px; z-index: 2; }

/* Horizontal content strips (Discover) — calm, uniform rhythm. */
.strip-wrap { margin: 20px 0; }
.strip-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
.strip-head h3 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
.strip-scroll {
  display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
}
.strip-card {
  flex: 0 0 200px; scroll-snap-align: start;
  border: 1px solid var(--hairline, #E8E4DC); border-radius: 12px;
  background: #fff; overflow: hidden; cursor: pointer;
}
.strip-card img { width: 100%; height: 110px; object-fit: cover; display: block; }
.strip-card .strip-body { padding: 8px 10px; }
.strip-card .strip-title { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.strip-card .strip-meta { font-size: 12px; color: #6E757D; }

/* Intent chips + scope toggle */
.intent-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.scope-toggle { display: inline-flex; border: 1px solid var(--hairline, #E8E4DC); border-radius: 20px; overflow: hidden; }
.scope-toggle button { border: 0; background: transparent; padding: 3px 12px; font-size: 12px; cursor: pointer; }
.scope-toggle button.active { background: #023A50; color: #fff; }

/* Bundle cards */
.bundle-savings { color: #43A002; font-weight: 700; font-size: 12px; }

/* ==================== Tablet & big-screen refinement (Oct 2026) ==================== */
/* Phone layout above is untouched. These rules only widen/enrich the experience
   on tablets, desktops, and TV browsers (mouse/touch — not remote-control apps). */

/* Tablet portrait (768–1023px): roomier grids, dashboards and drawers */
@media (min-width: 768px) and (max-width: 1023px) {
  .container { padding: 20px; }
  .admin-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .kpi-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .tool-hero .photo-gallery img { height: 360px; }
  .modal { width: min(560px, 100%); }
  .detail-layout .tool-glass-card { margin-left: 20px; margin-right: 20px; }
  /* Discover: dock the tool list beside the map (side-by-side) instead of
     overlaying it — the drawer becomes a static side panel, the pull-tab,
     scrim, and close button are hidden at this width. */
  .discover-layout { display: flex; }
  .map-wrap { position: relative; inset: auto; flex: 1 1 auto; min-width: 0; }
  .list-panel.tool-drawer {
    position: relative; inset: auto; transform: none;
    flex: 0 0 min(400px, 46%); width: auto; max-height: none;
    border-radius: 0; border-left: 1px solid var(--border);
    box-shadow: none; z-index: 2;
  }
  .drawer-toggle, .drawer-scrim, .list-panel.tool-drawer .drawer-close { display: none; }
}

/* (Retired Oct 11, 2026: nothing search-related floats over the map — the
   header search is the single entry point. The phone-width drawer-tab rule
   that lived under .discover-search was already dead; removed.) */

/* Readability caps for wide screens: chat and prose stay comfortable to read */
@media (min-width: 1024px) {
  #view:has(#msg-list) .container { max-width: 880px; }
  #view:has(.agreement-box) .container { max-width: 880px; }
}

/* Large desktop: 1440px+ — booking form stays focused, hero gets presence */
@media (min-width: 1440px) {
  .booking-layout { grid-template-columns: minmax(0, 820px) 380px; justify-content: center; }
  .tool-hero .photo-gallery img { height: 480px; }
}

/* TV: 1920px+ — couch-readable pins, strips and hero */
@media (min-width: 1920px) {
  .price-pin { font-size: 15px; padding: 8px 14px; }
  .strip-card { flex: 0 0 240px; }
  .strip-card img { height: 130px; }
  .tool-hero .photo-gallery img { height: 540px; }
  .msg { font-size: 17px; }
  .chat-msg { font-size: 17px; }
}

/* Coarse pointers (touch tablets): every target 44px+ */
@media (pointer: coarse) {
  .icon-btn { width: 44px; height: 44px; }
  .scope-toggle button { min-height: 34px; font-size: 13px; }
  .strip-head a { min-height: 44px; display: inline-flex; align-items: center; }
  .filters-panel .chip { min-height: 44px; }
}

/* Shopping cart link + count badge in the global header (visible on every page). */
.cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  color: var(--mist-red, #F6040C);
  flex-shrink: 0;
}
.cart-link svg { width: 24px; height: 24px; }
.cart-badge {
  position: absolute; top: -4px; right: -6px;
  min-width: 18px; height: 18px; padding: 0 5px;
  background: #F6040C; color: #fff; border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}

/* Language picker (🌐) — compact header select + settings row. */
.lang-picker { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; }
.lang-picker select {
  border: 1px solid var(--border, #e5e7eb); border-radius: 8px; background: #fff;
  font-size: 13px; padding: 4px 6px; max-width: 110px; cursor: pointer;
}
.lang-picker-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lang-picker-row select {
  border: 1px solid var(--border, #e5e7eb); border-radius: 8px; background: #fff;
  font-size: 14px; padding: 8px 10px; cursor: pointer;
}

/* ---------- Offline browsing (Oct 2026) ---------- */
#offline-bar {
  background: #023A50;
  color: #fff;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 12px;
  position: sticky;
  top: 0;
  z-index: 2000;
}
#offline-bar[hidden] { display: none; }
.offline-notice {
  background: #FFF7E6;
  border: 1px solid #FBA200;
  color: #7A5200;
  border-radius: 10px;
  padding: 10px 14px;
  margin: 12px 0;
  font-size: 14px;
  text-align: center;
}

/* ---- Merch Store (premium retail) ---- */
.merch-collection { font-size: 1.25rem; font-weight: 800; margin: 28px 0 4px; }
.merch-collection:first-of-type { margin-top: 8px; }
.merch-card { display: flex; flex-direction: column; padding: 18px; }
.merch-card-link { text-decoration: none; color: inherit; display: block; }
.merch-card-link h3 {
  font-size: 1.06rem; font-weight: 650; letter-spacing: -0.01em;
  margin: 16px 0 6px;
}
.merch-img {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, #F7F7F8 0%, #ECEEF1 100%);
  border-radius: 16px;
  aspect-ratio: 4 / 3;
  margin-bottom: 4px;
}
.merch-img img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .6s cubic-bezier(.2,.6,.2,1);
}
@media (hover: hover) {
  .merch-card-link:hover .merch-img img { transform: scale(1.045); }
}
.merch-hero { padding: 0; overflow: hidden; }
.merch-img-lg { aspect-ratio: 1 / 1; border-radius: 20px; margin-bottom: 0; }
.merch-desc { min-height: 60px; line-height: 1.55; }
.merch-buy { margin-top: auto; }
/* Showcase products (not yet priced): calm 12px muted line in place of a
 * price — never an invented price, never a buy button. */
.merch-soon { font-size: 12px; color: var(--muted); margin: 0; }
/* Merch grid sponsored cell (Donald's Oct 13, 2026): the amber sponsored
 * card fills its grid cell exactly like a product card — the grid owns the
 * spacing, so the card's own vertical margins come off inside the cell. */
.merch-ad-cell { display: flex; flex-direction: column; min-width: 0; }
.merch-ad-cell .ad-card { flex: 1 1 auto; width: 100%; height: auto; margin: 0; }
/* Merch view switcher (Donald's Oct 13, 2026): one small segmented pill —
 * Grid / Slide / List — centered in the store header. */
.merch-view-switch {
  display: inline-flex; gap: 2px; margin-top: 14px;
  background: var(--card); border: 1px solid var(--border); border-radius: 999px; padding: 3px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 8px 20px rgba(2, 32, 71, 0.10);
}
.merch-view-switch button {
  border: 0; background: transparent; padding: 6px 16px; border-radius: 999px;
  font: 600 12px 'Inter', sans-serif; color: var(--muted); cursor: pointer;
}
.merch-view-switch button.on {
  background: var(--navy); color: #fff;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.12), 0 6px 14px rgba(2, 32, 71, 0.18);
}
/* Classy layered drop shadows (Donald's Oct 13, 2026 — "I love drop
 * shadow"): every merch card, slide and row carries the navy-tinted
 * layered shadow of the storefront cards, with a gentle lift on hover. */
.merch-card {
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 14px 34px rgba(2, 32, 71, 0.13);
  transition: box-shadow .18s ease, transform .18s ease;
}
@media (hover: hover) {
  .merch-card:hover {
    box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 20px 44px rgba(2, 32, 71, 0.18);
    transform: translateY(-2px);
  }
}
.merch-hero { box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 14px 34px rgba(2, 32, 71, 0.13); }
/* Slide view: horizontal snap rail — one prominent card, peek of the next.
 * Extra rail padding gives the drop shadows room to breathe. */
.merch-rail {
  display: flex; gap: 16px; overflow-x: auto;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  padding: 20px 4px 26px; margin: -8px -4px 0;
}
.merch-rail::-webkit-scrollbar { display: none; }
.merch-slide {
  flex: 0 0 min(84%, 340px); scroll-snap-align: center;
  display: flex; flex-direction: column; padding: 18px;
  background: var(--card); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 10px 26px rgba(2, 32, 71, 0.10);
  transition: box-shadow .25s ease;
}
.merch-slide.is-active {
  box-shadow: 0 2px 6px rgba(2, 32, 71, 0.10), 0 24px 48px rgba(2, 32, 71, 0.22);
}
.merch-slide .merch-desc { min-height: 0; }
.merch-slide-ad { padding: 0; border: 0; background: transparent; }
.merch-slide-ad .merch-ad-cell { flex: 1; }
/* List view: elegant full-width rows — photo left, name/description right. */
.merch-list { display: flex; flex-direction: column; gap: 12px; }
.merch-row {
  display: flex; align-items: center; gap: 8px; padding: 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 12px 28px rgba(2, 32, 71, 0.12);
  transition: box-shadow .18s ease, transform .18s ease;
}
@media (hover: hover) {
  .merch-row:hover {
    box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 18px 40px rgba(2, 32, 71, 0.17);
    transform: translateY(-2px);
  }
}
.merch-row-link { display: flex; align-items: center; gap: 14px; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.merch-row-img { width: 88px; height: 88px; flex: 0 0 88px; object-fit: cover; border-radius: 14px; background: #F1F2F4; }
.merch-row-body { flex: 1; min-width: 0; }
.merch-row-body h3 { font-size: 1rem; font-weight: 650; letter-spacing: -0.01em; margin: 0 0 4px; }
.merch-row-desc { margin: 0 0 6px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.merch-row .merch-soon, .merch-row .merch-price { margin: 0; }
.merch-row .merch-buy { margin-top: 0; flex: 0 0 auto; }
.merch-list-ad { display: flex; }
.merch-list-ad .merch-ad-cell { flex: 1; }
/* Storefront view switcher (Donald's Oct 13, 2026: "same as merch") —
 * one small segmented pill above the storefront's tools. */
.sf-view-switch {
  display: inline-flex; gap: 2px; margin-top: 10px;
  background: var(--card); border: 1px solid var(--border); border-radius: 999px; padding: 3px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 8px 20px rgba(2, 32, 71, 0.10);
}
.sf-view-switch button {
  border: 0; background: transparent; padding: 6px 16px; border-radius: 999px;
  font: 600 12px 'Inter', sans-serif; color: var(--muted); cursor: pointer;
}
.sf-view-switch button.on {
  background: var(--navy); color: #fff;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.12), 0 6px 14px rgba(2, 32, 71, 0.18);
}
/* Storefront tools: the classy layered navy drop shadow on every card
 * and row in every view, with the gentle hover lift. */
#pub-tools .tool-card {
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 14px 34px rgba(2, 32, 71, 0.13);
}
@media (hover: hover) {
  #pub-tools .tool-card:hover {
    box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 20px 44px rgba(2, 32, 71, 0.18);
  }
  #pub-tools .tool-row:hover {
    box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 18px 40px rgba(2, 32, 71, 0.17);
  }
}
#pub-tools .tool-row {
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 12px 28px rgba(2, 32, 71, 0.12);
}
/* Storefront Slide view: horizontal snap rail — one prominent tool
 * card, peek of the next; the centered card's shadow deepens. */
.sf-rail {
  display: flex; gap: 16px; overflow-x: auto;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  padding: 20px 4px 26px; margin: -8px -4px 0;
}
.sf-rail::-webkit-scrollbar { display: none; }
.sf-slide { flex: 0 0 min(84%, 340px); scroll-snap-align: center; min-width: 0; }
.sf-slide .tool-card {
  height: 100%;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 10px 26px rgba(2, 32, 71, 0.10);
  transition: box-shadow .25s ease;
}
.sf-slide.is-active .tool-card {
  box-shadow: 0 2px 6px rgba(2, 32, 71, 0.10), 0 24px 48px rgba(2, 32, 71, 0.22);
}
.sf-slide .tool-card img.tool-photo { height: 230px; }
/* Storefront List view: elegant full-width rows. */
.sf-list { display: flex; flex-direction: column; gap: 12px; }
/* The ONE sponsored card, designed into every storefront view: a grid
 * cell in Grid, a slide in Slide, a row in List — after the 4th tool. */
.sf-ad-cell { display: flex; flex-direction: column; min-width: 0; }
.sf-ad-cell .ad-card { flex: 1 1 auto; width: 100%; height: auto; margin: 0; }
.sf-slide-ad .sf-ad-cell { flex: 1; height: 100%; }
.sf-list-ad { display: flex; }
.sf-list-ad .sf-ad-cell { flex: 1; }
/* ---- Uniform product grid (Donald's Oct 14, 2026: "search what a grid
 * view is on the web, and redesign the grid view of the merch store and
 * storefront") ---- the web-standard product grid: neat rows and columns,
 * EVERY card the same size, one fixed 4:3 photo area (cover-cropped,
 * never stretched or letterboxed), a fixed text structure under it
 * (one-line name, one muted 12px line, then the price/status line),
 * uniform 12px gutters, responsive columns — 2 on phones, 3 on
 * tablet/desktop, 4 on wide screens. Text is clamped to its single line
 * so it can never change a card's size, and the ONE sponsored cell is
 * exactly one standard cell. Scoped to the merch store + the public
 * storefront tools only — Slide and List views are untouched. */
.merch-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 1024px) { .merch-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1440px) { .merch-grid { grid-template-columns: repeat(4, 1fr); } }
.merch-grid .merch-card { height: 100%; margin-bottom: 0; }
.merch-grid .merch-card-link { display: flex; flex-direction: column; flex: 1; }
.merch-grid .merch-card-link h3 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.merch-grid .merch-desc { min-height: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#pub-tools .tool-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; grid-auto-rows: 1fr; }
@media (min-width: 1024px) { #pub-tools .tool-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1440px) { #pub-tools .tool-grid { grid-template-columns: repeat(4, 1fr); } }
#pub-tools .tool-grid .tool-card { display: flex; flex-direction: column; height: 100%; }
#pub-tools .tool-grid .tool-card img.tool-photo { height: auto; aspect-ratio: 4 / 3; }
#pub-tools .tool-grid .tool-card-body { flex: 1; display: flex; flex-direction: column; }
#pub-tools .tool-grid .tool-card-meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#pub-tools .tool-grid .tool-card-price { margin-top: auto; padding-top: 6px; }
/* Grid sponsored cells (Donald's Oct 14, 2026): inside the uniform
 * grids the sponsored card stacks like its neighbors — media on top
 * at the grid's 4:3, text below at the cell's FULL width — instead of
 * squeezing into the sliver beside the horizontal card's thumbnail
 * (at phone width that sliver is ~50px and no text can fit neatly in
 * it). The creative is never cropped: contain on its navy stage,
 * exactly as on every other surface. Only the grid cells restack —
 * banner/feed/list/slide cards keep the horizontal layout.
 * FINAL shrink-to-fit rule (Oct 14, 2026, 11:16 AM CDT): the cell is
 * EXACTLY one standard cell — the copy zone below fills the space a
 * product cell leaves under its photo (flex, min-height 0, below)
 * and can never push the row taller; AdFit shrinks the type inside
 * the zone instead of growing the card. */
.merch-grid .merch-ad-cell a.ad-card,
#pub-tools .tool-grid .sf-ad-cell a.ad-card,
.merch-grid .merch-ad-cell .ad-rot-layer,
#pub-tools .tool-grid .sf-ad-cell .ad-rot-layer {
  flex-direction: column;
  align-items: stretch !important;
}
.merch-grid .merch-ad-cell .ad-card .ad-video-wrap,
#pub-tools .tool-grid .sf-ad-cell .ad-card .ad-video-wrap { width: 100%; }
.merch-grid .merch-ad-cell .ad-card img,
.merch-grid .merch-ad-cell .ad-card video,
#pub-tools .tool-grid .sf-ad-cell .ad-card img,
#pub-tools .tool-grid .sf-ad-cell .ad-card video {
  width: 100% !important;
  height: auto !important;
  /* 16/9 in the grids (Oct 21, 2026): the shorter media funds the
   * reaction row under the card so the cell keeps its one-cell
   * total; creatives are contained, never stretched or cropped. */
  aspect-ratio: 16 / 9;
  flex: none;
}
/* Shrink-to-fit copy zone inside the uniform grids: a FIXED height
 * equal to the copy block of the neighboring product cells (merch
 * product copy measures 112px under its photo; the storefront tool
 * body 103.5px), adjusted for the ad card's own padding/media
 * deltas so the sponsored cell totals EXACTLY one standard product
 * cell at any width — the zone can never push its row taller, and
 * AdFit shrinks the type inside it. */
.merch-grid .merch-ad-cell .ad-copy,
#pub-tools .tool-grid .sf-ad-cell .ad-copy {
  max-height: none;
  flex: none;
}
/* Oct 21, 2026 (Donald's distortion report): the ad's reaction row
 * rides UNDER the card inside these grid cells (the cells stack
 * vertically); its height is funded by the grid media switching to
 * 16/9 below, so the copy zone keeps its full budget and the
 * sponsored cell still totals exactly one standard product cell. */
.merch-grid .merch-ad-cell .ad-copy { height: 101px; }
#pub-tools .tool-grid .sf-ad-cell .ad-copy { height: 95px; }
/* The grid ad card is a flex column with a 12px gap between photo
 * and copy. In the merch grid the zone above absorbs it (101 = 113
 * copy budget − 12 gap). In the storefront grid the copy budget is
 * fully needed, so the 12px comes out of the card's top padding
 * instead — the photo sits near-flush, like the product cards' own
 * photos, and the sponsored cell still totals one product cell. */
#pub-tools .tool-grid .sf-ad-cell .ad-card { padding-top: 4px; }
/* Cover picker (personalize editor): the 10 built-in covers as calm
 * thumbnails with the same layered shadow; the active one is ringed. */
.sf-cover-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px; margin: 0 0 10px;
}
.sf-cover-thumb {
  padding: 0; border: 2px solid transparent; border-radius: 12px; overflow: hidden;
  background: none; cursor: pointer; line-height: 0;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.07), 0 8px 20px rgba(2, 32, 71, 0.10);
  transition: box-shadow .18s ease, transform .18s ease;
}
.sf-cover-thumb img { width: 100%; aspect-ratio: 16 / 5; object-fit: cover; display: block; }
.sf-cover-thumb.on {
  border-color: #023A50;
  box-shadow: 0 0 0 2px #F6040C, 0 2px 4px rgba(2, 32, 71, 0.10), 0 12px 26px rgba(2, 32, 71, 0.16);
}
@media (hover: hover) {
  .sf-cover-thumb:hover { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(2, 32, 71, 0.08), 0 14px 30px rgba(2, 32, 71, 0.16); }
  .sf-cover-thumb.on:hover { box-shadow: 0 0 0 2px #F6040C, 0 2px 4px rgba(2, 32, 71, 0.10), 0 16px 34px rgba(2, 32, 71, 0.20); }
}
.merch-detail { display: grid; grid-template-columns: 1fr; gap: 24px; }
@media (min-width: 760px) {
  .merch-detail { grid-template-columns: 1.05fr 1fr; align-items: start; gap: 40px; }
}
.merch-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.merch-price { font-weight: 700; font-size: 1.18rem; letter-spacing: -0.01em; color: var(--text); }
.merch-price-soon { font-weight: 400; font-size: .9em; color: var(--muted); }
.merch-thumb {
  width: 64px; height: 64px; flex: 0 0 64px;
  object-fit: cover; border-radius: 12px; background: #F1F2F4;
}
.merch-line { align-items: center; gap: 14px; padding: 10px 0; }
.merch-qty { display: flex; align-items: center; gap: 6px; }
.merch-check {
  width: 64px; height: 64px; margin: 8px auto 4px;
  border-radius: 50%; background: #E7F6EC; color: #1E7E34;
  font-size: 30px; font-weight: 700; line-height: 64px;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }

/* Manual & safety tips (Oct 2026) */
.safety-tips { margin: 8px 0 4px; padding-left: 20px; }
.safety-tips li { margin-bottom: 6px; }

/* ---- RateInline one-tap rating card (Oct 2026) ---- */
.rate-inline .rate-title { color: var(--navy); margin: 0 0 4px; }
.rate-stars { display: flex; gap: 6px; margin: 10px 0 4px; }
.rate-star {
  width: 56px; height: 56px; font-size: 40px; line-height: 1;
  background: none; border: none; cursor: pointer; padding: 0;
  color: #C9CDD4; transition: transform .12s ease, color .12s ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.rate-star.on { color: var(--red); } /* selected fill #F6040C */
button.rate-star:hover { transform: scale(1.1); }
button.rate-star:disabled { cursor: default; }
.rate-inline .rate-prompt { font-size: 15px; line-height: 1.45; margin: 8px 0 4px; }
.rate-inline .rate-success { color: var(--green); font-weight: 600; font-size: 15px; margin: 8px 0 0; }
.rate-inline.rate-done { border-left: 4px solid var(--green); }
.rate-inline.rate-highlight { box-shadow: 0 0 0 3px var(--red); }
/* small variant: optional condition-stars row inside proof modals */
.rate-stars.small .rate-star { width: 40px; height: 40px; font-size: 30px; }
.rate-stars.static .rate-star { cursor: default; }

/* ---- "Help us improve" suggestion channel (Mist styling) ---- */
.sug-chip {
  padding: 4px 10px;
  border: 1px solid var(--navy);
  color: var(--navy);
  background: #fff;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  min-height: 26px;
}
.sug-chip.active { background: var(--navy); color: #fff; border-color: var(--navy); }

/* "Enjoying Tools Nearby?" popup — Donald's aesthetic (Oct 12, 2026):
   small + organized, centered, soft red-glow badge, 12px muted copy,
   quiet text dismiss (no big outlined button). */
.sug-hero {
  width: 52px; height: 52px; margin: 0 auto 10px; border-radius: 50%;
  display: grid; place-items: center; font-size: 22px;
  background: rgba(246, 4, 12, 0.07);
  border: 1px solid rgba(246, 4, 12, 0.22);
  box-shadow: 0 0 0 6px rgba(246, 4, 12, 0.05), 0 6px 16px rgba(246, 4, 12, 0.12);
}
.sug-later {
  background: none; border: none; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--muted);
  padding: 6px 10px;
}
.sug-later:hover { color: var(--text); }

/* ---- Survey → Support chain (Donald's Oct 15, 2026 order) ----
   When the survey pop-up resolves (Send or Not now), it eases out and
   the Support Sov Expression LLC box eases in — never both visible at
   once. Since the pop-up sweep (Oct 21, 2026) the chain rides the
   shared UI.modal/UI.closeModal panel-token animations and no JS adds
   these classes anymore; the rules below are kept, retokenized onto
   the shared panel token, so any future use is on-token too. The global
   prefers-reduced-motion rule above already collapses these durations
   to ~0. */
#modal-root .modal-backdrop.tn-fade-out { opacity: 0; transition: opacity var(--tn-motion-panel, 360ms) var(--tn-ease-cross, ease); }
#modal-root .modal-backdrop.tn-fade-in { animation: tn-fade-in var(--tn-motion-panel, 360ms) var(--tn-ease-out, ease-out) both; }
@keyframes tn-fade-in { from { opacity: 0; } to { opacity: 1; } }
.sug-vote {
  background: #fff;
  border: 2px solid var(--navy);
  color: var(--navy);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
  line-height: 1.3;
  min-width: 44px;
  text-align: center;
}
.sug-vote.active { background: var(--red); border-color: var(--red); color: #fff; }
.sug-vote:disabled { opacity: 0.6; }

/* ==========================================================================
   Immersive app experience (Oct 2026, Donald's order — web-first direction).
   CSS-only motion: no animation libraries, no new dependencies.
   Mist design language only — light glassmorphism, red accents, no new palette.
   ========================================================================== */

/* ---------- Boot splash: branded, never blocks (tap dismisses, pwa.js) ---------- */
#boot-splash {
  position: fixed; inset: 0; z-index: 9999;
  background: var(--mist-navy);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  transition: opacity 0.3s ease-out;
}
#boot-splash.boot-hide { opacity: 0; pointer-events: none; }
#boot-splash img { border-radius: 24px; box-shadow: 0 8px 32px rgba(0,0,0,0.35); }
.boot-word {
  color: #fff; font-weight: 800; letter-spacing: 0.35em; font-size: 13px;
  text-indent: 0.35em;
}
.boot-shimmer {
  width: 120px; height: 4px; border-radius: 99px; overflow: hidden;
  background: rgba(255,255,255,0.15); position: relative;
}
.boot-shimmer::after {
  content: ""; position: absolute; inset: 0; width: 40%;
  background: var(--mist-red); border-radius: 99px;
  animation: boot-slide 0.9s ease-in-out infinite;
}
@keyframes boot-slide {
  0% { left: -40%; } 100% { left: 100%; }
}

/* ---------- Route transitions: quick slide/fade, app-like ---------- */
#view.view-enter { animation: view-in 0.22s ease-out; }
@keyframes view-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Bottom sheets: modals become sheets on phone widths ----------
   Matches the mobile app's sheet pattern. Backdrop tap still dismisses. */
@media (max-width: 640px) {
  #modal-root .modal-backdrop {
    align-items: flex-end;
    padding: 0;
  }
  #modal-root .modal {
    width: 100%;
    max-width: 100%;
    border-radius: 20px 20px 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    max-height: 92dvh;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
    animation: sheet-up 0.25s ease-out;
  }
  #modal-root .modal::before {
    /* drag-handle hint, pure CSS */
    content: ""; display: block;
    width: 40px; height: 4px; border-radius: 99px;
    background: var(--border); margin: -8px auto 12px;
  }
}
@keyframes sheet-up {
  from { transform: translateY(48px); opacity: 0.6; }
  to { transform: translateY(0); opacity: 1; }
}
/* Explicit sheet variant (UI.modal(html, {sheet:true})) — sheet on all widths */
#modal-root .modal-backdrop.sheet { align-items: flex-end; padding: 0; }
#modal-root .modal-backdrop.sheet .modal {
  width: 100%; max-width: 640px; margin: 0 auto;
  border-radius: 20px 20px 0 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  max-height: 92dvh;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
  animation: sheet-up 0.25s ease-out;
}

/* ---------- Press states: subtle scale/opacity feedback ---------- */
.btn { transition: transform 0.12s var(--mist-ease)-out, opacity 0.12s ease-out; }
.btn:active { transform: scale(0.97); opacity: 0.92; }
.card { transition: transform 0.12s var(--mist-ease)-out; }
a.card:active, .card.tappable:active { transform: scale(0.985); }
.chip { transition: transform 0.12s var(--mist-ease)-out, background 0.12s ease-out; }
.chip:active { transform: scale(0.95); }
#bottom-nav a { transition: transform 0.12s var(--mist-ease)-out, background 0.15s ease-out; }
#bottom-nav a:active { transform: scale(0.93); }
.price-pin { transition: transform 0.15s ease-out; }

/* ---------- Skeleton screens: no blank flashes while data loads ---------- */
.skel {
  position: relative; overflow: hidden;
  background: var(--border);
  border-radius: var(--radius-sm);
}
.skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.65), transparent);
  animation: skel-shimmer 1.2s ease-in-out infinite;
}
@keyframes skel-shimmer {
  0% { transform: translateX(-100%); } 100% { transform: translateX(100%); }
}
.skel-card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 12px; margin-bottom: 12px;
}
.skel-line { height: 14px; margin: 8px 0; }
.skel-line.short { width: 55%; }
.skel-img { height: 150px; border-radius: var(--radius-sm); margin-bottom: 10px; }
.skel-avatar { width: 44px; height: 44px; border-radius: 50%; }
.skel-row { display: flex; gap: 12px; align-items: center; }

/* ---------- Standing header Install button (Donald's Oct 14, 2026) ------
   Compact navy pill in the header's action cluster. pwa.js owns its
   visibility: only while the app is installable in this browser (Chrome
   prompt captured, or iPhone steps), never once installed/standalone. */
.header-install {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 40px; padding: 8px 14px;
  border: 1px solid rgba(2, 58, 80, 0.35); border-radius: 999px;
  background: linear-gradient(135deg, #04506E, var(--mist-navy));
  color: #fff; font-family: 'Inter', system-ui, sans-serif;
  font-size: 13.5px; font-weight: 700; letter-spacing: -0.01em;
  white-space: nowrap; cursor: pointer;
  box-shadow: 0 6px 18px rgba(2, 58, 80, 0.28), 0 2px 6px rgba(2, 58, 80, 0.18);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform .15s var(--mist-ease), box-shadow .15s var(--mist-ease);
}
.header-install:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(2, 58, 80, 0.32), 0 2px 6px rgba(2, 58, 80, 0.2); }
.header-install:active { transform: scale(0.96); }
.header-install[hidden] { display: none; }
@media (max-width: 480px) {
  .header-install { padding: 8px 11px; font-size: 12.5px; min-height: 38px; }
}

/* Download page logo hero: the official mark, front and center. */
.dl-hero { text-align: center; margin: 6px 0 2px; }
.dl-hero img { width: 104px; height: 104px; display: inline-block; border-radius: 24px; box-shadow: 0 14px 34px rgba(38, 35, 30, 0.22), 0 3px 8px rgba(38, 35, 30, 0.12); }

/* ---------- PWA install card: gentle, dismissible, never a modal ---------- */
#pwa-install-card {
  position: fixed; left: 12px; right: 12px;
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 2000;
  display: flex; align-items: center; gap: 12px;
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--border); border-radius: 20px;
  box-shadow: var(--mist-glass-shadow);
  padding: 12px 14px;
  transform: translateY(24px); opacity: 0;
  transition: transform 0.25s ease-out, opacity 0.25s ease-out;
}
#pwa-install-card.pwa-show { transform: translateY(0); opacity: 1; }
#pwa-install-card.pwa-hide { transform: translateY(24px); opacity: 0; }
#pwa-install-card img { border-radius: 12px; flex: none; }
#pwa-install-card .pwa-text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#pwa-install-card .pwa-text strong { font-size: 14px; }
#pwa-install-card .pwa-text span { font-size: 12px; color: var(--muted); }
#pwa-install-card .btn { flex: none; }
#pwa-install-card .pwa-main { flex: 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
#pwa-install-card .pwa-btns { display: flex; gap: 8px; flex-wrap: wrap; }
#pwa-install-card .pwa-steps { display: flex; flex-direction: column; gap: 6px; }
#pwa-install-card .pwa-steps[hidden] { display: none; }
#pwa-install-card .pwa-steps > div { display: flex; gap: 8px; align-items: baseline; font-size: 12px; color: var(--muted); }
#pwa-install-card .pwa-steps b { color: var(--navy); }
#pwa-install-card .pwa-step-n { flex: none; font-size: 13px; color: var(--navy); }

/* ---------- Download page (#/download): two honest ways to get the app ---------- */
.dl-grid { display: grid; grid-template-columns: 1fr; gap: 14px; margin-top: 16px; }
@media (min-width: 720px) { .dl-grid { grid-template-columns: 1fr 1fr; } }
.dl-card { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.dl-card img { border-radius: 14px; }
.dl-card h3 { margin: 0; }
.dl-card p { margin: 0; }
.dl-feats { display: flex; flex-direction: column; gap: 6px; text-align: left; font-size: 13px; color: var(--navy); margin: 2px 0 6px; }
.dl-steps { text-align: left; width: 100%; display: flex; flex-direction: column; gap: 6px; }
.dl-steps[hidden] { display: none; }
.dl-steps > div { display: flex; gap: 8px; align-items: baseline; font-size: 12px; color: var(--muted); }
.dl-steps b { color: var(--navy); }
.dl-steps .pwa-step-n { flex: none; font-size: 13px; color: var(--navy); }
.dl-soon { display: inline-block; padding: 9px 18px; border: 1.5px solid var(--navy); border-radius: 999px; color: var(--navy); font-weight: 700; font-size: 13.5px; background: var(--mist-glass, #fff); }
.dl-compare { display: flex; flex-direction: column; }
.dl-crow { display: grid; grid-template-columns: 1fr; gap: 2px; padding: 10px 2px; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.dl-crow:last-child { border-bottom: 0; }
.dl-clabel { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
@media (min-width: 720px) { .dl-crow { grid-template-columns: 110px 1fr 1fr; gap: 12px; align-items: baseline; } }

/* ---------- Touch targets: 44px minimum on small interactive elements ---------- */
.chip { min-height: 44px; display: inline-flex; align-items: center; }
.icon-btn, .chip-btn { min-width: 44px; min-height: 44px; }
#menu-toggle { min-width: 44px; min-height: 44px; }
#chat-fab { min-width: 56px; min-height: 56px; }
.suggest-dropdown button { min-height: 44px; }

/* ---------- Reduced motion: respect the OS setting everywhere ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  #view.view-enter { animation: none; }
  #modal-root .modal { animation: none; }
}

/* ---------- Fit the device — Donald's Oct 12, 2026 order ----------
   No page may grow wider than the device: no sideways scrolling anywhere,
   and the toolbar (header + bottom nav) always fits the screen whole. */
html, body { overflow-x: clip; max-width: 100%; }
img, video, canvas, iframe, svg { max-width: 100%; }
pre { max-width: 100%; overflow-x: auto; }
table { max-width: 100%; }
.tool-grid > *, .gs-type-grid > *, .pool-grid > *, .grid > *, .admin-grid > * { min-width: 0; }
.gs-type { min-width: 0; }
.card { min-width: 0; }
#site-header > * { min-width: 0; }
#bottom-nav { max-width: calc(100vw - 16px); }

/* Group Share text scale matches Merch (Donald's Oct 12, 2026 order):
   descriptions 12px muted, secondary text 13px muted — same as merch cards. */
.gs-tabs button { font-size: 13px; padding: 10px 12px; }
h1, h2, h3, strong { overflow-wrap: break-word; }
.card a, .thread-row a { overflow-wrap: anywhere; }

/* Universal header search dropdown (Donald's Oct 12, 2026 order). */
.suggest-head { padding: 10px 14px 2px; font-size: 6px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.suggest-group-row { display: flex; align-items: center; gap: 8px; padding: 8px 14px 10px; white-space: nowrap; overflow: hidden; }
.suggest-group-row .sg-name { font-weight: 600; font-size: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex-shrink: 1; }
.suggest-group-row .sg-meta { font-size: 6px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex-shrink: 2; }
.suggest-group-row .btn { flex-shrink: 0; }
.suggest-dropdown { max-height: 70vh; overflow-y: auto; }

/* Group Share cards match Merch cards (Donald's Oct 12, 2026 order):
   centered text, merch padding, merch text scale — nothing bigger. */
.gs-group-card { display: block; text-align: center; text-decoration: none; color: inherit; padding: 18px; margin-bottom: 12px; }
.gs-group-name { font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
.gs-group-meta { font-size: 12px; color: var(--muted); line-height: 1.55; margin-top: 4px; }

/* Search predictions as horizontal chips (Donald's Oct 12, 2026 order):
   words flow one after another as separate pieces, font size 9. */
.suggest-head { font-size: 9px; }
.suggest-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 12px 10px; }
.suggest-dropdown .s-chip {
  display: inline-flex; align-items: center; gap: 6px;
  width: auto; min-height: 0;
  font-size: 9px; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--bg); color: var(--text); cursor: pointer;
  white-space: nowrap;
}
.suggest-dropdown .s-chip:hover, .suggest-dropdown .s-chip:focus-visible { background: var(--card); border-color: var(--red); }
.suggest-dropdown .s-chip .s-title { font-size: 9px; }
.suggest-dropdown .s-chip .s-cat { font-size: 9px; color: var(--muted); }
.s-chip-group {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 9px; padding: 4px 4px 4px 10px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--bg);
}
.s-chip-group .sg-name { font-weight: 600; font-size: 9px; white-space: nowrap; }
.s-chip-group .sg-meta { font-size: 9px; color: var(--muted); white-space: nowrap; }
.s-chip-group .btn { flex-shrink: 0; }

/* ---------- The slide — search results (Donald's Oct 12, 2026 design,
   built from the Google-pattern research, in the Mist aesthetic) ---------- */
.list-panel.tool-drawer {
  background: var(--mist-glass);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
  box-shadow: -18px 0 50px rgba(38, 35, 30, 0.22), -4px 0 14px rgba(38, 35, 30, 0.12);
}
.drawer-head {
  position: relative;
  display: block;
  padding: 18px 44px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.drawer-head::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 70% 90% at 50% 0%, rgba(246, 4, 12, 0.07), transparent 70%);
  pointer-events: none;
}
.drawer-head-main { text-align: center; }
.drawer-head-main h2 {
  margin: 0; font-size: 16px; font-weight: 800; letter-spacing: -0.01em;
  text-shadow: 0 2px 12px rgba(38, 35, 30, 0.18);
}
.drawer-sub { margin-top: 3px; font-size: 11px; color: var(--muted); text-align: center; }
.drawer-head .drawer-close { position: absolute; top: 10px; right: 10px; }
.drawer-body { padding: 14px 14px calc(16px + env(safe-area-inset-bottom)); }

/* Result rows: one calm unit each — picture, name + facts, price.
   The gap BETWEEN rows (14px) is several times the gaps WITHIN a row. */
.result-list { display: flex; flex-direction: column; gap: 14px; }
.tool-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(38, 35, 30, 0.10), 0 2px 6px rgba(38, 35, 30, 0.06);
  text-decoration: none; color: inherit;
  transition: transform 0.25s var(--mist-ease, ease), box-shadow 0.25s var(--mist-ease, ease);
}
.tool-row:hover { transform: translateY(-2px); box-shadow: 0 18px 44px rgba(38, 35, 30, 0.16), 0 4px 10px rgba(38, 35, 30, 0.08); }
.tool-row-photo {
  width: 76px; height: 76px; flex-shrink: 0;
  border-radius: 12px; object-fit: cover; display: block;
  box-shadow: 0 4px 12px rgba(38, 35, 30, 0.14);
}
.tool-row-photo-empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--mist-card-2, #F1EEE8); font-size: 28px;
}
.tool-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tool-row-name { font-size: 13px; font-weight: 650; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.tool-row-badges .badge { vertical-align: 1px; }
.tool-row-meta { font-size: 11px; color: var(--muted); line-height: 1.45; overflow-wrap: anywhere; }
.tool-row-price { font-size: 15px; font-weight: 800; color: var(--red); letter-spacing: -0.01em; white-space: nowrap; flex-shrink: 0; }
.tool-row-price .rate-per { font-size: 10px; font-weight: 500; color: var(--muted); }

/* Sponsored group: one labeled block at the top of the results,
   separated by a divider and extra space — never sprinkled through
   the results. ALWAYS present (Donald's Oct 22, 2026 order): no Hide
   control, no collapse, no empty-hiding — loadAds fills the slot
   with a calm house card when no advertiser is running. */
#drawer-sponsored { margin-bottom: 20px; }
.sponsored-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 2px 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
#drawer-sponsored #top-ad-slot { border-bottom: 1px solid var(--border); padding-bottom: 16px; }
#drawer-sponsored .tool-card { box-shadow: 0 10px 30px rgba(38, 35, 30, 0.10); }
#drawer-sponsored .tool-photo { height: 128px; }
/* Ad videos + sponsored cards in the drawer keep the full treatment
 * (Donald's Oct 13, 2026 orders): the video shows its full 16:9 frame
 * (graphic ads keep the compact 128px strip above) and the sponsored
 * card keeps the darker pop shadow. */
#drawer-sponsored video.tool-photo { height: auto; }
#drawer-sponsored .tool-card.ad-card { box-shadow: 0 2px 4px rgba(120, 84, 10, 0.20), 0 18px 42px rgba(120, 84, 10, 0.36); }

/* Discover sponsored VIDEO ads — compact card (Donald's Oct 25, 2026
 * order: "Make the video ads space on Discover 1/3 smaller, make sure
 * the proportions are correct. No distorted video, make sure all text
 * fits"). When the Discover top slot's ad unit carries a video (single
 * ad, or any ad in the rotator pool — loadAds in discover.js adds
 * .ad-video-compact), the whole unit scales down to ~2/3: narrower
 * centered card, the video keeps its true 16:9 stage (width 100% +
 * aspect-ratio + contain — the Oct 13 full-frame rule is untouched),
 * and the copy zone shrinks proportionally while AdFit (app.js) keeps
 * doing the fitting under the Oct 14 FINAL rule — fonts step down,
 * text is never clipped, the SPONSORED badge never shrinks. The zone
 * is 86px rather than a strict 0.67× of 92px because at the compact
 * width the longest real copy wraps to a third description line —
 * the zone absorbs it instead of clipping it, and the narrower card
 * width keeps the card's total height at ~0.67× (measured 282.8px →
 * 193.2px at a 390px viewport, worst-case copy, harness-proven).
 * Graphic-only cycles and singles never get the class and render
 * exactly as before; inside a compact (video-carrying) cycle a
 * graphic layer shares the one frame, so its 128px strip scales
 * with the frame (cover fit, as always — no distortion). Scoped to
 * #drawer-sponsored: no other surface's ad card changes. */
#drawer-sponsored .ad-unit.ad-video-compact {
  width: 56%;
  margin-inline: auto;
}
#drawer-sponsored .ad-unit.ad-video-compact .tool-card-body {
  height: 86px;
  padding: 6px 12px;
}
#drawer-sponsored .ad-unit.ad-video-compact .tool-card-title {
  margin-bottom: 2px;
}
#drawer-sponsored .ad-unit.ad-video-compact img.tool-photo {
  height: 86px;
}
/* The reaction row keeps its one line at the compact width — the
 * Share button goes icon-only, the same treatment the merch and
 * storefront grid cells already use in tight cells (its accessible
 * name rides the button's aria-label/title, as everywhere). */
#drawer-sponsored .ad-unit.ad-video-compact .reaction-share-label {
  display: none;
}

/* Related searches: quiet plain text links under the results
   (links, not chips — Donald's Oct 22, 2026 no-pills order). */
#drawer-related { margin-top: 22px; }
.related-head { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); padding: 0 2px 8px; }
.related-links { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 0 2px; }
.related-links a { font-size: 13px; font-weight: 600; color: var(--navy, #023A50); }

/* Search result chips are LINKS (Donald's Oct 12, 2026 order): each result
   takes you straight to its page — tool, garage, group, or person. */
.suggest-dropdown a.s-chip { text-decoration: none; }
.suggest-dropdown a.s-chip:hover { border-color: var(--red); background: var(--card); }
.s-chip-group .sg-name-link { color: inherit; text-decoration: none; }
.s-chip-group .sg-name-link:hover { color: var(--red); text-decoration: underline; }

/* Account menu (Donald's Oct 12, 2026 pick) — SMALL and organized on
   purpose: compact rows, tiny section heads; users can zoom for bigger.
   The menu never runs past the screen (Donald's Oct 18, 2026 order):
   capped below the header, it scrolls its own length. */
#mobile-menu { width: min(264px, calc(100vw - 24px)); min-width: 0; padding: 8px;
  max-height: calc(100vh - var(--header-h) - 12px);
  max-height: calc(100dvh - var(--header-h) - 12px);
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
#mobile-menu .am-sec {
  font-size: 9px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--muted); padding: 8px 9px 3px;
}
#mobile-menu .am-sec[hidden] { display: none; }
#mobile-menu a.am-row {
  font-size: 12.5px; font-weight: 550; padding: 7px 9px; min-height: 32px; gap: 8px;
  border-radius: 10px;
}
#mobile-menu a.am-row[hidden] { display: none; }
#mobile-menu a.am-id {
  gap: 9px; padding: 8px 9px; min-height: 0; border-radius: 12px;
  background: rgba(255, 255, 255, 0.55); border: 1px solid var(--border); margin-bottom: 2px;
}
#mobile-menu a.am-id[hidden] { display: none; }
#mobile-menu .am-avatar {
  width: 34px; height: 34px; border-radius: 50%; object-fit: cover; flex: 0 0 auto;
  border: 1px solid var(--border);
}
/* W5: wrapper carries the Kit tier ring (classes set by fillAccountMenu). */
#mobile-menu .am-avatar-wrap { display: inline-flex; border-radius: 50%; flex: 0 0 auto; }
#mobile-menu .am-avatar-fallback {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--mist-cream, #F6F1E7); font-size: 16px;
}
#mobile-menu .am-avatar[hidden] { display: none; }
#mobile-menu .am-id-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
#mobile-menu .am-name { font-size: 13px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#mobile-menu .am-verify { display: flex; align-items: center; gap: 5px; font-size: 10px; color: var(--muted); font-weight: 500; }
#mobile-menu .am-dots { display: inline-flex; gap: 3px; }
#mobile-menu .am-dots i { width: 6px; height: 6px; border-radius: 50%; background: rgba(38, 35, 30, 0.18); }
#mobile-menu .am-dots i.on { background: #43A002; }
#mobile-menu .am-chev { color: var(--muted); font-size: 15px; }
#mobile-menu .am-guest { display: flex; flex-direction: column; gap: 3px; padding: 8px 9px 4px; }
#mobile-menu .am-guest[hidden] { display: none; }
#mobile-menu .am-guest strong { font-size: 13px; font-weight: 650; }
#mobile-menu .am-guest > span { font-size: 11px; color: var(--muted); }
#mobile-menu .am-guest-btns { display: flex; gap: 6px; margin-top: 5px; }
#mobile-menu .am-guest-btns a { min-height: 0; padding: 7px 14px; font-size: 12.5px; }
#mobile-menu a.am-cta {
  justify-content: center; margin: 2px 0 4px; padding: 9px 12px; min-height: 0;
  background: linear-gradient(135deg, #F6040C, #B80309); color: #fff;
  font-size: 13px; font-weight: 750; border-radius: 999px;
  box-shadow: 0 8px 20px rgba(246, 4, 12, 0.30);
}
#mobile-menu a.am-cta:hover { background: linear-gradient(135deg, #F6040C, #B80309); transform: translateY(-1px); }
#mobile-menu button#menu-install.am-install:not([hidden]) {
  width: calc(100% - 2px); margin: 6px 1px 2px; padding: 9px 12px;
  font-size: 12.5px; font-weight: 750; border-top: none;
}
#mobile-menu .am-logout {
  display: block; width: 100%; margin-top: 6px; padding: 8px 9px;
  background: none; border: 0; border-top: 1px solid var(--border); border-radius: 0 0 10px 10px;
  color: #B80309; font: 600 12.5px 'Inter', system-ui, sans-serif; text-align: left; cursor: pointer;
}
#mobile-menu .am-logout[hidden] { display: none; }
#mobile-menu .am-logout:hover { background: rgba(246, 4, 12, 0.06); }

/* Whole group search result is tappable (Donald's Oct 12, 2026 report). */
.s-chip-group[data-glink] { cursor: pointer; }

/* Competitor savings note (Donald's Oct 12, 2026) — small and gentle. */
.save-note {
  margin-top: 10px; padding: 9px 12px; border-radius: 12px;
  background: rgba(67, 160, 2, 0.08); border: 1px solid rgba(67, 160, 2, 0.28);
  font-size: 12px; line-height: 1.5; color: var(--text);
}

/* Profile actions row: group item (Donald's Oct 12, 2026 order) — NO pill,
   just a bigger people icon about the sign-out button's size + tiny label. */
.prof-group { display: inline-flex; flex-direction: column; align-items: center; gap: 1px; text-decoration: none; color: #023A50; padding: 2px 6px; }
.prof-group-icon { font-size: 18px; line-height: 1.05; filter: drop-shadow(0 2px 2px rgba(38,35,30,.35)); }
.prof-group-label { font-size: 10px; font-weight: 600; color: #6B6560; }

/* Profile actions row controls 30% smaller (Donald's Oct 12, 2026 order):
   Log out + Admin buttons shrink within the profile header row only —
   the group icon above went 25px -> 18px the same day. Text stays 9px
   for legibility; the shrink is in padding + height. */
.prof-actions .btn-sm { padding: 3px 7px; min-height: 16px; box-shadow: 0 2px 6px rgba(38,35,30,.28); }

/* Profile pictures 1/3 bigger (Donald's Oct 12, 2026 order): profile
   header photo 69px -> 92px. Scoped to the profile layout so list and
   menu avatars keep their sizes. */
.profile-layout .owner-row .avatar { width: 92px; height: 92px; }

/* Donald's rule (Oct 12, 2026): ALL informational / descriptive text —
   descriptions, hints, captions, meta lines, explanatory copy — is muted
   gray at 12px on every platform. Carried by the descriptive classes
   (.small, .page-desc, .field .hint, card/pool meta lines). Titles,
   names, prices, buttons, badges, and tabs keep their own sizes. */

/* Donald's order (Oct 12, 2026): ALL titles centered + uniform size on
   every platform (Inter everywhere; page title = 32px / 800 here). */
h1, h2 { text-align: center; }
h1 { font-size: 32px; font-weight: 800; letter-spacing: -0.5px; }

/* Result-slide groups + sponsored space (Donald's Oct 13, 2026 orders):
   group results appear in the slide as calm centered cards in the house
   aesthetic (same family as the group list cards) — name, ONE facts
   line, Tool Master with picture + established date. The sponsored slot
   is a single designed space; with no advertiser running it carries one
   quiet house card in the warm sponsored treatment. Never busy. */
#drawer-groups { margin: 2px 0 18px; }
.drawer-group-list { display: flex; flex-direction: column; gap: 10px; }
.drawer-group-card { display: block; text-align: center; background: var(--card); border: 1px solid var(--border); border-radius: 18px; padding: 14px 16px; box-shadow: 0 10px 24px rgba(38,35,30,.08); text-decoration: none; color: var(--text); transition: transform .18s ease, box-shadow .18s ease; }
.drawer-group-card:hover { transform: translateY(-1px); box-shadow: 0 14px 28px rgba(38,35,30,.12); }
.dgc-name { font-size: 15px; font-weight: 650; }
.dgc-meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.dgc-master { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 8px; font-size: 12px; color: var(--muted); }
.dgc-master img { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }
.dgc-ava { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--mist-bg-2); color: var(--navy); font-weight: 700; font-size: 10px; }
.ad-house-card { display: block; text-align: center; background: var(--amber-ad); border: 1px solid var(--amber-border); border-radius: 18px; padding: 16px; text-decoration: none; color: var(--text); }
.ad-house-title { font-size: 15px; font-weight: 650; margin-top: 8px; }
.ad-house-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.ad-house-link { font-size: 12px; font-weight: 600; color: var(--navy); margin-top: 8px; }

/* Capacity Watch (Donald's Oct 14, 2026): vertical thermometer meters
   in the Admin Performance tab. The fill rises bottom-to-top and takes
   the FULL column's gradient (green at the bottom → amber → red at
   the top) via a full-height gradient layer anchored inside the fill,
   so the color deepens as the level rises. 70% / 85% ticks sit beside
   each column. Classes are .capw- prefixed and additive only. */
.capw-card { margin-bottom: 16px; }
.capw-title { text-align: center; }
.capw-sub { text-align: center; margin: 2px 0 0; }
.capw-row { display: flex; flex-wrap: wrap; gap: 28px; justify-content: center; padding: 18px 4px 8px; }
.capw-meter { display: flex; gap: 14px; align-items: flex-end; padding: 12px 14px; border-radius: 16px; }
.capw-tight { box-shadow: 0 0 0 2px var(--amber-border), 0 12px 26px rgba(38,35,30,.10); }
.capw-colwrap { width: 86px; flex: none; }
.capw-col { position: relative; width: 56px; height: 170px; border-radius: 14px; background: #EFECE6; box-shadow: inset 0 2px 6px rgba(38,35,30,.14), 0 10px 22px rgba(38,35,30,.10); }
.capw-track { position: absolute; inset: 0; border-radius: 14px; opacity: .16; background: linear-gradient(to top, #43A002 0%, #7BCF25 40%, #FBA200 72%, #F6040C 100%); }
.capw-fill { position: absolute; left: 0; right: 0; bottom: 0; overflow: hidden; border-radius: 0 0 14px 14px; transition: height .6s ease; }
.capw-fillgrad { position: absolute; left: 0; right: 0; bottom: 0; height: 170px; background: linear-gradient(to top, #43A002 0%, #7BCF25 40%, #FBA200 72%, #F6040C 100%); }
.capw-tick { position: absolute; left: 0; right: 0; border-top: 2px dashed rgba(2,58,80,.45); }
.capw-tick span { position: absolute; left: 62px; top: 0; transform: translateY(-50%); font-size: 10px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.capw-data { display: flex; flex-direction: column; gap: 2px; min-width: 118px; padding-bottom: 2px; }
.capw-label { font-size: 13px; font-weight: 700; color: var(--navy); }
.capw-pct { font-size: 24px; font-weight: 800; line-height: 1.1; }
.capw-pct-ok { color: #43A002; }
.capw-pct-warn { color: #B7791F; }
.capw-pct-urgent { color: #F6040C; }
.capw-pct-unknown { color: var(--muted); }
.capw-line { margin: 0; }
.capw-chip { align-self: flex-start; margin-top: 6px; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.capw-chip-ok { background: #EAF5E2; color: #2F6B01; }
.capw-chip-warn { background: var(--amber-ad); color: #B7791F; }
.capw-chip-urgent { background: #FDE8E8; color: #B80309; }
.capw-chip-unknown { background: #EEEEEC; color: var(--muted); }
.capw-foot { text-align: center; margin: 10px 0 0; }
/* Weave Capacity Learning (Oct 18, 2026): learned trend + forecast
   lines and the upgrade-suggestion banner inside each meter's data
   block. Lines only — the meter row geometry (and its centering)
   is untouched. */
.capw-sugg { margin-top: 8px; padding: 8px 10px; border-radius: 10px; font-size: 12px; line-height: 1.45; text-align: left; }
.capw-sugg-watch { background: var(--amber-ad); color: #7A5200; box-shadow: inset 0 0 0 1px var(--amber-border); }
.capw-sugg-act { background: #FDEBD2; color: #8A4B00; box-shadow: inset 0 0 0 1px #E8A33D; }
.capw-sugg-urgent { background: #FDE8E8; color: #B80309; box-shadow: inset 0 0 0 1px #F0A3A8; }
.capw-sugg-why { opacity: .8; font-size: 11px; }
@media (max-width: 480px) {
  .capw-row { gap: 18px; }
  .capw-col { height: 140px; }
  .capw-fillgrad { height: 140px; }
  .capw-data { min-width: 104px; }
}
@media (prefers-reduced-motion: reduce) {
  .capw-fill { transition: none; }
}

/* ── Job Showcase (contractor pro storefront, Oct 14 2026) ──────────
   Before/after pairs side by side + work videos; calm grid, classy
   drop shadow, captions muted 12px. Only .showcase-* classes. */
.showcase-grid { display: grid; grid-template-columns: 1fr; gap: 14px; align-items: start; }
@media (min-width: 760px) { .showcase-grid { grid-template-columns: 1fr 1fr; } }
.showcase-card {
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--card);
  box-shadow: 0 6px 20px rgba(38, 35, 30, 0.10);
}
.showcase-pair { display: flex; }
.showcase-half { position: relative; flex: 1 1 50%; min-width: 0; }
.showcase-half + .showcase-half { border-left: 2px solid #fff; }
.showcase-tag {
  position: absolute; left: 8px; bottom: 8px;
  background: rgba(14, 17, 19, 0.72); color: #fff;
  font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
  padding: 3px 8px; border-radius: 999px;
}
.showcase-video { background: #0b0f11; aspect-ratio: 16 / 9; }
.showcase-video video { display: block; width: 100%; height: 100%; object-fit: contain; }
.showcase-caption { font-size: 12px; color: var(--muted); text-align: center; padding: 8px 10px 2px; }
.showcase-controls { justify-content: center; padding: 8px 10px 10px; margin-top: 0; }

/* ── Pilot area fence (Admin → Feature flags, Oct 2026) ────────────
   The map is the hero; calm spacing, centered title, muted 12px
   instructions, uniform pills and area rows. Only .pilot-* classes. */
.pilot-title { text-align: center; margin: 0 0 4px; }
.pilot-sub { text-align: center; margin: 0 auto 14px; max-width: 520px; }
.pilot-status { text-align: center; margin: 8px 0 0; }
.pilot-map {
  height: 340px; border-radius: 14px; overflow: hidden;
  box-shadow: 0 10px 30px rgba(38, 35, 30, .18);
  margin: 14px 0 16px; background: var(--mist-card-2);
}
@media (max-width: 640px) { .pilot-map { height: 260px; } }
.pilot-pills { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin: 0 0 14px; }
.pilot-pill {
  flex: 0 1 auto; border: 1px solid rgba(2, 32, 71, 0.18); background: #fff; color: var(--text);
  border-radius: 999px; padding: 4px 12px; min-height: 30px; cursor: pointer;
  font: 600 12px var(--font);
}
.pilot-pill.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.pilot-editor { max-width: 560px; margin: 0 auto; }
.pilot-editor .field { margin-bottom: 10px; }
.pilot-editor .field label { font-size: 13px; }
.pilot-results { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.pilot-result {
  text-align: left; border: 1px solid var(--border); background: #fff; border-radius: 10px;
  padding: 8px 12px; font: 600 13px var(--font); color: var(--text); cursor: pointer; width: 100%;
}
.pilot-result.on { border-color: var(--navy); background: #EEF4F6; }
.pilot-areas { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.pilot-area-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1px solid var(--border); border-radius: 999px; padding: 6px 8px 6px 14px; background: #fff;
}
.pilot-area-label { font-size: 13px; font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.pilot-remove {
  flex: none; width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--border);
  background: #fff; color: var(--red); font-size: 15px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.pilot-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--navy); border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(2, 58, 80, .45);
}

/* Admin Snapshot page (#/admin-snapshot) — the compiled one-page digest.
   House style: Inter, centered titles, muted 12px notes, classy cards
   with soft shadows, navy primary. */
.snap-actions { display: flex; gap: 8px; justify-content: center; margin: 0 0 14px; }
.snap-grid { display: grid; grid-template-columns: 1fr; gap: 14px; align-items: start; }
@media (min-width: 900px) {
  .snap-grid { grid-template-columns: 1fr 1fr; }
  .snap-card.wide { grid-column: 1 / -1; }
}
.snap-card { box-shadow: 0 8px 28px rgba(38, 35, 30, .12); }
.snap-h { margin: 0 0 10px; font-size: 17px; text-align: center; }
.snap-sub { margin: 14px 0 6px; font-size: 13px; font-weight: 700; color: var(--navy); }
.snap-kpis { display: flex; gap: 18px; justify-content: center; text-align: center; flex-wrap: wrap; }
.snap-big { font-size: 28px; font-weight: 800; color: var(--navy); }
.snap-rows { display: flex; flex-direction: column; gap: 5px; }
.snap-row { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; }
.snap-funnel-row { margin-bottom: 8px; }
.snap-funnel-top { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 3px; }
.snap-funnel-track { height: 8px; border-radius: 999px; background: #EEF1F3; overflow: hidden; }
.snap-funnel-fill { height: 100%; background: var(--navy); border-radius: 999px; }
@media print {
  .snap-actions { display: none !important; }
  .snap-grid { grid-template-columns: 1fr 1fr; }
}

/* Analytics mini-nav + Traffic page (#/admin-traffic, #/admin-insights)
   — one nav across Traffic · Snapshot · Insights · Download all
   (Donald's Oct 15, 2026: "Make things visual and easy to navigate").
   Same house style as the Snapshot block above. */
.analytics-nav {
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; align-items: center;
  margin: 0 auto 14px; max-width: 640px;
}
.anav-link {
  border: 1px solid rgba(2, 32, 71, 0.18); background: #fff; color: var(--text);
  border-radius: 999px; padding: 5px 14px; min-height: 30px;
  font: 600 12px var(--font); text-decoration: none;
  display: inline-flex; align-items: center;
}
.anav-link.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.anav-download {
  border: 1px solid var(--navy); background: var(--navy); color: #fff;
  border-radius: 999px; padding: 5px 14px; min-height: 30px; cursor: pointer;
  font: 700 12px var(--font);
}
.anav-download:disabled { opacity: .55; cursor: wait; }
.traffic-kpis { margin: 2px 0 12px; }
.traffic-layers { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin: 0 0 12px; }
.layer-chip {
  border: 1px solid rgba(2, 32, 71, 0.18); background: #fff; color: var(--muted, #666);
  border-radius: 999px; padding: 4px 12px; min-height: 30px; cursor: pointer;
  font: 600 12px var(--font); opacity: .55;
}
.layer-chip.on { color: var(--text); opacity: 1; border-color: var(--navy); box-shadow: 0 2px 8px rgba(38, 35, 30, .12); }
.traffic-detail { margin-top: 14px; box-shadow: 0 8px 28px rgba(38, 35, 30, .12); }
.traffic-detail .snap-row b { text-align: right; overflow-wrap: anywhere; }
.traffic-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.traffic-table th {
  text-align: left; font-size: 12px; color: var(--navy); padding: 6px 8px;
  border-bottom: 2px solid #EEF1F3; white-space: nowrap;
}
.traffic-table td { padding: 6px 8px; border-bottom: 1px solid #EEF1F3; vertical-align: top; }
.traffic-table tbody tr:hover { background: #F7FAFB; }
@media print {
  .analytics-nav { display: none !important; }
  .traffic-layers { display: none !important; }
}

/* Admin Online & Member Activity page (#/admin-activity) — super-admin
   only. Calm member cards with a label/value fact grid; reads cleanly
   at phone and desktop widths without wide tables. */
.act-card { box-shadow: 0 8px 28px rgba(38, 35, 30, .12); padding: 16px; margin-bottom: 14px; }
.act-member { padding: 10px 0; border-bottom: 1px solid #EEF1F3; }
.act-member:last-child { border-bottom: none; }
.act-member[data-member] { cursor: pointer; border-radius: 8px; }
.act-member[data-member]:hover { background: #F7FAFB; }
.act-member-head { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; }
.act-name { font-weight: 700; color: var(--navy); }
.act-facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 14px; margin-top: 8px; }
@media (min-width: 900px) { .act-facts { grid-template-columns: repeat(3, 1fr); } }
.act-fact-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #8A939A; }
.act-fact-value { font-size: 13px; font-weight: 600; color: var(--navy); margin-top: 1px; overflow-wrap: anywhere; }
.act-timeline { display: flex; flex-direction: column; gap: 4px; max-height: 420px; overflow-y: auto; }
.act-timeline-row { display: flex; gap: 10px; font-size: 13px; }
.act-timeline-time { color: #8A939A; white-space: nowrap; min-width: 118px; }

/* Admin Member Contacts page (#/admin-contacts) — calm controls above
   one classy table card; same house style as Snapshot. */
.contacts-controls { box-shadow: 0 8px 28px rgba(38, 35, 30, .12); padding: 16px; margin-bottom: 14px; }
.contacts-search-label { display: block; font-size: 12px; font-weight: 700; color: var(--navy); margin-bottom: 6px; text-align: center; }
.contacts-search-row { display: flex; gap: 8px; max-width: 560px; margin: 0 auto; }
.contacts-search-row .input { flex: 1; min-width: 0; }
.contacts-control-row { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; max-width: 560px; margin: 12px auto 0; }
.contacts-toggle { display: inline-flex; gap: 8px; align-items: center; font-size: 13px; font-weight: 600; cursor: pointer; }
.contacts-toggle input { width: 18px; height: 18px; accent-color: var(--navy); }
.contacts-counts { margin: 12px auto 0; }
.contacts-table-card { box-shadow: 0 8px 28px rgba(38, 35, 30, .12); padding: 6px 10px; }
.contacts-table td, .contacts-table th { white-space: nowrap; }
.contacts-table td[data-label="Name"], .contacts-table td[data-label="Email"] { white-space: normal; overflow-wrap: anywhere; }

/* Member Segments section on #/admin-contacts (Donald's Oct 15, 2026):
   headline stat cards, the plan × verification grid, and muted summary
   lines — same calm card language as the contacts table below it. */
.segments-card { box-shadow: 0 8px 28px rgba(38, 35, 30, .12); padding: 16px; margin-bottom: 14px; }
.segments-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 12px 0; }
@media (min-width: 720px) { .segments-stats { grid-template-columns: repeat(4, 1fr); } }
.segments-stat { border: 1px solid var(--border); border-radius: 10px; padding: 10px 8px; text-align: center; }
.segments-stat-num { font-size: 24px; font-weight: 800; color: var(--navy); line-height: 1.1; }
.segments-stat-label { font-size: 12px; color: #8A939A; margin-top: 2px; }
.segments-stat-sub { font-size: 12px; color: #8A939A; margin-top: 2px; }
.segments-grid td, .segments-grid th { white-space: nowrap; }
.segments-line { font-size: 12px; color: #8A939A; text-align: center; margin: 8px auto 0; max-width: 640px; }
/* Prices section (on #/admin-contacts, under Segments): first-party
   bucket bars + the one-listing lookup. */
.prices-buckets { max-width: 520px; margin: 10px auto 2px; }
.prices-bucket-row { display: flex; align-items: center; gap: 10px; margin: 6px 0; }
.prices-bucket-label { flex: 0 0 74px; font-size: 12px; color: #8A939A; text-align: right; }
.prices-bucket-track { flex: 1 1 auto; height: 12px; background: rgba(2, 58, 80, .08); border-radius: 6px; overflow: hidden; }
.prices-bucket-bar { display: block; height: 100%; background: var(--navy); border-radius: 6px; min-width: 0; }
.prices-bucket-count { flex: 0 0 34px; font-size: 12px; font-weight: 700; color: var(--navy); }
.prices-lookup { max-width: 520px; margin: 16px auto 0; }
.prices-lookup .contacts-search-label { display: block; text-align: center; margin-bottom: 6px; }
.prices-timeline-head { text-align: center; margin-top: 14px; }

/* Gentle verification guidance card on the profile overview
   (Donald's Oct 15, 2026): dismissible, snoozes a week, never a modal. */
.verify-guide-card { border-left: 4px solid var(--green, #43A002); }
@media (max-width: 560px) {
  .contacts-search-row { flex-direction: column; }
  .contacts-search-row .btn { width: 100%; }
  .contacts-control-row { justify-content: center; }
}

/* Member card + perks (Oct 15, 2026) — each tier has its OWN color
   identity, recognizable at a glance across a counter: Plus is the
   brand NAVY gradient card (white ink); Contractor Pro is a deep
   GOLD gradient card (navy ink). Same face, same layout — only the
   color identity differs. The logo ships on its own white tile, so
   it stays crisp on both. */
.member-card {
  background: linear-gradient(135deg, #023A50 0%, #012636 100%);
  color: #fff;
  border-radius: 18px;
  padding: 16px 18px;
  box-shadow: 0 14px 34px rgba(2, 41, 59, 0.35);
  max-width: 460px;
  margin: 10px auto;
}
.member-card--pro {
  background: linear-gradient(135deg, #F9C74F 0%, #F5A623 40%, #E0950A 72%, #B97A0F 92%, #9A6605 100%);
  color: #023A50;
  border: 1.5px solid rgba(138, 90, 0, 0.55);
  box-shadow: 0 14px 34px rgba(138, 90, 0, 0.38);
}
.member-card--locked { opacity: 0.92; }
/* Dual holders (both tiers, or an admin on the waiver): the two
   card faces sit side by side on wide surfaces and stack on narrow
   ones. A single card keeps its centered 460px measure. */
.mc-cards { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.mc-cards .member-card { flex: 1 1 340px; margin: 0; }

/* Card slider + tap-to-popup (Oct 15, 2026 — Donald's "organize the
   card better" order). Multi-card holders (dual holders, and admins
   who hold every tier on the waiver) slide between faces — one card
   at a time, brand dots below — instead of a stacked wrap. Tapping
   ANY card pops it up full-focus: enlarged, centered, the page
   behind it blurred and dimmed, QR bigger for an easy scan. */
.mc-pickable { cursor: pointer; }
.mc-pickable:focus-visible { outline: 3px solid #029DAA; outline-offset: 3px; border-radius: 18px; }
.mc-slider { max-width: 472px; margin: 2px auto; }
.mc-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; border-radius: 18px; padding: 14px 6px 20px; }
.mc-track::-webkit-scrollbar { display: none; }
.mc-slide { flex: 0 0 100%; scroll-snap-align: center; padding: 0 2px; box-sizing: border-box; }
.mc-slide .member-card { margin: 0 auto; }
.mc-dots { display: flex; justify-content: center; gap: 7px; margin-top: 2px; }
.mc-dot { width: 8px; height: 8px; border-radius: 999px; border: 0; padding: 0; background: #CECFD4; cursor: pointer; transition: width .18s ease, background .18s ease; }
.mc-dot--on { width: 20px; background: #023A50; }
.mc-pop-backdrop { position: fixed; inset: 0; z-index: 2100; background: rgba(1, 30, 44, .55); backdrop-filter: blur(8px) saturate(1.05); -webkit-backdrop-filter: blur(8px) saturate(1.05); display: flex; align-items: center; justify-content: center; padding: 18px; }
.mc-pop-backdrop[hidden] { display: none; }
.mc-pop { position: relative; width: min(92vw, 520px); }
.mc-pop .member-card { margin: 0; max-width: none; opacity: 0; transform: scale(.96) translateY(6px); transition: opacity .2s ease, transform .24s cubic-bezier(.2, .8, .3, 1); }
.mc-pop--in .member-card { opacity: 1; transform: none; }
.mc-pop-x { position: absolute; top: -14px; right: -6px; z-index: 2; width: 34px; height: 34px; border-radius: 50%; border: 0; background: #fff; color: #023A50; font-size: 15px; font-weight: 700; line-height: 1; cursor: pointer; box-shadow: 0 6px 18px rgba(1, 30, 44, .35); }
.member-card--pop .mc-qr { width: 196px; }
.member-card--pop .mc-photo { width: 76px; height: 76px; }
.member-card--pop .mc-photo--initial { font-size: 32px; }
.member-card--pop .mc-name { font-size: 22px; }
@media (prefers-reduced-motion: reduce) {
  .mc-pop .member-card { transition: none; }
  .mc-dot { transition: none; }
}
.mc-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mc-brandwrap { display: inline-flex; align-items: center; gap: 8px; }
.mc-logo { width: 30px; height: 30px; border-radius: 8px; }
.mc-brand { font-weight: 800; letter-spacing: 2px; font-size: 13px; }
.mc-mid { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 14px; }
.mc-person { min-width: 0; }
.mc-photo { width: 62px; height: 62px; border-radius: 50%; object-fit: cover; display: block; margin-bottom: 8px; background: rgba(255,255,255,.15); }
.member-card--pro .mc-photo { background: rgba(2, 58, 80, .16); }
.mc-photo--initial { display: flex; align-items: center; justify-content: center; font-size: 26px; font-weight: 800; color: #fff; }
.member-card--pro .mc-photo--initial { color: #023A50; }
.mc-name { font-size: 19px; font-weight: 700; line-height: 1.2; }
.mc-since { font-size: 12px; color: rgba(255,255,255,.75); margin-top: 2px; }
.member-card--pro .mc-since { color: rgba(2, 58, 80, .72); }
.mc-status { font-size: 13px; font-weight: 700; margin-top: 6px; color: #7BCF25; }
.member-card--pro .mc-status { color: #2F6B01; }
.mc-qr { background: #fff; border-radius: 12px; padding: 8px; width: 118px; flex: 0 0 auto; }
.mc-qr svg { width: 100%; height: auto; display: block; }
.mc-note { font-size: 12px; color: rgba(255,255,255,.82); margin: 12px 0 0; }
.member-card--pro .mc-note { color: rgba(2, 58, 80, .82); }
.mc-locked-copy { margin: 14px 0 4px; }

/* Universal card faces (Oct 15, 2026 — "Create a card for all
   users"): Free is a clean white card with navy ink and a silver
   border — a proud base card, not a greyed-out upsell. Business is
   a deep RED face (Donald's pick): brand red bright at the top-left
   deepening to dark red at the bottom-right, white ink, navy tier
   pill, sand status line. */
.member-card--free {
  background: linear-gradient(160deg, #FFFFFF 0%, #F2F6F7 100%);
  color: #023A50;
  border: 1.5px solid #CECFD4;
  box-shadow: 0 14px 34px rgba(2, 41, 59, 0.16);
}
.member-card--free .mc-photo { background: rgba(2, 58, 80, .08); }
.member-card--free .mc-photo--initial { color: #023A50; }
.member-card--free .mc-since { color: rgba(2, 58, 80, .66); }
.member-card--free .mc-status { color: #2F6B01; }
.member-card--free .mc-note { color: rgba(2, 58, 80, .78); }
.member-card--free .mc-qr { border: 1px solid #E1E8EA; }
.member-card--business {
  background: linear-gradient(135deg, #F6040C 0%, #C4040B 45%, #8C030A 100%);
  border: 1.5px solid rgba(90, 2, 6, 0.55);
  box-shadow: 0 14px 34px rgba(140, 3, 10, 0.38);
}
.member-card--business .badge-business { background: #023A50; color: #fff; }
.member-card--business .mc-status { color: #FBD184; }
.badge-member { background: #CECFD4; color: #023A50; }

/* Nearby Tap on the card face (Donald's Oct 15, 2026 order): the
   full Nearby Tap graphic in a small white tile under the QR, with
   a quiet caption — the card works by tap or by scan. */
.mc-side { display: flex; flex-direction: column; align-items: center; gap: 7px; flex: 0 0 auto; }
.mc-tapmark { display: flex; align-items: center; gap: 7px; }
.mc-tapmark-tile { background: #fff; border-radius: 10px; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; box-shadow: 0 3px 10px rgba(2, 41, 59, 0.25); flex: 0 0 auto; }
.mc-tapmark-tile img { width: 42px; height: 41px; display: block; }
.mc-tapmark-cap { font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, .8); white-space: nowrap; }
.member-card--pro .mc-tapmark-cap { color: rgba(2, 58, 80, .72); }
.member-card--free .mc-tapmark-cap { color: rgba(2, 58, 80, .66); }
.member-card--free .mc-tapmark-tile { border: 1px solid #E1E8EA; box-shadow: none; }

/* Card activity — the member's own card-check history under the card
   (profile overview + perks page). Calm list, muted detail text. */
.mc-activity { max-width: 560px; margin: 16px auto 0; text-align: left; }
.mc-activity-h { text-align: center; font-size: 15px; margin: 0 0 6px; color: var(--mist-navy); }
.mc-activity-row { display: flex; align-items: baseline; gap: 10px; padding: 7px 2px; border-top: 1px solid var(--mist-line-2); font-size: 13px; }
.mc-activity-status { font-weight: 700; flex: 0 0 auto; }
.mc-activity-status.ok { color: #2F6B01; }
.mc-activity-status.off { color: #B3261E; }
.mc-activity-meta { color: var(--mist-ink); flex: 1 1 auto; min-width: 0; }
.mc-activity-time { color: var(--mist-muted); font-size: 12px; flex: 0 0 auto; }
.mc-howto { max-width: 560px; margin: 16px auto 0; text-align: left; }
.mc-howto-h { text-align: center; font-size: 15px; margin: 0 0 6px; color: var(--mist-navy); }
.mc-howto-list { list-style: none; margin: 0; padding: 0; }
.mc-howto-list li { display: flex; gap: 10px; padding: 7px 2px; border-top: 1px solid var(--mist-line-2); }
.mc-howto-n { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%; background: var(--mist-navy); color: #fff; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; margin-top: 1px; }
.mc-howto-list p { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.45; }
.mc-howto-list p strong { color: var(--mist-ink); }

/* Welcome + tour + welcome video (Donald's Oct 15, 2026): Pip's panel,
   the coach-mark tour, and the player. The panel and player ride the
   standard modal (blur backdrop); the tour dims use the same navy. */
.wt-panel { text-align: center; }
.wt-pip { width: 132px; height: 132px; object-fit: contain; }
.page-head-centered .wt-pip { display: block; margin-inline: auto; }
.wt-title { margin: 10px 0 6px; font-size: 20px; color: var(--mist-navy); }
.wt-line { font-size: 13px; line-height: 1.5; margin: 0 auto; max-width: 400px; }
.wt-btns { justify-content: center; margin-top: 16px; }
.wt-player-title { margin: 0 0 12px; font-size: 17px; color: var(--mist-navy); text-align: center; }
.wt-video { width: 100%; aspect-ratio: 16 / 9; background: #012636; border-radius: 12px; display: block; }
.wt-page-player { max-width: 720px; margin: 18px auto 0; padding: 10px; }
.wt-layer { position: fixed; inset: 0; z-index: 1450; }
.wt-dim { position: absolute; background: rgba(1, 30, 44, .55); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.wt-ring { position: absolute; border: 3px solid var(--sand); border-radius: 14px; box-shadow: 0 0 0 4px rgba(251, 209, 132, .35), var(--shadow-lg); pointer-events: none; }
.wt-skip { position: absolute; top: calc(10px + env(safe-area-inset-top)); right: 12px; z-index: 2; background: #fff; color: var(--mist-navy); border: 1px solid var(--border); border-radius: 999px; padding: 7px 14px; font: 600 13px var(--font); cursor: pointer; box-shadow: var(--shadow-lg); }
.wt-card { position: absolute; z-index: 2; width: min(360px, calc(100vw - 24px)); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 16px; }
.wt-card-head { display: flex; align-items: center; gap: 9px; }
.wt-card-icon { font-size: 22px; line-height: 1; }
.wt-card-title { margin: 0; font-size: 16px; color: var(--mist-navy); }
.wt-card-cap { margin: 8px 0 0; font-size: 13px; line-height: 1.5; color: var(--mist-ink); }
.wt-card-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 14px; gap: 10px; }
.wt-dots { display: flex; gap: 6px; }
.wt-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); }
.wt-dot.on { background: var(--mist-navy); }
.wt-nav { display: flex; gap: 8px; }
.wt-watch { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

/* Public verify landing (#/member-card/<token>) mirrors the face of
   the tier being verified, so a partner reads the tier from the
   color before a word. Untinted until the server confirms a tier. */
#mcl-shell.mcl--plus { background: linear-gradient(135deg, #023A50 0%, #012636 100%); color: #fff; }
#mcl-shell.mcl--plus h2 { color: #fff; }
#mcl-shell.mcl--plus .muted { color: rgba(255, 255, 255, .78); }
#mcl-shell.mcl--gold { background: linear-gradient(135deg, #F9C74F 0%, #F5A623 40%, #E0950A 72%, #B97A0F 92%, #9A6605 100%); color: #023A50; }
#mcl-shell.mcl--gold h2 { color: #023A50; }
#mcl-shell.mcl--gold .muted { color: rgba(2, 58, 80, .74); }
.perk-status { font-size: 15px; font-weight: 600; color: var(--navy); margin: 4px 0 8px; }
.perk-step { display: flex; gap: 9px; align-items: flex-start; padding: 8px 0; border-top: 1px solid var(--hairline, #eee); font-size: 14px; }
.perk-step input { width: 18px; height: 18px; margin-top: 1px; flex: 0 0 auto; }

/* Designed receipt card (Donald's Oct 15, 2026: "receipts look nice,
   with our logo on it") — one treatment across web, email, PDF, and
   mobile: official logo centered on the brand-navy band, receipt
   number + local date/time, parties, itemized lines with muted
   "of which" components, a bold TOTAL, the standard sign-off. */
.receipt-card {
  background: #fff; border-radius: 18px; overflow: hidden;
  box-shadow: 0 18px 44px rgba(2, 41, 59, .28), 0 3px 10px rgba(2, 41, 59, .18);
  max-width: 560px; margin: 6px auto 18px; text-align: left;
}
.receipt-band { background: #023A50; padding: 20px 24px 16px; text-align: center; }
.receipt-logo { width: 92px; height: 92px; display: block; margin: 0 auto; }
.receipt-body { padding: 22px 28px 24px; }
.receipt-title { text-align: center; font-size: 21px; color: #023A50; margin: 0 0 4px; }
.receipt-number { text-align: center; font-weight: 800; font-size: 16px; color: #22333d; letter-spacing: .02em; }
.receipt-date { text-align: center; font-size: 13px; color: #5c6f7a; margin-top: 2px; }
.receipt-status { text-align: center; margin-top: 8px; }
.receipt-refund-of { text-align: center; font-size: 13px; font-weight: 700; color: #8C030A; margin: 8px 0 0; }
.receipt-parties { margin: 18px 0 4px; }
.receipt-lines { margin-top: 14px; }
.receipt-line { display: flex; justify-content: space-between; gap: 16px; padding: 3px 0; font-size: 15px; color: #22333d; }
.receipt-line .receipt-amt { font-variant-numeric: tabular-nums; white-space: nowrap; }
.receipt-line.component { font-size: 13px; color: #8a97a0; padding-left: 16px; }
.receipt-total {
  display: flex; justify-content: space-between; gap: 16px;
  border-top: 2px solid #023A50; margin-top: 8px; padding-top: 8px;
  font-size: 16px; font-weight: 800; color: #023A50;
}
.receipt-thanks { text-align: center; font-size: 15px; font-weight: 600; color: #023A50; margin: 22px 0 0; }
.receipt-smallprint { text-align: center; font-size: 12px; color: #8a97a0; margin: 4px 0 0; }
.receipt-record { text-align: center; font-size: 12px; margin: 12px 0 0; }
@media print {
  /* The receipt prints as itself: logo + lines, no shadow, no chrome
     (chrome is already hidden by the global print rules). */
  .receipt-card { box-shadow: none !important; border: 1px solid #ccc; max-width: none; }
  .receipt-band { background: #fff !important; border-bottom: 2px solid #023A50; }
}

/* Admin Transactions explorer (#/admin-transactions) */
.atx-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.atx-f { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: #8a97a0; font-weight: 600; }
.atx-f input, .atx-f select { font-size: 14px; padding: 8px 10px; border: 1px solid #d5dde2; border-radius: 10px; font-family: inherit; color: #22333d; background: #fff; }
.atx-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; text-align: center; }
.atx-chip { display: inline-block; background: #eef4f7; border: 1px solid #d5dde2; border-radius: 999px; padding: 2px 10px; font-size: 12px; margin: 2px; color: #22333d; }
.atx-row {
  display: grid; grid-template-columns: 150px 110px 1fr 90px 80px 76px 108px; gap: 10px; align-items: center;
  width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid #eef2f4;
  padding: 10px 16px; font: inherit; font-size: 13px; color: #22333d; cursor: pointer;
}
.atx-row:hover { background: #f6fafc; }
.atx-row .atx-amt { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.atx-row .atx-when { color: #5c6f7a; }
.atx-row .atx-kind { font-weight: 600; }
@media (max-width: 700px) {
  .atx-row { grid-template-columns: 1fr 90px; }
  .atx-row .atx-when, .atx-row .atx-fee, .atx-row .atx-status, .atx-row .atx-receipt { display: none; }
}

/* Profile widgets Batch 1 (Oct 16, 2026): the "Your widgets" section on
   the profile overview — same card language as the rest of the profile,
   titles centered, descriptive text muted 12px, small + organized. */
.widgets-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 900px) { .widgets-grid { grid-template-columns: 1fr 1fr; } }
.widget-card { margin-bottom: 0; }
.widget-title { text-align: center; }
.widget-center { text-align: center; }
.widget-big { text-align: center; font-size: 26px; font-weight: 800; color: var(--navy); margin: 2px 0; }
.widget-rows { display: flex; flex-direction: column; }
.widget-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.widget-row:last-child { border-bottom: none; }
a.widget-row.widget-link { text-decoration: none; color: inherit; }
a.widget-row.widget-link:hover { background: rgba(2,58,80,.04); }
.widget-checklist li { min-height: 44px; padding: 7px 0; }

/* Profile widgets Batch 2 (Oct 16, 2026): section header row, amber
   due-back state, My-card mini strip, Widgets page (#/widgets) rows. */
.widgets-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.widgets-head h3 { margin-bottom: 0; }
.widget-amber { color: #B45309; }
.widget-mc-mini { margin: 0 auto 8px; max-width: 360px; }
.widget-mc-mini .widget-mc-status { font-size: 13px; font-weight: 600; }
.widget-flash { outline: 3px solid var(--orange, #FBA200); outline-offset: 3px; }
.wpage-list { margin-top: 10px; }
.wpage-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 2px; border-bottom: 1px solid var(--border); }
.wpage-row:last-child { border-bottom: none; }
.wpage-info { flex: 1; min-width: 0; text-align: left; }
.wpage-action { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.wpage-added { color: #43A002; font-weight: 700; font-size: 13px; }
.badge-soon { background: #FBD184; color: #023A50; font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; }

/* Profile widgets — Nearby Bookings v2 (Oct 16, 2026): in-widget
   actions, owner's strip, live trip strip, mini calendar. Calm and
   native to the widget family; append-only. */
.widget-row.nb-row { display: block; }
/* Nearby Tap widget (Oct 16, 2026): exchange rows stack like NB rows;
   its action row and the live present-card QR slot. Append-only. */
.widget-row.tap-row { display: block; }
.tap-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.tap-qr { max-width: 148px; margin: 4px auto; }
.tap-qr svg { width: 100%; height: auto; display: block; }
.nb-main { display: flex; justify-content: space-between; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.nb-main:hover { background: rgba(2,58,80,.04); }
.nb-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.nb-strip { text-align: center; font-size: 13px; margin: 2px 0 6px; }
.nb-trip { background: rgba(2,58,80,.05); border-radius: 10px; padding: 8px 10px; margin: 6px 0; }
.nb-trip-main { display: flex; justify-content: space-between; align-items: center; gap: 10px; text-decoration: none; color: inherit; font-size: 13px; }
.nb-trip .trip-progress { margin-top: 6px; }
.nb-cal { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.nb-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.nb-cal-dow { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.nb-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.nb-cell { border: none; background: transparent; border-radius: 8px; padding: 3px 0 4px; text-align: center; font-size: 12px; cursor: pointer; color: inherit; display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 30px; font-family: inherit; }
.nb-cell:hover { background: rgba(2,58,80,.06); }
.nb-cell.today { box-shadow: inset 0 0 0 1px var(--navy); }
.nb-cell.sel { background: var(--navy); color: #fff; }
.nb-cell-empty { cursor: default; }
.nb-cell-empty:hover { background: transparent; }
.nb-dots { display: flex; gap: 2px; min-height: 6px; }
.nb-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; }
.nb-dot.pickup { background: #43A002; }
.nb-dot.return { background: #F6040C; }
.nb-day-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px; text-decoration: none; color: inherit; }
.nb-day-row:last-child { border-bottom: none; }
.nb-day-row:hover { background: rgba(2,58,80,.04); }

/* Nearby Bookings brand tiles (Donald's logo, Oct 16, 2026) — the pin
   mark in a white rounded tile, the member-card Nearby Tap tile recipe:
   on the widget card header (Profile) and its Widgets-page row. */
.widget-brand { display: flex; justify-content: center; margin: 0 0 8px; }
.widget-brand-tile { background: #fff; border: 1px solid #E1E8EA; border-radius: 10px; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; box-shadow: 0 3px 10px rgba(2, 41, 59, 0.12); flex: 0 0 auto; }
.widget-brand-tile img { height: 40px; width: auto; display: block; }
.wpage-name { display: inline-flex; align-items: center; gap: 8px; }
.wpage-tile { background: #fff; border: 1px solid #E1E8EA; border-radius: 8px; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 2px 6px rgba(2, 41, 59, 0.10); flex: 0 0 auto; }
.wpage-tile img { height: 29px; width: auto; display: block; }

/* Group Sell banner (Donald's Oct 16, 2026 order): the state-driven
   sell card under the group header — the Tool Master's Sell button,
   the open-vote notice, and the LIVE state live here so nobody has
   to hunt the last tab. */
.gs-sell-banner { text-align: center; margin: 0 0 12px; }
.gs-sell-banner .gs-sell-title { font-weight: 800; font-size: 15px; }
.gs-sell-banner.live { background: #fdecec; border-color: #f5b8ba; }
.gs-sell-banner.live .gs-sell-title { color: var(--red); }
.gs-sell-actions { display: flex; gap: 8px; justify-content: center; margin-top: 10px; flex-wrap: wrap; }
/* Group Share navigation redesign (Oct 16, 2026): the Requests tab
   carries a count badge for what is waiting on the member; Dashboard
   and Ideas move to a quiet secondary row under the section tabs;
   My Groups cards gain a one-line state (waiting / vote / next). */
.gs-tab-badge {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 999px; background: var(--red); color: #fff;
  font-size: 11px; font-weight: 800; line-height: 18px; text-align: center;
  vertical-align: 2px;
}
.gs-subnav {
  display: flex; gap: 4px; align-items: center; flex-wrap: wrap;
  margin: 0 0 10px;
}
.gs-subnav button {
  border: none; background: none; padding: 6px 10px; min-height: 36px;
  font-size: 12.5px; font-weight: 600; color: var(--muted); cursor: pointer;
  border-radius: 999px;
}
.gs-subnav button.active { color: var(--navy); background: var(--mist-bg-2, #eef3f5); }
.gs-subnav .gs-suggest-link { margin-left: auto; color: var(--navy); text-decoration: underline; }
.gs-group-state { font-size: 12px; color: var(--muted); margin-top: 6px; min-height: 0; }
.gs-group-state:empty { display: none; }
.gs-group-state.waiting { color: #9a6200; font-weight: 700; }

/* Download page — single-card layout (Oct 16, 2026: the Android App card
 * was removed on Donald's order; center the lone Web App card on wide
 * screens instead of leaving it in the left half of the 2-col grid). */
@media (min-width: 720px) { .dl-grid { grid-template-columns: minmax(0, 560px); justify-content: center; } }

/* ==========================================================================
   WEBSITE REDESIGN — dedicated bigger-screen designs (Donald's orders,
   Oct 16, 2026). Append-only layer: every rule lives at ≥768px, so the
   phone design (≤767px) is untouched. Governing principles, his words:
   (1) "Create similar but separate design for bigger screen for all
       pages" — dedicated desktop compositions, not a scaled phone UI.
   (2) "Instead of stretching the cards reorganize them so we can fit
       more since the devices are bigger" — cards keep natural size;
       bigger screens fit MORE across.
   (3) "Use the spaces of the bigger screen wisely" — rails, panels and
       columns with a purpose; no empty expanses or stranded ribbons.
   (4) A clear, always-visible TOOLBAR on every laptop/desktop width.
   ========================================================================== */

/* ---------- §A. The desktop shell: a real toolbar at every laptop width --
   Before: .header-nav only appeared at ≥1280px, so at 1024–1279px (the
   classic laptop band) there was NO top navigation at all — just a
   hamburger and the phone dock. Now the desktop shell starts at 1024px:
   toolbar visible, hamburger + dock retired, and the nav cluster is
   styled as one designed toolbar bar. */
@media (min-width: 1024px) {
  #menu-toggle { display: none; }
  #bottom-nav { display: none; }
  #view { padding-bottom: 0; }
  #site-footer { padding-bottom: 24px; }
  #chat-fab { bottom: 24px; }
  #chat-panel { bottom: 96px; }
  .header-nav {
    display: inline-flex;
    background: rgba(255, 255, 255, 0.66);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 4px;
    gap: 2px;
    box-shadow: 0 6px 18px rgba(38, 35, 30, 0.08);
  }
  .header-nav a { white-space: nowrap; }
}
/* The fit band: on smaller laptops the search flexes and the toolbar
   compacts so logo + search + Install + toolbar + actions always fit
   on one line (the header never wraps — Donald's standing rule). */
@media (min-width: 1024px) and (max-width: 1279px) {
  #site-header { gap: 8px; padding: 0 12px; }
  .brand-logo { height: 34px; }
  .header-search { max-width: 300px; }
  .header-nav a { font-size: 13.5px; padding: 8px 10px; min-height: 40px; }
  .header-install { padding: 7px 11px; font-size: 12.5px; min-height: 38px; }
}

/* ---------- §B. One type scale at every width ----------------------------
   Before: body type grew 16 → 17px (@1440) → 20px (@1920) and the
   @1920 block ballooned px-sized components (.btn 20px/60px tall,
   inputs 60px, header 76px) while the rest stayed small — the mixed
   scaling behind "the buttons look distorted". Desktop now uses the
   same designed sizes as everywhere else; width goes to layout. */
@media (min-width: 1440px) {
  body { font-size: 16px; }
}
@media (min-width: 1920px) {
  :root { --header-h: 60px; }
  body { font-size: 16px; }
  .container { max-width: 1440px; padding: 24px; }
  .brand-logo { height: 38px; }
  .header-nav a { font-size: 15px; padding: 10px 14px; }
  .header-search input { height: 42px; font-size: 15px; }
  .tool-card-title { font-size: 16px; }
  .tool-card-price { font-size: 17px; }
  .btn { font-size: 11px; padding: 6px 14px; min-height: 30px; }
  .btn-sm { font-size: 9px; padding: 4px 10px; min-height: 22px; }
  .card { padding: 16px; }
  .field label { font-size: 15px; }
  .field input, .field select, .field textarea { font-size: 16px; min-height: 48px; }
  .price-line { font-size: 28px; }
  .price-pin { font-size: 13px; padding: 6px 12px; }
  .strip-card { flex: 0 0 200px; }
  .strip-card img { height: 110px; }
  .msg { font-size: 15px; }
  .chat-msg { font-size: 15px; }
  h2 { font-size: 24px; }
}

/* ---------- §C. Button proportions on desktop ---------------------------
   .btn-sm (9px) and .btn-tiny (7px) are phone-density sizes; with a
   mouse they render as unreadable micro-pills (33 of them on the My
   Tools tab, 14 on the Widgets page). Desktop floors keep every button
   at its designed proportions — same classes, same labels, legible.
   Garages carried an outright accident at ≥1024px: 4.5px buttons. */
@media (min-width: 1024px) {
  .btn-sm { font-size: 11px; min-height: 30px; padding: 6px 12px; }
  /* (the base .btn-tiny rule is !important, so the desktop floor is too) */
  .btn-tiny { font-size: 10px !important; min-height: 26px !important; padding: 4px 10px !important; letter-spacing: 0.03em; }
  .garages-page .btn { font-size: 12px; padding: 6px 12px; min-height: 30px; }
  .garages-page .chip { font-size: 11px; padding: 4px 10px; min-height: 26px; }
  .garages-page .badge { font-size: 10px; padding: 2px 7px; }
}

/* ---------- §D. Reflowing card grids (Donald's governing rule) ----------
   Fixed column counts made cards GROW with the screen (a tool card was
   ~415px wide at 1920px). Auto-fill keeps cards at their natural
   measure and adds COLUMNS as the screen widens: ~250–330px tool
   cards and ~230–300px merch cards at every desktop width. */
@media (min-width: 768px) {
  .tool-grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
  #pub-tools .tool-grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
  .merch-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
}

/* ---------- §E. Tool detail: a composed page, not a stretched card ------
   Before: the glass card (title, price, ad, owner, the whole button
   stack) spanned the full 1,360px container — nine buttons over 470px
   wide, one 1,222px ad ribbon. Now the glass card is a 360px action
   rail (buttons at phone proportions) beside a ≤820px reading column
   of detail cards. */
@media (min-width: 1024px) {
  .tool-detail .container:has(> .tool-glass-card) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 28px;
    align-items: start;
  }
  .tool-detail .tool-glass-card {
    grid-column: 2; grid-row: 1;
    margin: -64px 0 0;
    position: sticky; top: calc(var(--header-h) + 16px);
    max-height: calc(100dvh - var(--header-h) - 32px);
    overflow-y: auto;
  }
  .tool-detail .detail-layout { grid-column: 1; grid-row: 1; display: block; }
  .tool-hero .photo-gallery { max-width: 1280px; margin: 0 auto; }
}
@media (min-width: 1440px) {
  .tool-detail .container:has(> .tool-glass-card) {
    grid-template-columns: minmax(0, 820px) 360px;
    justify-content: center;
  }
}

/* ---------- §F. Ads: a dedicated bigger-screen design -------------------
   Standing rules unchanged (one sponsored placement per surface,
   classy, fixed copy zones + shrink-to-fit inside grid cells). What
   changes is the BANNER form: before, the generic slot's flex row
   stretched to the full column (measured 1,222px wide on a tool page).
   On bigger screens the banner is a designed wide-format card: capped
   measure, a larger media stage designed for the slot, a copy zone
   that matches the stage, and a quiet arrow affordance. In the tool
   rail the same card takes a mid-format stage at the rail's measure.
   Grid-cell ads keep the equal-cell system (one product cell exactly). */
@media (min-width: 768px) {
  #gs-list-ad .ad-card, #gs-thread-ad .ad-card, #garage-ad-slot .ad-card,
  #w-ad-slot .ad-card, #sf-ad-slot .ad-card, #closed-ad-slot .ad-card,
  #gms-ad-slot .ad-card {
    max-width: 880px; margin-left: auto; margin-right: auto;
  }
}
@media (min-width: 1024px) {
  #gs-list-ad .ad-card, #gs-thread-ad .ad-card, #garage-ad-slot .ad-card,
  #w-ad-slot .ad-card, #sf-ad-slot .ad-card, #closed-ad-slot .ad-card,
  #gms-ad-slot .ad-card {
    padding: 18px 20px; position: relative;
  }
  #gs-list-ad .ad-card img, #gs-list-ad .ad-card video,
  #gs-thread-ad .ad-card img, #gs-thread-ad .ad-card video,
  #garage-ad-slot .ad-card img, #garage-ad-slot .ad-card video,
  #w-ad-slot .ad-card img, #w-ad-slot .ad-card video,
  #sf-ad-slot .ad-card img, #sf-ad-slot .ad-card video,
  #closed-ad-slot .ad-card img, #closed-ad-slot .ad-card video,
  #gms-ad-slot .ad-card img, #gms-ad-slot .ad-card video {
    width: 176px !important; height: 124px !important; border-radius: 12px;
  }
  #gs-list-ad .ad-copy, #gs-thread-ad .ad-copy, #garage-ad-slot .ad-copy,
  #w-ad-slot .ad-copy, #sf-ad-slot .ad-copy, #closed-ad-slot .ad-copy,
  #gms-ad-slot .ad-copy { max-height: 124px; padding-right: 48px; }
  #gs-list-ad a.ad-card::after, #gs-list-ad div.ad-card::after,
  #gs-thread-ad a.ad-card::after, #gs-thread-ad div.ad-card::after,
  #garage-ad-slot a.ad-card::after, #garage-ad-slot div.ad-card::after,
  #w-ad-slot a.ad-card::after, #w-ad-slot div.ad-card::after,
  #sf-ad-slot a.ad-card::after, #sf-ad-slot div.ad-card::after,
  #closed-ad-slot a.ad-card::after, #closed-ad-slot div.ad-card::after,
  #gms-ad-slot a.ad-card::after, #gms-ad-slot div.ad-card::after {
    content: "→"; position: absolute; right: 18px; top: 50%;
    transform: translateY(-50%); width: 36px; height: 36px;
    border-radius: 50%; background: var(--navy); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 17px; font-weight: 700;
    box-shadow: 0 6px 16px rgba(2, 58, 80, 0.30);
  }
  /* Tool rail: mid-format stage at the rail's natural measure. */
  #tool-ad-slot .ad-card img, #tool-ad-slot .ad-card video {
    width: 128px !important; height: 88px !important;
  }
  #tool-ad-slot .ad-copy { max-height: 88px; }
}

/* ---------- §G. Group Share: a first-class desktop surface --------------
   List: group cards were full-width ribbons (1,312px) — now a
   reflowing card grid, cards at natural measure, more across as the
   screen grows. Group page: the sell banner takes a designed measure,
   the tab row centers under the centered header, and the stacked tab
   cards (Requests / Calendar / Threads / Members / Sell) compose at a
   reading measure instead of spanning the container. */
@media (min-width: 768px) {
  .gs-sell-banner { max-width: 880px; margin-left: auto; margin-right: auto; }
}
@media (min-width: 1024px) {
  #gs-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 16px;
  }
  #gs-list > :not(.gs-group-wrap) { grid-column: 1 / -1; }
  .gs-group-wrap { display: flex; flex-direction: column; }
  #gs-list .gs-group-card { flex: 1; margin-bottom: 6px; }
  .gs-tabs { justify-content: center; }
  #gs-tab-body > .card { max-width: 880px; margin-left: auto; margin-right: auto; }
  #gs-tab-body > h2, #gs-tab-body > h3, #gs-tab-body > p {
    max-width: 880px; margin-left: auto; margin-right: auto;
  }
}

/* ---------- §H. Widgets --------------------------------------------------
   The Widgets page rendered straight into #view with no container —
   edge-to-edge at every width, rows spanning 1,440px with the action
   stranded at the far right. It gains a page measure (desktop only;
   phone bytes identical) and its rows become a reflowing card grid.
   On the Profile, the widget grid fits a third column when the screen
   is wide enough to hold it at natural size. */
@media (min-width: 768px) {
  .widgets-page { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
}
@media (min-width: 1024px) {
  .wpage-list { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .wpage-row {
    border: 1px solid var(--border); border-radius: 16px;
    padding: 14px 16px; background: #F7F5F1;
    box-shadow: 0 8px 22px rgba(38, 35, 30, 0.07);
  }
}
@media (min-width: 1500px) {
  .wpage-list { grid-template-columns: repeat(3, 1fr); }
  .widgets-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- §I. Public storefront ---------------------------------------
   The identity card spanned the full container around a centered
   avatar. Identity + member-since cards now compose at a designed
   measure; the listings card stays wide so its tool grid fits more
   across. */
@media (min-width: 1024px) {
  .storefront-card { max-width: 880px; margin-left: auto; margin-right: auto; }
  .storefront-card:has(#pub-tools) { max-width: none; }
  .storefront-card + .card { max-width: 880px; margin-left: auto; margin-right: auto; }
  /* the comment submit is a full-width form bar on phone by design;
     on desktop it takes a natural button measure, centered */
  #pub-comment-post { width: min(320px, 100%) !important; display: flex; margin-left: auto; margin-right: auto; }
}

/* ---------- §J. Profile: the overview as a desktop dashboard ------------
   Donald's acceptance test: at 1440×900 the overview's essentials —
   identity, verification, quick stats, widgets, member card, quick
   actions — must be on the first screen, arranged across the width in
   compact columns, no text shrunk. Before: one 764px column 3,693px
   tall (member card at y2,322, quick actions at y3,545). At ≥1280px
   the section rail becomes a horizontal strip (freeing the content
   width) and the overview composes as a grid: widgets across the top,
   badges | quick stats | quick actions in one row, the member card
   composed in columns (card face | how-to + activity), deeper cards
   paired below. Other tabs keep the rail layout. */
@media (min-width: 1280px) {
  .profile-body { display: flex; flex-direction: column; }
  .profile-body .profile-sections {
    order: -1; flex-direction: row; align-items: center;
    border-right: none; border-bottom: 2px solid var(--border);
    overflow-x: auto; margin-bottom: 16px; margin-top: 0 !important;
  }
  .profile-sections button {
    text-align: center; border-left: none;
    border-bottom: 3px solid transparent; margin-right: 0; margin-bottom: -2px;
    white-space: nowrap; min-height: 40px; padding-top: 6px; padding-bottom: 6px;
  }
  .profile-sections button.active { border-bottom-color: var(--red); }

  #tab-body:has(> #ov-widgets) {
    display: grid; grid-template-columns: repeat(6, 1fr);
    gap: 12px; align-items: start;
  }
  #tab-body:has(> #ov-widgets) > * { grid-column: span 3; order: 5; margin-bottom: 0; min-width: 0; }
  #tab-body:has(> #ov-widgets) > h3 { display: none; }
  #tab-body:has(> #ov-widgets) > #ov-widgets { grid-column: span 6; order: 1; }
  #ov-widgets .widgets-grid { grid-template-columns: repeat(3, 1fr); }
  #tab-body:has(> #ov-widgets) > .card:has(> #ov-badges) { grid-column: span 2; order: 2; }
  #tab-body:has(> #ov-widgets) > .card:has(> #ov-stats) { grid-column: span 2; order: 2; }
  #tab-body:has(> #ov-widgets) > .welcome-card { grid-column: span 2; order: 2; }
  #tab-body:has(> #ov-widgets) > #ov-member-card-card { grid-column: span 6; order: 3; }
  #tab-body:has(> #ov-widgets) > #ov-activity-card { order: 4; }
  #tab-body:has(> #ov-widgets) > .card:has(> #ov-qr-slot) { order: 4; }

  #tab-body:has(> #ov-widgets) > .welcome-card .quick-actions .btn { flex: 1 1 30%; }
  #ov-widgets .widgets-head { margin-bottom: 2px; }
  #ov-widgets .widgets-head h3 { margin-top: 0; }
  .profile-body .profile-sections { margin-bottom: 10px; }
  #view:has(.profile-layout) .container { padding-top: 14px; }

  /* Member card, composed: the face at its natural measure on the
     left, the six how-to steps in two columns beside it, card
     activity as a full-width strip below — instead of a 1,039px
     stack. (#ov-member-card's blocks join the card's grid directly.) */
  #ov-member-card-card {
    display: grid; grid-template-columns: minmax(0, 472px) 1fr; column-gap: 20px;
  }
  #ov-member-card-card > h3 { grid-column: 1 / -1; }
  #ov-member-card-card > #ov-member-card { display: contents; }
  #ov-member-card .mc-slider, #ov-member-card .mc-cards {
    grid-column: 1; grid-row: 2; min-width: 0; max-width: 340px;
  }
  #ov-member-card-card { padding-top: 6px; }
  #tab-body:has(> #ov-widgets) > .welcome-card { padding: 12px; }
  #ov-member-card-card > h3 { margin-top: 0; }
  #ov-member-card .mc-tap { grid-column: 1; grid-row: 3; min-width: 0; }
  #ov-member-card .mc-howto {
    grid-column: 2; grid-row: 2 / span 3; min-width: 0;
    max-width: none; margin-top: 0; text-align: left;
  }
  #ov-member-card .mc-howto-list { columns: 2; column-gap: 16px; }
  #ov-member-card .mc-howto-list li { break-inside: avoid; }
  #ov-member-card-card > .btn-row { grid-column: 1; grid-row: 4; }
  #ov-member-card-card > p { grid-column: 1; grid-row: 5; }
  #ov-member-card-card > #ov-member-card-activity { grid-column: 1 / -1; grid-row: 6; min-width: 0; }
  #ov-member-card-activity .mc-activity { max-width: none; margin-top: 4px; text-align: left; }
}
/* The rail's storefront block squeezed its text into a ~110px column
   beside its buttons at 300px wide; let the text take the full rail
   width and the buttons follow on their own line. */
@media (min-width: 1024px) {
  .profile-layout > .card div:has(> div > a[href^="#/u/"]) { flex-wrap: wrap; }
  .profile-layout > .card div:has(> div > a[href^="#/u/"]) > div:first-child { flex: 1 1 100%; }
}

/* ---------- §K. Forms & plan cards keep a designed measure -------------- */
@media (min-width: 1024px) {
  .auth-card { max-width: 480px; margin-left: auto; margin-right: auto; }
  .plan-card { max-width: 400px; }
  div:has(> .plan-card) { justify-content: center; }
}

/* ---------- §L. Auth: one composed, symmetrical card on desktop ------------
   Donald's report (Oct 16, 2026): the login page on a laptop was "not
   symmetrical and esthetic" — measured: Google's pill renders 400px wide
   and sat LEFT-shifted (center offset −40px) in the 480px column, the
   three CTAs were three different sizes (400×40 / 480×52 / 480×38), and
   the form floated bare and top-hugging on the page background, with the
   verify pages' titles floating outside their cards. Desktop auth is now
   ONE perfectly centered card on a calm backdrop — the .auth-page hook
   (js/views/auth.js) puts login, sign-up and every verify sibling in the
   same composition. Card padding makes the content rail 398px (inside
   Google's 400px maximum) so Google, Facebook, the email pill and
   the form fields share one width and one center. Desktop only: no rule
   below 1024px references .auth-page, so the phone is untouched. */
@media (min-width: 1024px) {
  /* Calm branded backdrop; the auth column centers vertically in the view. */
  #view:has(> .container > .auth-page) {
    display: flex; flex-direction: column;
    background: radial-gradient(760px 520px at 50% 32%, rgba(2, 58, 80, 0.07), rgba(2, 58, 80, 0) 70%);
    /* Center the card on the TRUE viewport axis: 100vw includes the
       classic scrollbar, 100% (the containing block) does not, so this
       padding is exactly the scrollbar's width — without it the card
       sits half a scrollbar (~7.5px) left of center on desktop
       (measured Oct 21, 2026). No scrollbar -> 0 -> no shift. */
    padding-left: calc(100vw - 100%);
  }
  #view:has(> .container > .auth-page) > .container {
    flex: 1; display: flex; flex-direction: column; justify-content: center; width: 100%;
  }
  /* The page itself becomes the card. */
  .auth-page {
    width: 100%;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 40px 40px 36px;
  }
  /* Inner cards melt into the one composition (no card inside a card). */
  .auth-page > .card,
  .auth-page .auth-card {
    background: transparent; border: none; box-shadow: none;
    border-radius: 0; padding: 0; margin-bottom: 0;
  }
  .auth-page > h1 { margin-top: 0; }
  .auth-page #l-email-form, .auth-page #s-email-form { margin-top: 16px; }
  /* The one-CTA-rail rules (Google slot centered in a 48px row, both
     house CTAs at 48px) live with the base auth styles above so they
     hold at every width, not just on desktop. */
}

/* ---------- §L. Tool detail: Donald's left rule + use the width ---------
   Donald (Oct 16, 2026): "If something is on the right that makes it a
   long page move it to the left" — and "We shouldn't have to scroll if
   there is space on the left side." §E put the purchase panel on the
   RIGHT and stacked every reading section into ONE tall column beside
   it (reading column measured 1,307px tall at 1440; page 1,836px).
   Now: the 360px action rail (glass card — sticky, pull-up, internal
   scroll, ad mid-format all unchanged from §E/§F) sits in the LEFT
   column; the reading sections take the RIGHT and flow in the layout's
   own two columns (main 1.4fr | side 1fr: About / safety / delivery /
   reviews beside pickup / availability / repair) instead of one tall
   stack, so the page uses its width and the scroll shrinks. Desktop
   only — below 1024px nothing here applies; the phone keeps its
   stacked order untouched. */
@media (min-width: 1024px) {
  .tool-detail .container:has(> .tool-glass-card) {
    grid-template-columns: 360px minmax(0, 1fr);
  }
  .tool-detail .tool-glass-card { grid-column: 1; grid-row: 1; }
  .tool-detail .detail-layout {
    grid-column: 2; grid-row: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
  }
}
@media (min-width: 1440px) {
  .tool-detail .container:has(> .tool-glass-card) {
    grid-template-columns: 360px minmax(0, 924px);
    justify-content: center;
  }
}

/* ---------- §M. Helper on desktop: calm panel, small pills ---------------
   Donald (Oct 16, 2026): the helper on a laptop "feels too busy" and
   its pills are "too big". Measured before (1440×900): on open, the
   panel presented 66 pill controls — a 920px hub (8 categories, 33
   chips at 30px/13px + 29 red → links) stuffed into a 369px message
   window, plus 40px-tall quick-question pills; the conversation was
   buried. Desktop helper pill system now: suggestion chips and answer
   buttons one uniform small pill — 28px tall / 12px; hub chips 24px /
   12px; the hub becomes a bounded, softly styled topics well
   (max-height 188px, its own quiet scroll) so the conversation is the
   panel's main content and suggestions stay secondary. Every topic
   and destination remains reachable; only presentation changes. The
   admin helper gets the same calm: its hub topics were .btn-tiny —
   10px ALL-CAPS pills — and its hub card alone was taller than the
   visible log. Desktop only: no rule below 1024px, phone untouched. */
@media (min-width: 1024px) {
  /* Panel: a touch wider/taller so the content breathes. */
  #chat-panel { width: min(400px, calc(100vw - 32px)); height: min(600px, calc(100dvh - 190px)); }
  .chat-header { padding: 11px 16px; }
  .chat-messages { padding: 14px; gap: 8px; }
  .chat-msg { font-size: 14px; padding: 9px 12px; }

  /* The hub: a bounded topics well, not a wall of pills. flex:none so
     the well keeps its height as the conversation grows (the messages
     column scrolls instead of squishing the well). */
  .chat-hub { flex: none; max-height: 188px; overflow-y: auto; padding: 9px 11px; scrollbar-width: thin; }
  .chat-hub-cat { font-size: 11px; margin: 8px 0 4px; }
  .chat-hub-row { gap: 5px; }
  .chat-hub-chip { font-size: 12px; padding: 3px 9px; border-color: rgba(2, 58, 80, 0.45); background: #faf8f4; }
  .chat-hub-open { font-size: 12px; padding: 2px 3px; opacity: 0.85; }

  /* Suggestion chips + answer buttons: one small uniform pill. */
  .chat-chips { padding: 6px 12px; }
  .chat-chips button { min-height: 28px; padding: 4px 11px; font-size: 12px; }
  .chat-links { margin-top: 7px; }
  .chat-link-btn { padding: 4px 10px; font-size: 12px; }

  /* Input row slims to match. */
  .chat-form { padding: 8px 12px; }
  .chat-form input { min-height: 40px; font-size: 14px; }

  /* Admin helper: bounded hub well + quiet, sentence-case topics.
     (The .btn-tiny desktop floor is !important, so the font-size here
     is too — scoped to the admin helper's own containers only.) */
  #ahlp-log .ahlp-hub { flex: none; max-height: 190px; overflow-y: auto; scrollbar-width: thin; }
  #ahlp-log .btn-tiny, #ahlp-chips .btn-tiny { font-size: 12px !important; text-transform: none; letter-spacing: 0; }
}
/* The 1024–1279 band keeps the pre-§M height cap: there the panel's
   bottom offset is larger (bottom-nav clearance), so the taller §M
   height could crowd the top of a short laptop screen. */
@media (min-width: 1024px) and (max-width: 1279px) {
  #chat-panel { height: min(560px, calc(100dvh - 240px)); }
}

/* ---------- §N. Group Share symmetry pass (Donald's Oct 16, 2026) --------
   Two defects Donald named after v117 went live — "The ad, and the
   group share banner were not aligned symmetrically" — plus his width
   rule: "We shouldn't have to scroll if there is space on the left
   side."
   (1) THE AD. On the groups list, group sales, and group storefronts
   the sponsored card spanned 880px beside ~250-430px cards, and its
   content cluster sat 99px LEFT of the card's own axis at every width
   (stage hard-left, 219px of dead space before the edge-pinned
   arrow). The slot now moves into the surface's grid as its first
   cell (groups.js _adCellIntoGrid, >=1024 only) and composes like a
   card: the designed 176x124 stage centered on top, copy centered
   below, no edge arrow. The one wide ad that remains — the thread
   page's — sits in that page's 880px reading column at exactly the
   column width; its internals are balanced the same way (cluster
   centered on the axis, no edge arrow), as are the market slots on
   the rare empty states where no grid exists to join.
   (2) THE BANNER + TAB STACK. The group page's centers already
   coincided, but the width rhythm alternated (header / tabs / subnav
   at the full measure, banner and tab cards at 880) and the tabs
   stacked into a scroll while the sides sat empty (sparse Dashboard
   scrolled 1,500px at 1440x900). At >=1024 the banner now takes the
   FULL content measure — its edges align with the content below it —
   and the tab bodies compose at that same measure: Requests in two
   columns, Threads / Calendar / Ideas / activity as card grids,
   Members on a wider grid, Dashboard charts in one row. One axis,
   one width, cards at natural size. The §G 880px caps on tab-body
   cards and headings are repealed by the rules below (same
   selectors, later block). The thread DETAIL page keeps an 880px
   reading column — a conversation surface — and its message and
   compose cards now join that column instead of spanning the
   container as 1,312px ribbons.
   Everything here is >=1024: phone and tablet layout are untouched
   (the JS moves are matchMedia-gated the same way). */
@media (min-width: 1024px) {
  /* — the banner takes the content measure — */
  .gs-sell-banner { max-width: none; }

  /* — the tab stack composes at the full measure — */
  #gs-tab-body > .card { max-width: none; }
  #gs-tab-body > h2, #gs-tab-body > h3, #gs-tab-body > p {
    max-width: none; margin-left: 0; margin-right: 0;
  }
  .gs-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 12px;
    align-items: start;
  }
  .gs-card-grid > .card { margin-bottom: 0 !important; }
  .gs-card-grid > .empty { grid-column: 1 / -1; }
  .gs-card-grid-wide { grid-template-columns: repeat(auto-fill, minmax(430px, 1fr)); }
  .gs-card-grid-wide > .card { flex-wrap: wrap; }
  .gs-req-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    align-items: start;
  }
  .gs-req-cols > section > h3 { margin-top: 14px !important; }
  .gs-dash-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    align-items: start;
  }
  .gs-dash-grid h4.mt { margin-top: 0; }

  /* — sponsored cells: the ad becomes a card in the grid — */
  #gs-list > .gs-ad-cell { grid-column: auto; }
  .gs-ad-cell {
    display: flex;
    flex-direction: column;
    min-width: 0;
    max-width: none !important;
    margin: 0 !important;
  }
  /* The slot's child is the .ad-unit now (Oct 21, 2026 structural
     fix): the UNIT fills the cell; inside it the card flexes and
     the reaction row rides under the card. (As a flex ROW this
     cell put the row beside the card — the same crush v175 fixed
     in the merch/storefront cells.) */
  .gs-ad-cell > .ad-unit { flex: 1; min-width: 0; }
  .gs-ad-cell .ad-card {
    max-width: none;
    height: auto;
    flex-direction: column;
    justify-content: center;
  }
  .gs-ad-cell a.ad-card {
    align-items: center;
    text-align: center;
    gap: 10px;
    padding: 18px;
  }
  .gs-ad-cell .ad-rot-layer {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 10px;
    padding: 18px;
    height: 100%;
  }
  .gs-ad-cell .ad-copy { padding-right: 0; max-height: none; }
  .gs-ad-cell .ad-card::after { display: none; }
  /* The §F slot rules carry ID specificity and outrank the generic
     cell rules above — restate the two that matter (copy measure,
     edge arrow) at ID scope for the slots that become cells. */
  #gs-list-ad.gs-ad-cell .ad-copy, #gms-ad-slot.gs-ad-cell .ad-copy {
    padding-right: 0; max-height: none;
  }
  #gs-list-ad.gs-ad-cell .ad-card::after, #gms-ad-slot.gs-ad-cell .ad-card::after {
    display: none;
  }
  /* Cells keep their natural height: a tall rotation frame must not
     stretch the neighboring group cards to its height (Donald's
     rule — cards keep natural size). */
  #gs-list { align-items: start; }

  /* Listing cards in the market grids fill their cell: §I's
     margin-auto centering (written for the storefront page's stacked
     section cards) leaks into grid items sharing .storefront-card
     and shrinks them to their min-content — a short listing on the
     group storefront rendered 141px wide in a 291px cell. */
  .gms-listings-grid > .storefront-card, #gms-list .storefront-card {
    margin-left: 0; margin-right: 0;
  }

  /* — thread page: one 880px reading column — */
  #gs-thread .card { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* — wide ads that remain on group surfaces: balanced on the axis — */
  #gs-thread-ad .ad-card { justify-content: center; }
  #gs-thread-ad .ad-rot-layer { justify-content: center; }
  #gs-thread-ad .ad-copy { padding-right: 0; }
  #gs-thread-ad .ad-card::after { display: none; }
  #gms-ad-slot:not(.gs-ad-cell) .ad-card { justify-content: center; }
  #gms-ad-slot:not(.gs-ad-cell) .ad-rot-layer { justify-content: center; }
  #gms-ad-slot:not(.gs-ad-cell) .ad-copy { padding-right: 0; }
  #gms-ad-slot:not(.gs-ad-cell) .ad-card::after { display: none; }
}

/* ---------- §O. Profile cards: one gutter, packed rows, no dead space ---
   Donald's orders (Oct 16, 2026): "organize the cards well on laptop so
   there's a gap" + "Try not to leave gaps between cards" + "If something
   is on the right that makes it a long page, move it to the left" + "We
   shouldn't have to scroll if there is space on the left side."
   Measured before (1440, full fixtures): the overview's cards lived only
   in the right column — the identity rail's content ended at y≈1,486
   while the right column ran to y≈3,066 (≈1,600px of idle left column);
   overview rows mismatched by up to 186px (align-items:start); widget
   cards stranded up to 272px of dead bottom; the member card's "How to
   use your card" block rode in the RIGHT column, 457px of text against
   the 346px card face.
   The fix (≥1280px): ONE gutter — 16px, the rhythm the card system
   already uses (card padding/margin) — applied to every gap in the
   profile: shell, card grids, widget grid, stat tiles, member card.
   The overview flattens into one 12-column grid: the identity rail
   takes the left 3 columns across two rows; widgets + the member card
   fill the 9 columns beside it (≈1,480px of content against the rail's
   ≈1,430px — both sides end together); deeper cards flow full-width
   below in 3-across rows that SHARE a height, with interiors arranged
   to fill (stat tiles center, button rows pin to the bottom, widget
   lists spread evenly, badge chips center) — no dead bottoms. The
   member card's how-to moves out of the right column into the main
   flow under the card face as a full-width 3-column strip; beside the
   face sits only the short actions stack. Settings (17 cards in one
   ≈4,050px column) packs into two balanced columns at natural heights
   with the same gutter, headings kept with their cards. Tools/bookings
   tabs audited: stacked rows already balanced against the rail —
   untouched. */
@media (min-width: 1280px) {
  /* Gate re-keyed (page reorganization, Oct 22, 2026): the §Z
     composition used to key on :has(#ov-widgets) — the widget band
     existed only with Advanced ON. The band is a door now; its
     always-present Advanced marker is #ov-today (Happening today),
     the identical condition. Rules below that name retired band
     elements (#ov-widgets, #ov-member-card-card, #ov-badges…) are
     inert — the packer's inline placement governs the door groups,
     the strip and the today slot.
     Gate re-keyed again + composition reordered (Donald's Oct 25,
     2026 order: "The profile card should always show up on top"):
     the old gate matched only with Advanced ON (#ov-today), so with
     Advanced OFF no composition applied at all — yet the packer
     still wrote its 12-column inline placements into the base
     300px/1fr grid, pushing the identity card to row 2 UNDER the
     body (measured: identity y=1149 vs sections y=74 at 1920). The
     gate is now #ov-stats — the numbers strip renders on the
     overview in BOTH Advanced states and on no other tab — and the
     identity card LEADS the grid (rows 1–2, cols 1–3), with the
     section strip on row 3 beneath it and the flow packing from
     row 1 beside the rail, exactly as the packer computes it. */
  .profile-layout:has(#ov-stats) {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 16px; align-items: stretch; grid-auto-flow: dense;
  }
  .profile-layout:has(#ov-stats) .profile-body,
  .profile-layout:has(#ov-stats) .profile-body > div:first-child { display: contents; }
  .profile-layout:has(#ov-stats) #tab-body { display: contents; }
  .profile-layout:has(#ov-stats) .profile-sections {
    grid-column: 1 / -1; grid-row: 3; margin-bottom: 0;
  }
  .profile-layout:has(#ov-stats) > .card {
    grid-column: 1 / span 3; grid-row: 1 / span 2;
    display: flex; flex-direction: column; margin-bottom: 0;
  }
  .profile-layout:has(#ov-stats) > .card #live-stats-slot,
  .profile-layout:has(#ov-stats) > .card #agents-slot { margin-top: auto; }
  .profile-layout:has(#ov-stats) #tab-body > * { margin-bottom: 0; min-width: 0; }
  .profile-layout:has(#ov-stats) #tab-body > #ov-widgets { grid-column: 4 / -1; grid-row: 2; }
  .profile-layout:has(#ov-stats) #tab-body > #ov-member-card-card { grid-column: 4 / -1; grid-row: 3; }
  .profile-layout:has(#ov-stats) #tab-body > .card {
    grid-column: span 4; display: flex; flex-direction: column;
  }
  /* §J's per-card rules for these two carry an extra :has ID and would
     otherwise squeeze them to span 2 — restate them at span 4. */
  .profile-layout:has(#ov-stats) #tab-body > .card:has(> #ov-badges),
  .profile-layout:has(#ov-stats) #tab-body > .card:has(> #ov-stats) { grid-column: span 4; }
  /* The member card keeps §J's internal grid — the generic card rule
     above must not turn it into a flex stack. */
  .profile-layout:has(#ov-stats) #tab-body > #ov-member-card-card { display: grid; }
  .profile-layout:has(#ov-stats) #tab-body > #ov-appreview-prompt {
    grid-column: span 6; display: flex;
  }
  .profile-layout:has(#ov-stats) #tab-body > #ov-appreview-prompt > * { flex: 1 1 auto; }
  .profile-layout:has(#ov-stats) #tab-body > .card:has(> #ov-appreview-line) { grid-column: span 6; }
  /* When the impact card has no data and stays hidden, the devices row
     widens so no grid cell is stranded empty. */
  .profile-layout:has(#ov-stats) #tab-body:has(> #ov-impact-card[hidden]) > #ov-errand-card,
  .profile-layout:has(#ov-stats) #tab-body:has(> #ov-impact-card[hidden]) > .card:has(> #ov-devices) { grid-column: span 6; }

  /* Interiors fill the shared row height — no dead bottoms. */
  .profile-layout:has(#ov-stats) #tab-body > .card > .btn-row { margin-top: auto; }
  .profile-layout:has(#ov-stats) #tab-body > .card > .stat-tiles { flex: 1 1 auto; gap: 16px; }
  .profile-layout:has(#ov-stats) #tab-body .stat-tiles .tile {
    display: flex; flex-direction: column; justify-content: center;
  }
  .profile-layout:has(#ov-stats) #ov-badges { flex: 1 1 auto; align-content: center; }
  .profile-layout:has(#ov-stats) #ov-activity {
    flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center;
  }

  /* Widgets: same 16px gutter; lists spread to fill the card. */
  .profile-layout:has(#ov-stats) #ov-widgets .widgets-head { margin-bottom: 16px; }
  .profile-layout:has(#ov-stats) #ov-widgets .widgets-grid { gap: 16px; }
  .profile-layout:has(#ov-stats) #ov-widgets .widget-card { display: flex; flex-direction: column; }
  .profile-layout:has(#ov-stats) #ov-widgets .widget-rows,
  .profile-layout:has(#ov-stats) #ov-widgets .widget-checklist {
    flex: 1 1 auto; display: flex; flex-direction: column; justify-content: space-evenly;
  }
  .profile-layout:has(#ov-stats) #ov-widgets .widget-card > .btn-row { margin-top: auto; }

  /* Member card: the how-to leaves the right column for the main flow
     under the card face (full-width strip, steps in three columns);
     beside the face only the short actions stack remains. */
  .profile-layout:has(#ov-stats) #ov-member-card-card { column-gap: 16px; row-gap: 16px; }
  .profile-layout:has(#ov-stats) #ov-member-card .mc-slider,
  .profile-layout:has(#ov-stats) #ov-member-card .mc-cards {
    grid-column: 1; grid-row: 2 / span 3; align-self: start;
  }
  .profile-layout:has(#ov-stats) #ov-member-card .mc-tap { grid-column: 2; grid-row: 2; align-self: start; }
  .profile-layout:has(#ov-stats) #ov-member-card-card > .btn-row { grid-column: 2; grid-row: 3; }
  .profile-layout:has(#ov-stats) #ov-member-card-card > p { grid-column: 2; grid-row: 4; align-self: end; }
  .profile-layout:has(#ov-stats) #ov-member-card .mc-howto {
    grid-column: 1 / -1; grid-row: 5; max-width: none; margin-top: 0;
  }
  .profile-layout:has(#ov-stats) #ov-member-card .mc-howto-list { columns: 3; column-gap: 16px; }

  /* Settings tab: two balanced columns at natural heights, same 16px
     gutter. (A grid was tried first and rejected: the tab interleaves
     h3 section headings between its cards, and grid cells tore each
     heading away from its card. Columns keep every heading with its
     card — break-inside/after: avoid — and balance the two sides.) */
  #tab-body:has(> #set-notif-prefs) { columns: 2; column-gap: 16px; }
  #tab-body:has(> #set-notif-prefs) > * { break-inside: avoid; min-width: 0; }
  #tab-body:has(> #set-notif-prefs) > h3 { break-after: avoid; }
}

/* ================================================================
   §T — Flip / swipe note-card decks (Donald's Oct 16, 2026 order:
   "For any procedure of use that is long organize it into flip
   cards users can flip through. It also helps us with tidying up
   the spaces.") A long read-only procedure renders as ONE tidy
   deck: one step per note card, swipeable via scroll-snap, with
   prev/next arrows, progress dots and an "n of N" counter.
   First use: "How to use your card" (PlusCardUI.deckHtml), which
   replaces the old stacked <ol> AND the §O three-column strip on
   the profile overview — the deck supersedes that treatment (the
   .mc-howto-list element no longer exists; the rules below pin
   the deck's own measure inside the profile's member-card grid).
   Deck-scoped rules only; applies at every width — swiping is the
   point on phone too. Static render, works offline. */
.tn-deck { max-width: 680px; margin: 0 auto; }
.mc-howto:has(> .tn-deck) { max-width: 680px; }
.tn-deck-h { text-align: center; font-size: 15px; margin: 0 0 10px; color: var(--mist-navy); }
.tn-deck-track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth; border-radius: 16px;
}
.tn-deck-track::-webkit-scrollbar { display: none; }
.tn-deck-card {
  flex: 0 0 100%; scroll-snap-align: start; box-sizing: border-box;
  display: flex; gap: 12px; align-items: flex-start;
  min-height: 124px; padding: 16px 18px;
  background: #fff; border: 1px solid var(--mist-line-2); border-radius: 16px;
  box-shadow: 0 10px 24px rgba(2, 41, 59, .10);
}
.tn-deck-card p { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.55; }
.tn-deck-card p strong { color: var(--mist-ink); }
.tn-deck-nav {
  display: flex; align-items: center; justify-content: center;
  gap: 14px; margin-top: 12px;
}
.tn-deck-btn {
  width: 36px; height: 36px; flex: 0 0 auto; border-radius: 50%;
  border: 1px solid var(--mist-line-2); background: #fff; color: var(--mist-navy);
  font-size: 19px; font-weight: 700; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(2, 41, 59, .12); padding: 0 0 2px;
}
.tn-deck-btn:disabled { opacity: .35; cursor: default; box-shadow: none; }
.tn-deck-dots { display: flex; align-items: center; gap: 7px; }
.tn-deck-dot {
  width: 8px; height: 8px; border-radius: 999px; border: 0; padding: 0;
  background: #CECFD4; cursor: pointer;
  transition: width .18s ease, background .18s ease;
}
.tn-deck-dot--on { width: 20px; background: #023A50; }
.tn-deck-count {
  font-size: 12px; font-weight: 600; color: var(--muted);
  min-width: 42px; text-align: center;
}
@media (prefers-reduced-motion: reduce) {
  .tn-deck-track { scroll-behavior: auto; }
  .tn-deck-dot { transition: none; }
}
/* Profile overview: §O lays .mc-howto out as a full-width strip in
   the member-card grid — the deck now lives in that same slot at
   its own tidy measure, centered, and the strip's column treatment
   of the old list is explicitly retired. */
.profile-layout:has(#ov-today) #ov-member-card .mc-howto-list { columns: auto; }
.profile-layout:has(#ov-today) #ov-member-card .tn-deck { margin-inline: auto; }

/* §U — Beta note (Donald's Oct 16, 2026 order: first-time users are told
   we're still building and in beta testing — keep checking back). One
   small sand-tinted note, rendered by WelcomeTour.betaNoteHtml() inside
   the signed-in panel, the visitor panel, the player modal, and on the
   #/welcome page. Calm by design: 12px muted body, navy title, never a
   banner. */
.wt-beta {
  margin: 14px auto 0; max-width: 400px; text-align: left;
  background: rgba(251, 209, 132, .22); border: 1px solid var(--sand);
  border-radius: 12px; padding: 10px 12px;
}
.wt-beta-title { margin: 0; font-size: 13px; font-weight: 700; color: var(--mist-navy); }
.wt-beta-body { margin: 2px 0 0; font-size: 12px; line-height: 1.5; color: var(--muted); }
/* On the #/welcome page the note sits on the page measure, centered
   between the intro and the player card. */
.wt-beta--page { max-width: 560px; margin: 18px auto 0; text-align: center; }
.wt-beta--page .wt-beta-body { margin-left: auto; margin-right: auto; max-width: 480px; }
/* The player modal is wider than the panels — keep the note on the
   video's own measure, left-aligned like the closing copy. */
.modal .wt-beta { margin-left: 0; margin-right: 0; max-width: none; }
.wt-panel .wt-beta { margin-left: auto; margin-right: auto; max-width: 400px; }

/* ---------- §P. Marketplace laptop audit (Donald's order, Oct 16, 2026) ----
   Full-page laptop audit of the marketplace cluster (Discover, tool page,
   booking/checkout, Wanted, Offers, Bundles, Services, Projects, Garages),
   measured at 1366/1440/1920 with full + sparse fixtures. Defects fixed
   here (all rules ≥1024px; phone untouched):
   1. Wanted board: request cards stretched the full container width
      (1,152/1,312/1,392px) with the action button marooned at the far
      edge. The board is now a grid — cards keep natural size and bigger
      screens fit more across (2 up, 3 up on wide screens).
   2. Projects picker: template choices were full-width BUTTONS up to
      1,392px wide. Same grid treatment; the picker form keeps the
      640px form measure used by the other create forms.
   3. Garage detail: the booking rail took a 1fr share (537px at 1440)
      and both "Book this garage" buttons stretched with it (503/714px).
      The layout now mirrors the booking pages (880 reading column +
      380 rail, centered), the rail card sticks like the tool page's,
      and the hero button is capped.
   4. Booking checkout: the step sheet's Continue / More options buttons
      stretched to 786px. Capped and centered inside the sheet.
   5. Booking gate pages (verification / card required): the checklist
      card stretched full width under a centered title. The gate now
      sits on the 880 reading measure, centered like the auth pages.
   6. Offers: the whole page lived in one full-width card (1,392px),
      its rows stretched to 1,278px. Capped at the 880 reading measure
      (messages/agreement pattern).
   7. Service detail: bare left-hugging text under a centered title —
      the content column now takes the same 880 centered measure.
   8. Bundle detail: rate / contents / booking cards stacked at full
      width (1,312px at 1440) and the "Book all N tools" button
      stretched to 1,278px — the widest button in the app. The page
      now uses the detail composition: reading column (rate + contents)
      beside a 380px booking rail (bundles.js wraps the two reading
      cards in .bd-main inside a new .bd-cols container).
   9. Project kit review: item cards stacked at full width and the
      checkout button stretched to 1,241px. The kit column takes the
      880 reading measure and the checkout button is capped at 400px,
      centered with its Back partner.
   10. Service booking form: the 640px form column hugged the left
      edge (title axis up to 376px off the page axis at 1920) and its
      Confirm button stretched to 569px. The column is centered and
      the button takes the same 400px cap as the kit checkout.
   ------------------------------------------------------------------------- */
@media (min-width: 1024px) {
  /* 1 — Wanted board grid */
  #w-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  #w-list .card { margin: 0; display: flex; }
  #w-list .card > div { flex: 1; align-items: center; }
  /* text block shrinks + wraps so the Offer button keeps the top line */
  #w-list .card > div > div:first-child { flex: 1; min-width: 0; }
  #w-list > .empty { grid-column: 1 / -1; }

  /* 2 — Projects picker grid + form measure */
  #pj-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  #pj-list .pj-tpl { margin: 0; }
  #pj-list > .empty { grid-column: 1 / -1; }
  #pj-form { max-width: 640px; margin-left: auto; margin-right: auto; }

  /* 3 — Garage detail: booking composition + sticky rail + capped hero CTA */
  .detail-layout:has(#g-booking) { grid-template-columns: minmax(0, 880px) 380px; justify-content: center; }
  #g-booking { position: sticky; top: calc(var(--header-h) + 16px); }
  #g-hero-book { max-width: 340px; }

  /* 4 — Checkout sheet buttons */
  .booking-layout .card.sheet .btn-block { max-width: 400px; margin-left: auto; margin-right: auto; }

  /* 5 — Booking gate pages */
  .booking-gate { max-width: 880px; margin-left: auto; margin-right: auto; }
  .booking-gate > p { text-align: center; }
  .booking-gate .btn-row { justify-content: center; }

  /* 6 — Offers pages keep the reading measure */
  .offers-page > .card { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* 7 — Service detail reading measure */
  #sv-detail { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* 8 — Bundle detail: reading column + booking rail */
  .bd-cols { display: grid; grid-template-columns: minmax(0, 880px) 380px; gap: 16px; justify-content: center; align-items: start; }
  .bd-main { display: grid; gap: 16px; min-width: 0; }
  .bd-main > .card, .bd-cols > .card, .bd-cols > .btn-row { margin: 0; }

  /* 9 — Project kit review measure + capped checkout */
  #pk-wrap { max-width: 880px; margin-left: auto; margin-right: auto; }
  #pk-wrap .btn-row { justify-content: center; }
  /* the button carries an inline flex:1 — the override must win over it */
  #pk-go { flex: 0 0 auto !important; width: min(400px, calc(100% - 76px)); }

  /* 10 — Service booking form: centered column + capped confirm */
  #view:has(#sb-wrap) .page { margin-inline: auto; }
  #sb-wrap .btn-row { justify-content: center; }
  #sb-go { flex: 0 0 auto !important; width: min(400px, calc(100% - 110px)); }
}
@media (min-width: 1600px) {
  #w-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #pj-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- §S. Admin cluster: laptop audit pass (Donald's Oct 16, 2026) --
   Measured in the full admin audit (1366/1440/1920, full + sparse data):
   the admin area never got the §A–§O desktop treatment, and five measured
   defects are corrected here — launcher buttons floated at a different
   height on every card (dead space under the button varied 17/35/53px
   across one row); Snapshot grid rows left dead holes under the shorter
   card (align-items:start, Δ up to ~130px); a lone Insights-engine finding
   card sat stranded in the left half of its grid, 331px off the page axis
   its own heading is centered on; Security Watch's feed/block pair ended
   at two heights; and lone member-lookup email fields (refunds, add-an-
   admin) stretched the full 1,272px card width. All rules ≥1024px only;
   phone rendering is untouched. (Appended after §U in file order — the
   audit sections were written concurrently.) */
@media (min-width: 1024px) {
  /* Launcher cards: the blurb grows, so every Open button in a row sits
     on one baseline at the card's foot. */
  .admin-group-card { display: flex; flex-direction: column; }
  .admin-group-card > p { flex: 1 0 auto; }
  /* Snapshot + Insights grids: cards in a row share the row's height —
     no dead hole under the shorter card. */
  .snap-grid { align-items: stretch; }
  /* Insights engine: a category with a single finding spans the grid,
     centered on the same axis as its heading. */
  #insights-body .snap-grid > .card:only-child { grid-column: 1 / -1; }
  /* Security Watch: Attack feed and Blocked addresses share one height. */
  .secw-cols { align-items: stretch; }
  /* Lone lookup fields keep a designed measure instead of stretching
     the full card (Refunds member email; Add-an-admin email). */
  #rf-email, #pa-email { max-width: 520px; }
}

/* ---------- §Q. Member cluster: laptop audit pass (Donald's Oct 16, 2026) --
   Measured at 1366/1440/1920 with full + sparse fixtures (audit-member
   harness). Defects corrected: the Messages inbox card stretched the
   full 1152–1392px container with row actions stranded at the far edge;
   the thread title sat −39px off its column axis (the Call button shared
   its flex row); the Calendar sync card ribboned full-width over the
   month grid; Referrals stacked three full-width cards; Tracker rows
   ribboned full-width with 47px-tall status chips; Perks stacked six
   full-width cards into a 2,449px scroll at 1440. All rules ≥1024px
   only; phone rendering untouched. */
@media (min-width: 1024px) {
  /* Messages: the inbox takes the same 880px reading measure the
     thread view already uses, on the same centered axis — group
     invite cards follow it so the stack keeps one axis. */
  #threads, #gs-invites .card { max-width: 880px; margin-inline: auto; }

  /* Thread view: the Call button pins to the header row's right edge,
     out of the title's centering math — the Conversation title now
     centers on the column's true axis. */
  #view:has(#msg-list) .page > div:has(> #call-btn) { position: relative; }
  #view:has(#msg-list) #call-btn { position: absolute; right: 0; top: 50%; transform: translateY(-50%); }

  /* Calendar: the sync card becomes a centered banner over the
     full-width month grid instead of a full-measure ribbon. */
  #cal-feed .card { max-width: 880px; margin-inline: auto; }

  /* Referrals: the hero card takes the 880 measure; the stats and
     redeem cards share that measure stacked, then pair up at ≥1280. */
  #view:has(.ref-cols) .card.center { max-width: 880px; margin-inline: auto; }
  .ref-cols { max-width: 880px; margin-inline: auto; }

  /* Tracker: the two sections pair up at ≥1280 (below that they stack
     on the 880 measure), and the status chips take the uniform 28px
     pill (they measured 47px tall). */
  .trk-cols { max-width: 880px; margin-inline: auto; }
  #trk-body .chip { height: 28px; min-height: 28px; padding: 0 12px; font-size: 12px; display: inline-flex; align-items: center; }

  /* Perks: the section stack caps at the 880 measure on smaller
     laptops; the composed two-column layout lives in the ≥1280 block. */
  #perks-sections > .card { max-width: 880px; margin-inline: auto; }
}
@media (min-width: 1280px) {
  /* Referrals: stats + redeem side by side under the centered hero. */
  .ref-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  .ref-cols > .card { margin: 0; }

  /* Tracker: "Out with someone" and "Tools I have" as two columns. */
  .trk-cols { max-width: none; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
  .trk-sec > h3 { margin-top: 0; }
  .trk-sec > .card:last-child { margin-bottom: 0; }

  /* Perks: the long Care card anchors the left column; the short
     program cards stack down the right; Priority help closes the
     stack as a full-width band. DOM order (and phone) unchanged. */
  #perks-sections {
    display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start;
    grid-template-areas: "care reg" "care partner" "care save" "care kits" "care pro" "prio prio";
  }
  #perks-sections > .card { max-width: none; margin: 0; }
  #perks-sections .perk-care { grid-area: care; }
  #perks-sections .perk-reg { grid-area: reg; }
  #perks-sections .perk-partner { grid-area: partner; }
  #perks-sections .perk-save { grid-area: save; }
  #perks-sections .perk-kits { grid-area: kits; }
  #perks-sections .perk-pro { grid-area: pro; }
  #perks-sections .perk-prio { grid-area: prio; }
}

/* ---------- §V. Admin Full Report (#/admin-report) ----------
   Donald's Oct 16, 2026 order: one button compiles all our data into
   ONE report with graphs and charts. Every rule is scoped to the
   report page (.rpt-* classes, used only by js/views/adminReport.js).
   Desktop-first composition (an admin laptop surface): KPI strip six
   across, sections two across with wide sections spanning; it still
   stacks sanely at phone width. Charts are hand-drawn SVG — the
   numbers always sit beside them. */
.rpt-actions { display: flex; justify-content: center; margin: 0 0 14px; }
.rpt-kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 16px; }
@media (min-width: 768px) { .rpt-kpis { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1280px) { .rpt-kpis { grid-template-columns: repeat(6, 1fr); } }
.rpt-kpi { text-align: center; margin: 0; }
.rpt-kpi-label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.rpt-kpi-value { font-size: 30px; font-weight: 800; color: var(--mist-navy, #023A50); margin: 4px 0 2px; line-height: 1.1; }
.rpt-kpi-delta { font-size: 12px; margin-bottom: 2px; }
.rpt-delta { color: var(--mist-navy, #023A50); font-weight: 600; }
.rpt-delta.na { color: var(--muted); font-weight: 400; }
.rpt-delta-note { color: var(--muted); font-weight: 400; font-size: 11px; }
.rpt-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 1024px) {
  .rpt-grid { grid-template-columns: 1fr 1fr; }
  .rpt-sec.rpt-wide { grid-column: 1 / -1; }
}
.rpt-sec { margin: 0; }
.rpt-chart { width: 100%; height: auto; display: block; }
.rpt-chart text { font-family: Inter, system-ui, sans-serif; }
.rpt-chart-max { font-size: 12px; font-weight: 700; fill: var(--mist-navy, #023A50); }
.rpt-chart-axis { font-size: 10px; fill: #8a8578; }
.rpt-hbar-label { font-size: 13px; fill: var(--mist-ink, #26231e); }
.rpt-hbar-value { font-size: 13px; font-weight: 700; fill: var(--mist-navy, #023A50); }
.rpt-chart-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 1024px) { .rpt-chart-grid { grid-template-columns: 1fr 1fr; } }
.rpt-caption { margin: 4px 0 12px; }
.rpt-stat { display: flex; align-items: baseline; gap: 10px; padding: 7px 2px; border-top: 1px solid var(--mist-line-2, #e6e1d3); }
.rpt-stat-label { flex: 1 1 auto; font-size: 13px; color: var(--mist-ink, #26231e); }
.rpt-stat-value { font-weight: 800; color: var(--mist-navy, #023A50); white-space: nowrap; }
.rpt-stat-delta { font-size: 12px; white-space: nowrap; }
.rpt-donut-wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; justify-content: center; }
.rpt-donut { width: 170px; height: 170px; flex: none; }
.rpt-donut text { font-family: Inter, system-ui, sans-serif; }
.rpt-donut-total { font-size: 30px; font-weight: 800; fill: var(--mist-navy, #023A50); }
.rpt-donut-label { font-size: 11px; fill: #8a8578; }
.rpt-legend { display: flex; flex-direction: column; gap: 6px; min-width: 170px; }
.rpt-legend-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.rpt-legend-dot { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.rpt-legend-label { flex: 1 1 auto; }
.rpt-botbox { background: var(--bg-soft, #faf8f2); border: 1px solid var(--mist-line-2, #e6e1d3); border-radius: 12px; padding: 14px; margin-top: 14px; }
.rpt-finding { border-top: 1px solid var(--mist-line-2, #e6e1d3); padding: 10px 2px; }
.rpt-finding-title { font-weight: 700; color: var(--mist-navy, #023A50); }
.rpt-notes { margin-top: 16px; }
@media print {
  .rpt-back, .rpt-page .analytics-nav, .rpt-page .pilot-pills, .rpt-actions,
  header, nav.bottom-dock, #chat-fab { display: none !important; }
  .rpt-grid { grid-template-columns: 1fr 1fr; }
  .rpt-sec, .rpt-kpi { break-inside: avoid; box-shadow: none !important; }
  body { background: #fff; }
}

/* ---------- §R. Business / Pro / Invoices / Public audit pass (Oct 16, 2026) -
   Donald's full laptop audit, Business/Pro/Invoices/Public cluster.
   Measured defects (1366/1440/1920, full + sparse fixtures; journal:
   audit-business-journal.md): the Business hub was ONE giant full-width
   card with everything stacked (stat tiles 3-across left a 2/3-row hole;
   analytics + Stock Connect cards each spanned the whole measure); the
   Contractor Pro page, the contractor public page and the storefront
   reviews card are document cards that missed the 880px measure §I gave
   their siblings; the invoice pay page stretched its receipt full-width
   with a 1,278px Pay button; bare .input fields (styled only inside
   .field) rendered raw in this cluster's forms; the storefronts filter
   bar hid chips behind an invisible scroll; a comment's Remove button
   stretched into a 72x74 circle. All rules >=1024px; phone untouched. */
@media (min-width: 1024px) {

  /* R1 — Business hub: compose the interior, one 16px rhythm. */
  .biz-page > h3 { text-align: center; }
  .biz-hub-card .stat-tiles { grid-template-columns: repeat(4, 1fr); gap: 16px; }
  .biz-hub-card [id^="biz-analytics-"] { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  .biz-hub-card [id^="biz-analytics-"] > .card { margin-bottom: 0; }
  .biz-hub-card [id^="biz-analytics-"] > h4 { grid-column: 1 / -1; margin-top: 0; }
  .biz-hub-card [id^="biz-analytics-"] > .card:nth-of-type(1),
  .biz-hub-card [id^="biz-analytics-"] > .card:nth-of-type(4) { grid-column: 1 / -1; }
  .biz-hub-card #biz-connections { display: flex; flex-wrap: wrap; gap: 16px; }
  .biz-hub-card #biz-connections > * { flex: 1 1 100%; min-width: 0; margin-top: 0 !important; }
  .biz-hub-card #biz-connections > .card { margin-bottom: 0; }
  .biz-hub-card #biz-connections > .card:not(:first-child),
  .biz-hub-card #biz-connections > #biz-snippet { flex: 1 1 calc(33.333% - 11px); }
  .biz-hub-card #biz-connections > #biz-snippet:empty { display: none; }
  .biz-hub-card #biz-connections > #biz-snippet > .card { height: 100%; margin-top: 0 !important; margin-bottom: 0; box-sizing: border-box; }
  .biz-hub-card #biz-connections .field { max-width: 720px; }
  .biz-hub-card [id^="bizapi-"] > .card { max-width: 880px; margin-left: auto; margin-right: auto; }
  .biz-hub-card [id^="bizapi-"] > .card .field { max-width: 720px; }

  /* R2 — Member-invoices area: one document measure on both host pages. */
  #member-invoices > .card { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* R3 — Contractor Pro page: document measure; the apply form tighter;
     the three btn-block actions in this cluster keep a natural width. */
  .pro-page .card { max-width: 880px; margin-left: auto; margin-right: auto; }
  .pro-page .card:has(#pro-apply) { max-width: 560px; }
  #pro-apply, #cpro-subscribe, .invoice-pay-page #pay-go { max-width: 440px; margin-left: auto; margin-right: auto; }

  /* R4 — Bare .input fields in this cluster's forms get the .field
     design (app.css styles inputs only inside .field; these forms use
     the class bare, so they rendered as raw browser inputs). */
  .pro-page .input, .invoice-pay-page .input, #member-invoices .input, #sf-q {
    width: 100%; min-height: 48px; border: 2px solid var(--border);
    border-radius: var(--radius-sm); padding: 10px 14px; font-size: 16px;
    font-family: var(--font); background: #fff; color: var(--text);
  }
  .pro-page .input:focus, .invoice-pay-page .input:focus, #member-invoices .input:focus, #sf-q:focus { border-color: var(--navy); outline: none; }

  /* R5 — Contractor public page joins the storefront measure. */
  #c-profile > .card { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* R6 — Invoice pay page: the receipt keeps a document measure. */
  .invoice-pay-page > .card { max-width: 640px; margin-left: auto; margin-right: auto; }

  /* R7 — Storefront reviews card matches its 880px siblings (§I's
     sibling rule missed it: the comments chunk between them is a div). */
  .sf-reviews-card { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* R8 — Comments: the Remove button keeps its natural pill size
     (the flex row stretched it to the row's full height). */
  #pub-comments [data-del-comment] { align-self: flex-start; }

  /* R9 — Storefronts directory: every filter chip visible + centered
     (the 720px bar hid chips behind a scrollbar-free scroll area). */
  #sf-rf { max-width: 880px !important; flex-wrap: wrap; overflow-x: visible; justify-content: center; }
}

/* ---------- §Q (continued). Member cluster: changelog --------------- */
@media (min-width: 1024px) {
  /* Changelog: the intro line centers on the title's axis, entries
     take the 880 reading measure, and the idea card follows. */
  #view:has(#cl-list) .page > p.muted { text-align: center; }
  #cl-list > .card, #view:has(#cl-list) .card.mt { max-width: 880px; margin-inline: auto; }
}
@media (min-width: 1280px) {
  /* Changelog entries are short notes — two across; the idea card
     stays on the centered measure beneath them. */
  #cl-list { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  #cl-list > .card { max-width: none; margin: 0; }
}

/* ---------- §Q (continued). Member cluster: transactions ------------ */
@media (min-width: 1024px) {
  /* Transactions: the intro line centers on the title's axis, and the
     filter fields take the design system's desktop field height —
     the bare .input class has no base height in this stylesheet, so
     they rendered at the browser default (19–21px measured). */
  #view:has(#tx-body) .page > p.muted { text-align: center; }
  #view:has(#tx-body) .input { min-height: 48px; padding: 10px 12px; font-size: 14px; box-sizing: border-box; }

  /* Receipt: the action row takes the document's own 560px measure,
     so Back / PDF / Email / Print align with the receipt card's edges
     instead of the full container's. */
  #tx-receipt > .btn-row { max-width: 560px; margin-inline: auto; }
}

/* ---------- §Q (continued). Member cluster: plans, plus, reviews,
   support, merch detail, advertise, payment methods ----------------- */
@media (min-width: 1024px) {
  /* Plans hub: plan cards become flex columns and every CTA pins to
     the card's foot — the three Subscribe/Manage buttons share one
     baseline (the Plus card's shorter list left 122–149px of dead
     space under its button). */
  .plan-card { display: flex; flex-direction: column; }
  .plan-card .btn-row { margin-top: auto; }

  /* Plus page (both the pitch and the active-member render): the card
     stack takes the 880 measure instead of full-width ribbons whose
     plan-pick buttons measured 553–673px and whose subscribe CTA
     measured 1,118–1,358px. The CTA itself caps at the plan-card
     width used on the hub. */
  #view:has(#plus-subscribe) .page > .card, #view:has(#plus-cancel) .page > .card { max-width: 880px; margin-inline: auto; }
  #plus-subscribe { max-width: 400px; margin-inline: auto; }

  /* App reviews: summary + editor take the 880 measure; the review
     wall shares it, then pairs up at ≥1280. */
  .apprev-summary, .apprev-editor { max-width: 880px; margin-inline: auto; }
  #ar-wall { max-width: 880px; margin-inline: auto; }

  /* Support: the long intro + legal lines take a reading measure
     inside the centered head (they ran the full 1,152–1,392px). */
  .support-head .page-desc, .support-head > p.small { max-width: 720px; }

  /* Merch detail: the 1.05fr hero (652px square) towered 328px over
     the info card. The hero takes a natural 460px column, the info
     card matches it at a capped 600px, both share one height, and
     the info card's last action row pins to its foot. */
  .merch-detail { grid-template-columns: minmax(0, 460px) minmax(0, 600px); justify-content: center; gap: 32px; align-items: stretch; }
  .merch-detail > .card:last-child { display: flex; flex-direction: column; }
  .merch-detail > .card:last-child .btn-row:last-of-type { margin-top: auto; }
  /* The Cart / Continue links carry an inline flex:1 (full-width on
     phone, by design there) — on desktop they take natural width.
     The Add-to-cart button keeps its flex (the buy row's primary). */
  .merch-detail > .card:last-child .btn-row > a.btn-outline { flex: 0 0 auto !important; }
  .merch-detail .input { min-height: 44px; padding: 8px 10px; box-sizing: border-box; }

  /* Advertise: below 1280 the studio keeps its designed 640 form
     measure (formerly an inline cap); the two-column layout is in
     the ≥1280 block. */
  .ad-page { max-width: 640px; margin-inline: auto; }

  /* Payment methods: the intro centers on the title's axis; the
     Cards/Bank stack takes the 880 measure (full-width ribbons
     before), pairing at ≥1280. */
  #view:has(#pm-body) .page > p.muted { text-align: center; }
  #pm-body { max-width: 880px; margin-inline: auto; }
}
@media (min-width: 1280px) {
  /* App reviews wall: two across. */
  #ar-wall { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  #ar-wall > .card { margin: 0; }

  /* Payment methods: Cards and Bank accounts side by side. */
  #pm-body { max-width: none; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  #pm-body > .card { margin: 0; }

  /* Advertise: studio steps run down the left at their 640 measure;
     "Your ads" rides the right column, sticky, so a member watches
     their ads while building the next one — the page no longer
     scrolls 2,549px past empty sides. */
  .ad-page { max-width: none !important; display: grid; grid-template-columns: minmax(0, 640px) 1fr; gap: 16px; align-items: start; }
  .ad-page > .page-head-centered { grid-column: 1 / -1; }
  .ad-page > div:nth-of-type(2), .ad-page > div:nth-of-type(3), .ad-page > div:nth-of-type(4) { grid-column: 1; }
  .ad-page > div:nth-of-type(5) { grid-column: 2; grid-row: 2 / span 3; position: sticky; top: 84px; }
}

/* §W — Welcome notification card (Oct 17, 2026): the in-app twin of the
   welcome email, same family — navy band with the official logo
   centered, centered title, personal-link row, the sign-off. */
.notif-welcome { padding: 0; overflow: hidden; }
.notif-welcome-band { background: #023A50; padding: 20px 16px 16px; text-align: center; }
.notif-welcome-band img { display: block; margin: 0 auto; width: 120px; max-width: 120px; height: auto; }
.notif-welcome-body { padding: 18px 22px 20px; text-align: center; }
.notif-welcome-title { display: block; font-size: 17px; color: #023A50; margin-bottom: 8px; }
.notif-welcome-text { margin: 0 0 12px; font-size: 14px; line-height: 1.55; color: #22333d; }
.notif-welcome-link { margin: 0 0 14px; font-size: 13px; line-height: 1.5; word-break: break-all; }
.notif-welcome-link a { color: #023A50; font-weight: 600; }
.notif-welcome-sign { margin: 4px 0 10px; font-size: 14px; font-weight: 600; color: #023A50; }

/* ---------- §X. Profile QR codes: Public | Private toggle ------------
   (Donald's Oct 17, 2026 order: "organize the QR codes into a toggle,
   label the toggle public and private. the private is for the handover
   code" — one card, one segmented toggle above a single centered stage,
   replacing the two side-by-side QR / handover cards. Same family as
   .merch-view-switch: card pill rail, navy active segment, soft layered
   shadow. The laptop grid slot is unchanged — the §O-family rule keys on
   #ov-qr-slot, still a direct child of the card.) */
#ov-codes-card > h3 { text-align: center; }
.qrt-toggle {
  display: flex; gap: 2px; width: fit-content; margin: 4px auto 6px;
  background: var(--card); border: 1px solid var(--border); border-radius: 999px; padding: 3px;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 8px 20px rgba(2, 32, 71, 0.10);
}
.qrt-seg {
  border: 0; background: transparent; padding: 7px 26px; border-radius: 999px;
  font: 600 13px 'Inter', sans-serif; color: var(--muted); cursor: pointer;
}
.qrt-seg.on {
  background: var(--navy); color: #fff;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.12), 0 6px 14px rgba(2, 32, 71, 0.18);
}
.qrt-stage { max-width: 200px; margin: 10px auto 4px; }
.qrt-stage svg { display: block; width: 100%; height: auto; }
#ov-codes-card .qrt-link { word-break: break-all; margin: 2px 0 10px; }
#ov-codes-card .btn-row { justify-content: center; }
#ov-qr-pane-private .small { max-width: 460px; margin-left: auto; margin-right: auto; }
#ov-qr-pane-private p.center { margin-top: 10px; }

/* ---------- §Y. Admin Live (Oct 17, 2026) ----------------------------
   #/admin-live: the real-time analytics page. Composed centered
   cards at natural size in a measure-based grid (Donald's rule:
   bigger screens fit MORE cards, cards never stretch), one
   consistent 16px gap, soft shadows, Inter, muted 12px notes.
   The status dot pulses only while the page is actually refreshing;
   it goes still and gray when paused or hidden — the paint never
   claims to be fresher than it is. */
.live-statusbar { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 14px; }
.live-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--mist-red); flex: none; animation: live-pulse 2s ease-in-out infinite; }
.live-dot.off { background: var(--mist-faint); animation: none; }
@keyframes live-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(246, 4, 12, .35); } 50% { box-shadow: 0 0 0 6px rgba(246, 4, 12, 0); } }
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }
.live-h { margin: 18px 0 10px; }
.live-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 16px; max-width: 1080px; margin: 0 auto; }
/* Desktop: fixed natural-size 200px tracks — short groups center under
   their titles instead of stretching (Donald's no-stretch rule). */
@media (min-width: 1024px) {
  .live-grid { grid-template-columns: repeat(auto-fit, 200px); justify-content: center; }
}
.live-card { background: var(--mist-surface); border: 1px solid var(--mist-hairline); border-radius: 14px; box-shadow: 0 10px 30px rgba(38, 35, 30, .10); padding: 16px 12px 13px; text-align: center; }
.live-big { font-size: 28px; font-weight: 800; color: var(--mist-navy); line-height: 1.15; }
.live-label { font-weight: 700; margin-top: 2px; }
.live-card .small { margin-top: 3px; line-height: 1.45; }
.live-feed-card { max-width: 880px; margin: 22px auto 0; }
.live-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 4px; border-top: 1px solid var(--mist-line-2); text-align: left; }
.live-row:first-child { border-top: none; }
.live-row-icon { font-size: 17px; line-height: 1.35; flex: none; width: 24px; text-align: center; }
.live-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.live-row-text { line-height: 1.4; }
.live-row-time { flex: none; white-space: nowrap; padding-top: 2px; }

/* §Y — Placement-fit composition (Donald's Oct 17, 2026: ads must be
   placed in spaces that complement the design; a creative is COMPOSED
   on the slot's designed letterbox stage — aspect preserved, never
   stretched, never awkwardly cropped). Graphic ad creatives carry the
   `ad-media` class (AdMedia.html). Card stages that used to center-crop
   graphics (object-fit: cover, meant for tool photos) now letterbox ad
   graphics on the same navy stage videos have always used. ONLY the
   fit changes — every box keeps its designed size, so slot geometry is
   identical for every creative (the symmetry invariant). Tool photos
   and member photos are untouched (no ad-media class). */
.tool-card img.tool-photo.ad-media { object-fit: contain; background: #10181c; }
.pool-photo img.ad-media { object-fit: contain; background: #10181c; }

/* ---------- §Z. Profile: dynamic reorganization (Donald's Oct 17, 2026) --
   "Make the profiles dynamic where the cards can reorganize themselves
   if something got toggled off — reorganize to make the profile cleaner
   and easier to navigate" + his hard constraint: "Nothing gets
   distorted" — cards MOVE, they never change shape.
   Measured before (harness, 1440): §O's flattened 12-col composition
   was gated on :has(#ov-widgets), so flipping Advanced OFF collapsed
   the whole dashboard into one 988px column of full-width cards
   (page 2,445px, every card stretched to the column). With Advanced ON
   the composition held, but §J's `order` values leaked into §O's grid
   (the Welcome card visually jumped into the FIRST flow row; impact /
   activity / QR read out of order in every state) and one flow row
   (errand + devices) stranded cols 8–11 empty mid-composition in
   EVERY advanced-on state; with impact hidden, §O's blind widen rule
   widened errand/devices while the actual hole sat in the row above.
   The fix: the composition now keys on the overview itself
   (#ov-member-card-card exists in BOTH Advanced states) instead of on
   a widget that only exists in one, and a state-driven packer in
   profile.js (Profile.packOverview) assigns each visible card an
   explicit grid slot computed from the cards actually present —
   sections on row 1, the identity rail spanning the band rows beside
   widgets / member card, flow cards packed in reading order below at
   their designed spans (4, or 6 for the review pair), closing each
   row exactly by widening a flexible card 4→6 (the §O precedent,
   generalized). No card ever takes a width outside its designed span
   classes; hidden/absent cards leave no reserved space because the
   pack is recomputed from the live set every time it changes.
   Below 1280px nothing here applies — the stacked layouts were
   measured clean (uniform 15–19px gaps, hidden cards reserve 0px).
   AMENDMENT (Oct 25, 2026, Donald's order — the profile card always
   on top): the packer now places the identity rail at rows 1–2 with
   flow beside it from row 1, and the sections strip at row 3; the
   live composition gate lives in §O, re-keyed to :has(#ov-stats) so
   it governs the overview in BOTH Advanced states (this §Z block's
   own gate never matches the post-reorganization overview). */
@media (min-width: 1280px) {
  .profile-layout:has(#ov-member-card-card) {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 16px; align-items: stretch;
  }
  .profile-layout:has(#ov-member-card-card) .profile-body,
  .profile-layout:has(#ov-member-card-card) .profile-body > div:first-child { display: contents; }
  .profile-layout:has(#ov-member-card-card) #tab-body { display: contents; }
  .profile-layout:has(#ov-member-card-card) .profile-sections {
    margin-bottom: 0; margin-top: 0 !important;
  }
  .profile-layout:has(#ov-member-card-card) #tab-body > * { margin-bottom: 0; min-width: 0; }
  /* The section headings live inside the flattened flow only in the
     stacked layouts; the composed grid carries no loose headings
     (§J hid them in the Advanced-on composition — now both states). */
  .profile-layout:has(#ov-member-card-card) #tab-body > h3 { display: none; }
  .profile-layout:has(#ov-member-card-card) > .card {
    display: flex; flex-direction: column; margin-bottom: 0;
  }
  .profile-layout:has(#ov-member-card-card) > .card #live-stats-slot,
  .profile-layout:has(#ov-member-card-card) > .card #agents-slot { margin-top: auto; }
  .profile-layout:has(#ov-member-card-card) #tab-body > .card {
    display: flex; flex-direction: column;
  }
  /* The member card keeps its internal grid — the generic card rule
     above must not turn it into a flex stack (same restatement §O made). */
  .profile-layout:has(#ov-member-card-card) #tab-body > #ov-member-card-card { display: grid; }
  .profile-layout:has(#ov-member-card-card) #tab-body > #ov-appreview-prompt {
    display: flex;
  }
  .profile-layout:has(#ov-member-card-card) #tab-body > #ov-appreview-prompt > * { flex: 1 1 auto; }

  /* Interiors fill the shared row height — no dead bottoms (§O's rules,
     now in both Advanced states). */
  .profile-layout:has(#ov-member-card-card) #tab-body > .card > .btn-row { margin-top: auto; }
  .profile-layout:has(#ov-member-card-card) #tab-body > .card > .stat-tiles { flex: 1 1 auto; gap: 16px; }
  .profile-layout:has(#ov-member-card-card) #tab-body .stat-tiles .tile {
    display: flex; flex-direction: column; justify-content: center;
  }
  .profile-layout:has(#ov-member-card-card) #ov-badges { flex: 1 1 auto; align-content: center; }
  .profile-layout:has(#ov-member-card-card) #ov-activity {
    flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center;
  }

  /* Widgets: same 16px gutter; lists spread to fill the card. */
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widgets-head { margin-bottom: 16px; }
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widgets-grid { gap: 16px; }
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widget-card { display: flex; flex-direction: column; }
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widget-rows,
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widget-checklist {
    flex: 1 1 auto; display: flex; flex-direction: column; justify-content: space-evenly;
  }
  .profile-layout:has(#ov-member-card-card) #ov-widgets .widget-card > .btn-row { margin-top: auto; }

  /* Member card composition (§O's, both states): face at its natural
     measure, the short actions stack beside it, the how-to as a
     full-width strip in the main flow under the face. */
  .profile-layout:has(#ov-member-card-card) #ov-member-card-card { column-gap: 16px; row-gap: 16px; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-slider,
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-cards {
    grid-column: 1; grid-row: 2 / span 3; align-self: start;
  }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-tap { grid-column: 2; grid-row: 2; align-self: start; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card-card > .btn-row { grid-column: 2; grid-row: 3; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card-card > p { grid-column: 2; grid-row: 4; align-self: end; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-howto {
    grid-column: 1 / -1; grid-row: 5; max-width: none; margin-top: 0;
  }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-howto-list { columns: 3; column-gap: 16px; }
}

/* ---------- §AA. Super-admin profile layout reorder (Donald's Oct 17,
   2026) ----------
   Reorder mode exists only on the super admin's own profile (the
   control is never rendered for anyone else; the server gates the
   saved layout to super admins). Cards gain a grip handle; the dragged
   card is outlined, never resized (the distortion law — only its
   position in the order changes, and the §Z packer re-packs live).
   The rail-side swap: below the composed breakpoint the two-column
   grid mirrors via order + template; in the composed grid the packer
   places the rail explicitly, so no rule here fights it. */
.ov-reordering [data-ov-card] { position: relative; }
.ov-reordering [data-ov-card] > :not(.ov-grip) { pointer-events: none; }
.ov-grip {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  width: 38px; height: 38px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card);
  color: var(--navy); font-size: 17px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  box-shadow: 0 1px 2px rgba(2, 32, 71, 0.06), 0 8px 20px rgba(2, 32, 71, 0.10);
}
.ov-grip:active { cursor: grabbing; }
.ov-dragging {
  outline: 2px solid var(--navy); outline-offset: 2px;
  opacity: 0.92;
  box-shadow: 0 2px 4px rgba(2, 32, 71, 0.10), 0 16px 34px rgba(2, 32, 71, 0.20);
}
.ov-tab-drag { cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none; }
.ov-tab-drag:active { cursor: grabbing; }
.ov-reorder-panel .qrt-toggle { margin-left: auto; margin-right: auto; }
@media (min-width: 1024px) {
  .profile-layout.ov-rail-right { grid-template-columns: 1fr 300px; }
  .profile-layout.ov-rail-right > .card { order: 2; }
  .profile-layout.ov-rail-right > .profile-body { order: 1; }
}

/* ---------- §AB. Esthetic sweep + Centering Law (Donald's Oct 17, 2026) --
   Measured in hidden_files/esthetic-sweep-repro (catalog.md). Append-only;
   no earlier rule is modified — these rules win by order/specificity. */

/* AB1 — Perks: when the Care anchor card is absent (guests, states
   without it), §Q's named-area grid strands every present card in
   column 2 (rows off +332px, left half empty — catalog S1-1). Without
   the anchor, the sections flow as a balanced two-column composition:
   cards auto-place in DOM order, and an odd last card closes the
   composition as a centered full-width band instead of hugging left.
   With the anchor present, §Q's composed layout is untouched. */
@media (min-width: 1280px) {
  #perks-sections:not(:has(> .perk-care)) { grid-template-areas: none; }
  #perks-sections:not(:has(> .perk-care)) > .card { grid-area: auto; }
  #perks-sections:not(:has(> .perk-care)) > .card:last-child:nth-child(odd):not(:only-child) { grid-column: 1 / -1; }
}

/* AB2 — Merch grid: a short final row centers as a group (Centering
   Law; measured off −397px @1440, −123px @768 for a 2-of-4 row). At
   ≥1024 the grid becomes a centered flex wrap with the SAME card
   measure (3 across, 4 across at ≥1440, 12px gap) — full rows are
   pixel-identical to the grid; only short rows move to the axis.
   Below 1024 the 2-column grid is unchanged. */
@media (min-width: 1024px) {
  .merch-grid { display: flex; flex-wrap: wrap; justify-content: center; }
  .merch-grid > * { flex: 0 1 calc((100% - 24px) / 3); }
}
@media (min-width: 1440px) {
  .merch-grid > * { flex-basis: calc((100% - 36px) / 4); }
}

/* AB3 — The base .input rule (catalog S2-5): inputs were styled only
   inside .field or page-scoped patches (§R4, §Q), so a bare .input
   anywhere else fell back to browser defaults. This base mirrors
   .field input exactly; every contextual rule carries higher
   specificity and still wins, and inline widths still govern. */
.input {
  width: 100%; min-height: 48px; box-sizing: border-box;
  border: 2px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 14px; font-size: 16px; font-family: var(--font);
  background: #fff; color: var(--text);
}
.input:focus { border-color: var(--navy); outline: none; }

/* AB4 — Calendar toolbar (catalog S3-10): the second toolbar row
   split its two button groups across a flex spacer, so at phone
   widths the five buttons wrapped into uneven scattered lines. The
   row now reads as ONE centered cluster (the spacer span is
   retired by display:none — its inline flex no longer applies);
   button ids, order and function are unchanged. */
#cal-body .btn-row + .btn-row { justify-content: center; }
#cal-body .btn-row + .btn-row > span { display: none; }

/* AB5 — Ad Credits (catalog S3-11): the page's sparse document cards
   spanned the full 1312px measure with mostly-empty interiors. They
   take the 880px centered measure §Q gave the sibling member
   document stacks (referrals, tracker). Scoped by the page's own
   redeem field so no other page can match. */
@media (min-width: 1024px) {
  #view .page:has(#adcredit-code) > .card { max-width: 880px; margin-inline: auto; }
}

/* ---------- §AC. Esthetic follow-ups — profile interiors + settings
   axis (Donald's Oct 17, 2026; sweep catalog #6 + #7) --
   Measured before/after in hidden_files/esthetic-sweep-repro
   (probe-fu.js; measurements-fu-*.json). Append-only; no earlier rule
   is modified — these rules win by order/specificity. */

/* AC1 — Settings axis (catalog #7): §O packed the settings tab into
   two balanced MULTICOL stacks — two independent column axes, so
   cards zig-zagged ±251px across the 988px body (per-card centroid
   offsets alternating −251/+251) and no two cards ever shared a
   row. Under the Centering Law the tab now stacks on ONE shared
   axis: every card and heading takes the 880px centered measure
   (the §Q measure for member document stacks — referrals, tracker,
   ad credits), so each card's centroid sits on the body axis
   (offset 0) and headings stand directly above their cards.
   Pairing the cards into rows instead was measured and rejected:
   the tab's heights vary too much (a ~640px notifications card
   beside ~180px cards), so row-pairing wasted ~1,500px to line-max
   slack and stranded a single before every heading. DOM order,
   grouping, and every setting's function are unchanged. */
@media (min-width: 1280px) {
  #tab-body:has(> #set-notif-prefs) {
    columns: auto; column-gap: normal;
    display: flex; flex-direction: column; align-items: center; gap: 16px;
  }
  #tab-body:has(> #set-notif-prefs) > * {
    flex: 0 0 auto; width: 880px; max-width: 100%; min-width: 0;
    margin-bottom: 0; break-inside: auto;
  }
  /* The content wrapper shrink-wraps to the 880 stack inside the
     988 body cell (§J's column flex, align-items: start) — center
     the wrapper itself so the stack's axis IS the body axis. */
  .profile-body > div:first-child:has(#set-notif-prefs) {
    margin-inline: auto;
  }
}

/* AC2 — Overview stat tiles share one height (catalog #6): in the
   badges / Quick stats / Your impact row (all three cards 245px),
   Quick stats' tiles flex-filled 148px while Your impact's filled
   only 106 — impact's interior carried a Share button row and an
   empty trend slot's margin beneath its tiles. The Share button
   now rides in a header row level with the title (profile.js
   .ov-head-row), an empty trend slot reserves nothing (the §Z
   doctrine), and overview card header blocks take one shared
   height — so both stat cards' tile areas flex-fill identically
   and the tiles share a height, like the cards themselves do. */
#ov-impact-trend:empty { display: none; }
@media (min-width: 1280px) {
  .profile-layout:has(#ov-member-card-card) #tab-body > .card > .ov-head-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; min-height: 32px; margin-bottom: 12px;
  }
  .profile-layout:has(#ov-member-card-card) #tab-body > .card > .ov-head-row h3 { margin: 0; }
  .profile-layout:has(#ov-member-card-card) #tab-body > .card:not(#ov-member-card-card) > h3 {
    min-height: 32px; display: flex; align-items: center; margin-bottom: 12px;
  }
}

/* AC3 — Member card right column (catalog #6): beside the card
   face, the tap note, the actions row and the fine print were each
   pinned to the top of a tall grid row (the face spans rows 2–4),
   leaving ~300px of unbalanced dead space down the right column.
   The stack now distributes over the face's height: the tap note
   centers in its row, the actions center in theirs (the §Z
   margin-top:auto that bottom-pins flex-card button rows is
   lifted for this grid item so centering can take effect), and
   the fine print keeps its designed bottom anchor, level with
   the slider's bottom edge. No cell moves and no box changes
   size — the face and the QR keep their exact measures. */
@media (min-width: 1280px) {
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-tap {
    align-self: stretch; display: flex; flex-direction: column; justify-content: center;
  }
  .profile-layout:has(#ov-member-card-card) #tab-body > #ov-member-card-card > .btn-row {
    align-self: center; margin-top: 0;
  }
}

/* ---------- §AD. Studio fix pack (Donald's Oct 17, 2026) ---------- */

/* AD1 — Visually hidden, but PRESENT in the accessibility/control
   tree (F1): the Ad Studio's file input used the bare `hidden`
   attribute, which removes the element from the control tree
   entirely and made it unreachable for browser automation tooling.
   This class keeps the input invisible to every human (the "📤
   Upload photo or video" button remains the only visible control
   and still forwards its click) while the input itself stays a
   real, targetable control. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  margin: 0; padding: 0; border: 0;
}

/* ---------- §AE. Studio upload overlay (Donald's Oct 17, 2026) ---------- */

/* AE1 — the Ad Studio's file input AS its own upload target: §AD's
   1px .visually-hidden box stayed invisible to people but gave the
   input a 1×1 hit area, which browser automation refuses as
   non-interactable (target_blocked on every upload attempt in two
   signed-in runs). The production pattern instead lays the input
   itself, full-size, over the upload button it serves: opacity 0
   keeps it invisible, the visible "📤 Upload photo or video" button
   beneath is pixel-for-pixel the same control, and a click (or a
   tool's upload) lands on the real input and opens the picker
   natively. The button stays in the tab order and still forwards
   its click for keyboard/screen-reader users; :focus-within keeps
   a visible ring when either control is focused. */
.ad-upload-zone {
  position: relative;
  display: block;
}
.ad-upload-zone > .btn {
  width: 100%; height: 100%;
}
.ad-file-overlay {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  margin: 0; padding: 0; border: 0;
  cursor: pointer;
}
.ad-upload-zone:focus-within {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: var(--radius-pill);
}

/* ---------- §AF. Discover area chip (Donald's Oct 17, 2026) ---------- */

/* AF1 — "Wrong area? Enter your ZIP": one small glass pill centered on
   the map's bottom edge (the centering law: it sits on the page axis,
   clear of the map key top-left, the nav controls top-right, and the
   drawer pull-tab mid-right). It renders ONLY on approximate openings
   (timezone area / Chicago floor) — see Discover.setupAreaChip. Same
   glass language as .map-key-btn. The expanded form swaps the label for
   an inline ZIP input + Go; the error line drops beneath the pill. */
.area-chip {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 550;
  display: flex; align-items: center; gap: 2px;
  background: var(--mist-glass); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  box-shadow: 0 4px 14px rgba(23,32,38,.14);
  padding: 3px 4px 3px 3px;
  font: 600 12px var(--font); color: var(--navy);
  max-width: calc(100% - 24px);
}
.area-chip[hidden] { display: none; }
.area-chip-main {
  background: none; border: 0; cursor: pointer;
  font: inherit; color: inherit; white-space: nowrap;
  padding: 5px 4px 5px 10px;
}
.area-chip-x {
  background: none; border: 0; cursor: pointer;
  font: 600 11px var(--font); color: var(--muted, #6b7a83);
  padding: 5px 8px 5px 2px; line-height: 1;
}
.area-chip-form { display: flex; align-items: center; gap: 6px; padding: 1px 2px 1px 8px; }
.area-chip-form[hidden] { display: none; }
.area-chip-form input {
  font: 600 12px var(--font); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 5px 10px; width: 86px; background: #fff;
}
.area-chip-go {
  background: var(--navy); color: #fff; border: 0; cursor: pointer;
  font: 700 12px var(--font); border-radius: var(--radius-pill);
  padding: 6px 14px;
}
.area-chip-go:disabled { opacity: .55; cursor: default; }
.area-chip-err {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(100% + 6px); white-space: nowrap;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 6px 18px rgba(23,32,38,.16);
  color: var(--red); font: 600 12px var(--font);
  padding: 6px 10px;
}
.area-chip-err[hidden] { display: none; }

/* ---------- §AG. Large-screen designs for the Oct 17 wave's new pages
   (Donald's Oct 17, 2026 order: "Make sure all new pages are enhanced
   and redesigned for laptop and TV experience"). These pages shipped
   phone-first: the discount pages sat in a 720/820px column floating
   in blank width, and the tracking page stretched its cards to the
   full container. At ≥1024 each page gets a composed wide layout —
   cards keep their natural size, more of them fit across, groups
   center on the page axis. Phone (<1024) is untouched: every rule
   lives inside these media blocks. The few !importants appear only
   where a view sets the same property inline (page measure, in-grid
   card margins, map heights) — the inline value still governs below
   1024px. ---------- */
@media (min-width: 1024px) {
  /* Discount events — owner list: the event cards pair up. */
  .page:has(#dev-list) { max-width: 1160px !important; }
  #dev-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
  #dev-list > .card { margin-bottom: 0 !important; }
  #dev-list > .empty { grid-column: 1 / -1; }
  /* Centering Law: a lone last card centers at its natural size
     instead of hugging the left column. */
  #dev-list > .card:nth-child(odd):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 7px); }

  /* Discount events — owner decision: the explainer anchors the left
     column at natural width; the three choices, the tool picker and
     the save button stack down the right; the picker's own rows pair
     up inside its card. */
  .page:has(#dev-detail) { max-width: 1180px !important; }
  #dev-detail { display: grid; grid-template-columns: 5fr 6fr; gap: 14px 20px; align-items: start; }
  #dev-detail > h1, #dev-detail > p { grid-column: 1 / -1; }
  #dev-detail > .card:not([data-choice-card]) { grid-column: 1; grid-row: 3 / span 4; }
  #dev-detail > [data-choice-card], #dev-detail > #dev-tools,
  #dev-detail > #dev-save, #dev-detail > #dev-msg { grid-column: 2; }
  #dev-detail > [data-choice-card] { margin-bottom: 0 !important; }
  #dev-detail > #dev-tools { margin: 0 !important; }
  #dev-tools .card { display: grid; grid-template-columns: 1fr 1fr; column-gap: 22px; }
  #dev-tools .card > strong, #dev-tools .card > p { grid-column: 1 / -1; }

  /* Discount events — admin list: the create form becomes a left
     rail; the events take the right column. */
  .page:has(#de-list) { max-width: 1240px !important; display: grid;
    grid-template-columns: 440px minmax(0, 1fr); gap: 18px 24px; align-items: start; }
  .page:has(#de-list) > p, .page:has(#de-list) > h1 { grid-column: 1 / -1; }
  .page:has(#de-list) > .card { grid-column: 1; }
  #de-list { grid-column: 2; margin-top: 0 !important; }

  /* Discount events — admin detail: the five participation stats
     become one even grid row; the joined-owner cards pair up. */
  .page:has(#de-detail) { max-width: 1240px !important; }
  #de-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
  #de-detail > h1, #de-detail > p, #de-detail > h3,
  #de-detail > div.card:first-of-type,
  #de-detail > div:has(> .card.center),
  #de-detail > div:has(> button) { grid-column: 1 / -1; }
  #de-detail > div:has(> .card.center) { display: grid !important;
    grid-template-columns: repeat(5, 1fr); gap: 12px; }
  #de-detail > .card ~ .card { margin-bottom: 0 !important; }
  /* Centering Law: an odd joined-owner card out centers the same
     way (joined cards start at child 7; an odd child with no .card
     after it is alone in its row). */
  #de-detail > .card ~ .card:nth-child(odd):not(:has(~ .card)) {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 7px); }

  /* Tracking: the trip card holds its natural width in a left rail;
     the map takes the rest of the row and grows taller. Columns are
     pinned explicitly (dense flow) so the en-route pill slot
     (#trk-enroute, mounted by the en-route board build) can never
     steal the map's cell — the pill takes a full-width row of its
     own under the trip/map row, and collapses while it is empty. */
  .page:has(> #trk-body) { display: grid; grid-auto-flow: dense;
    grid-template-columns: 470px minmax(0, 1fr); gap: 14px 20px; align-items: start; }
  .page:has(> #trk-body) > a, .page:has(> #trk-body) > h1 { grid-column: 1 / -1; }
  .page:has(> #trk-body) > #trk-trip { grid-column: 1; }
  .page:has(> #trk-body) > #trk-body { grid-column: 2; }
  .page:has(> #trk-body) > #trk-enroute { grid-column: 1 / -1; }
  .page:has(> #trk-body) > #trk-enroute:empty { display: none; }
  #trk-map { height: 400px !important; }
  /* No trip yet: the empty trip slot steps aside — the meet map
     centers on a measure, and the pure empty state centers narrow. */
  .page:has(> #trk-trip:empty) > #trk-trip { display: none; }
  .page:has(> #trk-trip:empty):has(#trk-map) > #trk-body {
    grid-column: 1 / -1; width: 100%; max-width: 920px; justify-self: center; }
  .page:has(> #trk-trip:empty):not(:has(#trk-map)) > #trk-body {
    grid-column: 1 / -1; width: 100%; max-width: 640px; justify-self: center; }

  /* Group meet spot: the map stops being a 200px ribbon inside the
     group page's full-measure composition. */
  #gs-meet-map { height: 300px !important; }
}
@media (min-width: 1440px) {
  #trk-map { height: 460px !important; }
  #gs-meet-map { height: 320px !important; }
}
@media (min-width: 1920px) {
  /* TV: one more step — a third event column, wider rails, taller
     maps. Cards still keep their natural size; more fit across. */
  .page:has(#dev-list) { max-width: 1500px !important; }
  #dev-list { grid-template-columns: repeat(3, 1fr); }
  #dev-list > .card:nth-child(odd):last-child { width: auto; justify-self: stretch; grid-column: auto; }
  #dev-list > .card:nth-child(3n+1):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(33.333% - 10px); }
  .page:has(#dev-detail) { max-width: 1280px !important; }
  .page:has(#de-list) { max-width: 1500px !important; grid-template-columns: 480px minmax(0, 1fr); }
  #de-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
  #de-list > .card { margin-bottom: 0 !important; }
  #de-list > .empty { grid-column: 1 / -1; }
  #de-list > .card:nth-child(odd):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 7px); }
  .page:has(> #trk-body) { grid-template-columns: 540px minmax(0, 1fr); }
  #trk-map { height: 520px !important; }
  .page:has(> #trk-trip:empty):has(#trk-map) > #trk-body { max-width: 1040px; }
  #gs-meet-map { height: 360px !important; }
}

/* ---------- §AH. En-route board (Donald's Oct 17, 2026) ----------
   The bookings page as a live FLOW BOARD: an "En route now" section
   that exists only while trip legs travel, direction groups relative
   to the viewer, party cards in the TripCard dialect. Laptop (~1440)
   and TV (1920+) are first-class: direction columns side by side,
   party cards across at NATURAL size (never stretched), the map
   strip wider, every row centered as a group (Centering Law). */
#enroute-host { margin-bottom: 4px; }
.enroute-board { margin: 0 auto 16px; }
.enroute-head { position: relative; display: flex; align-items: center; justify-content: center; }
.enroute-title { margin: 4px 0 2px; font-size: 18px; font-weight: 800; text-align: center; color: var(--text); }
.enroute-sub { text-align: center; margin: 0 0 10px; }
.enroute-collapse {
  position: absolute; right: 2px; top: 0;
  background: none; border: 0; cursor: pointer;
  font-size: 18px; line-height: 1; color: var(--muted); padding: 6px 8px;
}
.enroute-mapwrap { position: relative; margin-bottom: 12px; }
.enroute-map {
  position: relative; height: 180px; border-radius: 14px; overflow: hidden;
  box-shadow: var(--shadow); background: var(--mist-bg-2);
}
.enroute-offmap {
  position: absolute; left: 10px; bottom: 10px; z-index: 5;
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius-pill);
  box-shadow: 0 2px 8px rgba(2, 32, 71, 0.18);
  font-size: 11px; font-weight: 600; color: var(--muted); padding: 3px 10px;
}
.enroute-map-summary {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  gap: 10px; font-size: 13px; font-weight: 600; color: var(--muted);
}
.enroute-marker { display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer; }
.enroute-dot-label {
  background: #fff; color: var(--navy); font-size: 9px; font-weight: 800; line-height: 1.4;
  padding: 0 5px; border-radius: 6px; box-shadow: 0 1px 4px rgba(2, 32, 71, 0.35);
}
.enroute-cluster {
  width: 30px; height: 30px; border-radius: 50%; background: var(--navy); color: #fff;
  border: 3px solid #fff; box-shadow: 0 1px 6px rgba(2, 32, 71, 0.40);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; cursor: pointer;
}
.enroute-anchor-pin { font-size: 20px; line-height: 1; filter: drop-shadow(0 1px 3px rgba(2, 32, 71, 0.4)); }
.enroute-groups { display: block; }
.enroute-group { margin-bottom: 6px; }
.enroute-group-title {
  text-align: center; font-size: 13px; font-weight: 800; color: var(--navy);
  letter-spacing: 0.04em; text-transform: uppercase; margin: 12px 0 10px;
}
.enroute-cards { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.enroute-card {
  width: 100%; max-width: 430px; padding: 14px 16px; cursor: pointer;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.enroute-card:hover { transform: translateY(-1px); }
.enroute-card .trip-big { font-size: 30px; }
.enroute-flash { outline: 2px solid var(--navy); outline-offset: 2px; }
.enroute-idrow { display: flex; align-items: flex-start; gap: 10px; }
.enroute-avatar {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: 0 0 auto;
}
.enroute-avatar-init {
  background: var(--navy); color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 800;
}
.enroute-idmain { min-width: 0; }
.enroute-name { font-size: 15px; font-weight: 700; line-height: 1.25; }
.enroute-traveler { margin-top: 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.enroute-chips { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; flex: 0 0 auto; }
.enroute-legchip {
  font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: var(--radius-pill);
  border: 1px solid var(--navy); color: var(--navy); white-space: nowrap;
}
.enroute-statuschip {
  font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: var(--radius-pill);
  background: var(--mist-bg-2); color: var(--text); white-space: nowrap;
}
.enroute-statuschip.st-arrived { background: var(--green); color: #fff; }
.enroute-statuschip.st-exchanging { background: var(--navy); color: #fff; }
.enroute-statuschip.st-5-min-away { background: #E7F4DC; color: #2F6B01; }
.enroute-statuschip.st-signal-paused {
  background: var(--amber-ad); border: 1px solid var(--amber-border); color: var(--mist-sponsored-text);
}
.enroute-recent { text-align: center; margin-top: 6px; }
.enroute-step-labels { display: none; }
.enroute-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px;
}
.enroute-tool { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; min-width: 0; }
.enroute-thumb { width: 28px; height: 28px; border-radius: 6px; object-fit: cover; flex: 0 0 auto; }
.enroute-thumb-empty {
  background: var(--mist-bg-2); display: flex; align-items: center; justify-content: center; font-size: 14px;
}
.enroute-viewcue { font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.enroute-settle {
  text-align: center; padding: 18px 16px; margin-bottom: 16px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.enroute-settle .enroute-sub { margin-top: 4px; }
/* The minimized pill — booking surfaces only, bottom-center. */
.enroute-pill {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(18px + env(safe-area-inset-bottom, 0px)); z-index: 60;
  background: var(--navy); color: #fff; border: 0; cursor: pointer;
  font: 700 13px var(--font); border-radius: var(--radius-pill);
  padding: 11px 20px; box-shadow: 0 6px 20px rgba(2, 32, 71, 0.35); white-space: nowrap;
}
/* Bookings-entry badge: red count disc + muted next-ETA chip. */
.enroute-badge { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; vertical-align: 1px; }
.enroute-badge-disc {
  background: var(--red); color: #fff; font-size: 11px; font-weight: 800;
  min-width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; padding: 0 4px;
}
.enroute-badge-next { font-size: 11px; font-weight: 600; color: var(--muted); }
/* Ordinary-row live chip. */
.enroute-rowchip {
  display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 700;
  color: var(--navy); background: var(--mist-bg-2);
  padding: 2px 9px; border-radius: var(--radius-pill);
}
/* Booking detail: the quiet "See all en route (n)" row. */
.enroute-seeall {
  display: block; margin: 10px auto 2px; background: #fff; cursor: pointer;
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow);
  font: 600 13px var(--font); color: var(--navy); padding: 9px 16px;
}
/* Slide-over sheet (from the booking detail). */
.enroute-sheet-wrap { position: fixed; inset: 0; z-index: 90; }
.enroute-sheet-backdrop { position: absolute; inset: 0; background: rgba(2, 32, 71, 0.45); }
.enroute-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; max-height: 92vh; overflow-y: auto;
  background: #fff; border-radius: 18px 18px 0 0; box-shadow: 0 -8px 30px rgba(2, 32, 71, 0.30);
}
.enroute-sheet-head {
  position: sticky; top: 0; z-index: 2; background: #fff;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.enroute-sheet-title { font-size: 15px; font-weight: 800; }
.enroute-sheet-x {
  background: none; border: 0; cursor: pointer; font-size: 16px; color: var(--muted); padding: 6px 8px;
}
.enroute-sheet-body { padding: 6px 14px 18px; }
@media (min-width: 768px) {
  .enroute-sheet { left: auto; top: 0; width: 420px; max-height: none; height: 100%; border-radius: 0; }
}
/* Laptop (~1440): direction columns side by side, cards across at
   natural size inside each column, labels under the step dots. */
@media (min-width: 1024px) {
  .enroute-map { height: 220px; }
  .enroute-step-labels { display: flex; }
  .enroute-groups { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 24px; align-items: flex-start; }
  .enroute-group { flex: 1 1 460px; max-width: 820px; }
  .enroute-cards { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: stretch; }
  .enroute-card { flex: 0 1 360px; width: 360px; max-width: 100%; }
}
/* TV (1920+): the measure widens, the map strip grows, type steps up
   a notch for distance legibility — card internals unchanged. */
@media (min-width: 1440px) {
  .enroute-map { height: 240px; }
}
@media (min-width: 1920px) {
  .enroute-map { height: 260px; }
  .enroute-title { font-size: 20px; }
  .enroute-group-title { font-size: 14px; }
  /* TV: inside the site's 1600px measure each direction column is
     ~680px, so party cards run TWO across at a natural 330px rather
     than one stretched stack — more parties on screen, nothing
     enlarged. (380px made a pair 772px wide and never fit.) */
  .enroute-card { flex-basis: 330px; width: 330px; }
  .enroute-sheet { width: 480px; }
}

/* ---------- §AI. Tool page, simplified (Donald's Oct 18, 2026) --------
   The buyer tool page is four things: the pictures, the
   specifications, the calendar for prices, and the pickup-or-delivery
   request. The glass card is now a slim centered header (title + one
   quiet owner line); below it, a specifications column and the
   booking-card column. Phone order is Donald's listed order: header →
   specifications → booking card. Desktop: the booking card is a 360px
   sticky column on the left, the specifications take the wider right
   column, and the whole composition stays centered on the page —
   never stretched. */
.tool-detail .tool-glass-card { text-align: center; }
.tool-header-owner {
  display: flex; align-items: center; justify-content: center;
  gap: 10px; margin-top: 10px; flex-wrap: wrap; text-align: center;
}
.tool-header-owner .avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; }
.tool-detail .detail-layout { display: flex; flex-direction: column; gap: 16px; }
.tool-main-col, .tool-side-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.tool-main-col > *, .tool-side-col > * { min-width: 0; }
#tool-book-slot:empty { display: none; }
.tool-book-card .price-line { font-size: 26px; }
.tool-book-card .field { margin-top: 12px; }
#tb-cal { margin: 12px 0 4px; }
@media (min-width: 1024px) {
  .tool-detail .container:has(> .tool-glass-card) { display: block; }
  .tool-detail .tool-glass-card {
    position: relative; top: auto; margin: -64px auto 0; max-width: 720px;
    max-height: none; overflow: visible;
  }
  .tool-detail .detail-layout {
    display: grid; grid-template-columns: 360px minmax(0, 1fr);
    gap: 24px; align-items: start; margin-top: 24px;
  }
  .tool-detail .tool-side-col { grid-column: 1; grid-row: 1; position: sticky; top: calc(var(--header-h) + 16px); }
  .tool-detail .tool-main-col { grid-column: 2; grid-row: 1; }
}

/* ---------- §AJ. Unified Cards (Donald's Oct 18, 2026) -------------
   "Put payment cards and members card at the same place in the
   profile. Make so users can toggle and switch between payment cards
   and user cards." ONE cards card (Profile Overview + the
   payment-methods page): a centered segmented toggle in the
   .qrt-toggle family flips between the member card (PlusCardUI's
   settled rendering, untouched) and the member's saved payment
   cards, drawn as card FACES in the member card's visual family —
   same 18px radius, same measure, same slider + dots when there are
   several — with their management actions under the face. */
.ucards-toggle { margin: 6px auto 10px; width: 100%; max-width: 460px; box-sizing: border-box; }
.ucards-seg {
  white-space: nowrap; flex: 1 1 0; min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  padding: 8px 4px; font-size: 12.5px;
  transition: background-color .25s ease, color .25s ease, box-shadow .25s ease;
}
/* Pane flips (Donald's Oct 19, 2026 — "they animate in and out and
   flip smoothly"): switching stops fades the old pane out fast,
   then flips the new pane in (~300ms, ease-out). Compositor-only —
   transform + opacity, never a layout property — so a flip can
   never shift the page around it. prefers-reduced-motion swaps
   instantly: UnifiedCards.show checks the same media query and
   skips the out phase; these rules are the belt to that brace. */
@keyframes ucardsPaneIn {
  from { opacity: 0; transform: perspective(900px) rotateX(3.5deg) translateY(8px); }
  to { opacity: 1; transform: perspective(900px) rotateX(0deg) translateY(0); }
}
@keyframes ucardsPaneOut {
  from { opacity: 1; }
  to { opacity: 0; transform: translateY(-5px); }
}
.ucards-pane--in { animation: ucardsPaneIn .3s ease-out; transform-origin: 50% 0; }
.ucards-pane--out { animation: ucardsPaneOut .13s ease-in forwards; }
@media (prefers-reduced-motion: reduce) {
  .ucards-pane--in, .ucards-pane--out { animation: none; }
  .ucards-seg { transition: none; }
}
/* The profile QR as a card face (Donald's Oct 19, 2026 — "make the
   profile QR code look fancier, similar to the cards"): the SAME
   .member-card face as the member card, colored by the member's own
   tier, with the public profile QR centered on its white tile.
   Scannability is untouched — the modules stay black-on-white at
   full contrast inside the tile's quiet zone; only the face around
   the tile carries the design. */
.qrface { text-align: center; }
.qrface-body { display: flex; flex-direction: column; align-items: center; margin-top: 8px; }
.qrface-qr { width: 168px; padding: 10px; }
.qrface-name { margin-top: 12px; }
.qrface-sub { margin-top: 3px; }
.qrt-stage:has(.qrface) { max-width: 460px; }
.ucards-qr-wrap { max-width: 460px; margin: 0 auto; }
.ucards-qr-wrap .qrt-link { word-break: break-all; margin: 2px 0 10px; }
.pcard {
  background: linear-gradient(135deg, #3D5A68 0%, #22333D 58%, #141F27 100%);
  color: #fff;
  border-radius: 18px;
  padding: 16px 18px;
  box-shadow: 0 14px 34px rgba(10, 30, 42, 0.32);
  max-width: 460px;
  margin: 10px auto;
  text-align: left;
}
.pcard-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pcard-brandwrap { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.pcard-chip {
  width: 34px; height: 25px; border-radius: 5px; flex: 0 0 auto;
  background: linear-gradient(135deg, #FBD184 0%, #F5A623 100%);
  box-shadow: inset 0 0 0 2px rgba(122, 74, 0, 0.45), inset 0 9px 0 -7px rgba(122, 74, 0, 0.55), inset 0 -9px 0 -7px rgba(122, 74, 0, 0.55);
}
.pcard-face-label { font-size: 11px; font-weight: 700; letter-spacing: 2px; color: rgba(255, 255, 255, 0.78); }
.pcard-badges { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.pcard-num { font-size: 20px; font-weight: 600; letter-spacing: 2px; margin: 20px 0 16px; white-space: nowrap; }
.pcard-bot { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pcard-brandname { font-size: 15px; font-weight: 700; }
.pcard-exp { font-size: 12.5px; color: rgba(255, 255, 255, 0.82); white-space: nowrap; }
.pcards .pcard { margin: 10px auto; }
.mc-slide .pcard { margin: 0 auto; }
.pcard-actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 10px auto 2px; }
.ucards-empty { margin: 20px auto 8px; }
.ucards-addrow { justify-content: center; margin-top: 12px; }
.ucards-banklink { margin: 10px auto 0; }
.ucards-note { margin: 8px auto 0; max-width: 460px; }
/* Upgrade pill (Donald's Oct 18, 2026): the ONE pill by the member
   card suggesting an upgrade — its own centered row directly under
   the card face (block flow), member side only, shown only when
   the viewer has no paid plan entitlement. In the card's ≥1024px
   grid regimes the slot spans the full measure and centers, so it
   never collides with the face/howto columns and never distorts
   them (cards MOVE, never distort — this row only takes space
   when the pill is actually painted; an empty slot is 0px tall). */
.ucards-upgrade { display: flex; justify-content: center; margin-top: 10px; }
.ucards-upgrade-pill { box-shadow: 0 8px 22px rgba(10, 30, 42, 0.16); }
@media (min-width: 1024px) {
  #ov-member-card-card > #ov-upgrade-pill { grid-column: 1 / -1; justify-self: center; }
}
@media (min-width: 1280px) {
  /* The toggle takes the row under the card title inside the settled
     ≥1280 member-card grid; every member-side placement from the
     earlier sections shifts down exactly one row, and the payment
     pane spans the full measure. (In payment mode the member items
     are [hidden], so the pane flows directly under the toggle.) */
  #ov-member-card-card > .ucards-toggle { grid-column: 1 / -1; grid-row: 2; justify-self: center; }
  #ov-member-card-card > [data-ucards-pane="pay"] { grid-column: 1 / -1; min-width: 0; }
  #ov-member-card-card > [data-ucards-pane="qr"] { grid-column: 1 / -1; min-width: 0; }
  #ov-member-card-card > [data-ucards-pane="handover"] { grid-column: 1 / -1; min-width: 0; }
  #ov-member-card .mc-slider, #ov-member-card .mc-cards { grid-row: 3; }
  #ov-member-card .mc-tap { grid-row: 4; }
  #ov-member-card .mc-howto { grid-row: 3 / span 3; }
  #ov-member-card-card > .btn-row { grid-row: 5; }
  #ov-member-card-card > p { grid-row: 6; }
  #ov-member-card-card > #ov-member-card-activity { grid-row: 7; }
  .profile-layout:has(#ov-today) #ov-member-card .mc-slider,
  .profile-layout:has(#ov-today) #ov-member-card .mc-cards { grid-row: 3 / span 3; }
  .profile-layout:has(#ov-today) #ov-member-card .mc-tap { grid-row: 3; }
  .profile-layout:has(#ov-today) #ov-member-card-card > .btn-row { grid-row: 4; }
  .profile-layout:has(#ov-today) #ov-member-card-card > p { grid-row: 5; }
  .profile-layout:has(#ov-today) #ov-member-card .mc-howto { grid-row: 6; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-slider,
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-cards { grid-row: 3 / span 3; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-tap { grid-row: 3; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card-card > .btn-row { grid-row: 4; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card-card > p { grid-row: 5; }
  .profile-layout:has(#ov-member-card-card) #ov-member-card .mc-howto { grid-row: 6; }
}

/* =============== Weave HQ (#/admin-weave) — Oct 18, 2026 ===============
   One composed observatory page. Centering Law: every card row is a
   centered flex group (short rows center on the page axis). Large-
   Screen Law: laptop composes wider grids; TV (≥1500px) puts the
   Flow Map and Health side by side and the Ledger beside Learning at
   Work. Phone stacks the same composition; the flow map degrades to
   a grouped thread list. */
.whq-page { max-width: 1180px; margin: 0 auto; }
.whq-sec { scroll-margin-top: calc(var(--header-h, 56px) + 58px); margin: 26px 0 0; }
.whq-rail { position: sticky; top: calc(var(--header-h, 56px) + 4px); z-index: 30;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px;
  background: rgba(255,255,255,.94); padding: 8px 6px; border-radius: 12px;
  box-shadow: 0 4px 18px rgba(2,58,80,.12); margin: 10px auto 4px; max-width: 760px; }
.whq-rail a { font-size: 12.5px; font-weight: 600; color: #023A50; text-decoration: none;
  padding: 5px 11px; border-radius: 999px; background: #eef6f8; white-space: nowrap; }
.whq-rail a:hover { background: #dcecf1; }
.whq-tiles, .whq-hgrid, .whq-ggrid, .whq-wgrid { display: flex; flex-wrap: wrap;
  justify-content: center; gap: 14px; }
.whq-tile { flex: 0 1 208px; text-align: center; padding: 16px 12px; }
.whq-tile-big { font-size: 24px; font-weight: 800; color: #023A50; }
.whq-tile-label { font-weight: 700; margin: 2px 0 4px; }
.whq-domain-h { text-align: center; color: #023A50; margin: 18px 0 10px; font-size: 16px; }
.whq-hcard { flex: 0 1 262px; padding: 14px 16px; }
.whq-hcard.whq-grey { border: 1.5px dashed #b9c6cb; background: #f7f9fa; }
.whq-hcard-top { text-align: center; }
.whq-pill { font-weight: 700; font-size: 12.5px; }
.whq-hcard-title { text-align: center; margin: 4px 0 6px; font-size: 15.5px; color: #123c4c; }
.whq-evidence { text-align: center; margin: 0 0 6px; font-size: 13.5px; }
.whq-amber-rule { text-align: center; margin: 0; }
.whq-hcard .small { text-align: center; }
.whq-notyet { margin: 18px auto 0; max-width: 860px; padding: 14px 18px; }
.whq-flow-card { padding: 14px 10px 8px; margin: 0 auto; }
.whq-flow-svg { width: 100%; height: auto; display: block; }
.whq-thread-list { display: none; }
.whq-thread-row { display: flex; align-items: center; gap: 8px; padding: 7px 4px;
  border-top: 1px solid #e6edef; cursor: pointer; flex-wrap: wrap; }
.whq-thread-state { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; padding: 2px 8px; border-radius: 999px; background: #eef6f8; color: #023A50; }
.whq-thread-state.stale { background: #fdf0da; color: #8a5a00; }
.whq-thread-state.uncounted { background: #eef1f2; color: #66757c; }
.whq-thread-label { font-size: 13px; font-weight: 600; }
.whq-thread-panel { margin: 12px auto 0; max-width: 860px; padding: 12px 16px; }
.whq-gcard { flex: 0 1 342px; padding: 14px 16px; text-align: center; }
.whq-gcard-title { margin: 0 0 4px; font-size: 15.5px; color: #123c4c; text-align: center; }
.whq-gcard-big { font-size: 26px; font-weight: 800; color: #023A50; }
.whq-chart { width: 100%; height: 96px; display: block; }
.whq-chart-empty { border: 1.5px dashed #c3ced2; border-radius: 10px; padding: 26px 10px; margin: 6px 0; }
.whq-lentry { max-width: 860px; margin: 0 auto 12px; padding: 14px 18px; }
.whq-lentry-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.whq-fam { font-weight: 800; color: #023A50; }
.whq-learned { font-size: 11.5px; font-weight: 700; color: #2e6b00; background: #eaf5e2;
  padding: 2px 9px; border-radius: 999px; }
.whq-revised { font-size: 11.5px; font-weight: 700; color: #8a5a00; background: #fdf0da;
  padding: 2px 9px; border-radius: 999px; }
.whq-claim { font-size: 15px; font-weight: 600; margin: 8px 0 6px; }
.whq-evidence-box { margin-top: 8px; }
.whq-evidence-pre { background: #f4f8f9; border-radius: 8px; padding: 10px; font-size: 11.5px;
  overflow-x: auto; margin: 6px 0 0; }
.whq-wcard { flex: 0 1 400px; padding: 14px 16px; }
.whq-wcard-title { margin: 0; font-size: 15.5px; color: #123c4c; }
.whq-effect { font-size: 11.5px; font-weight: 700; padding: 2px 9px; border-radius: 999px; margin-left: auto; }
.whq-effect.live { color: #2e6b00; background: #eaf5e2; }
.whq-effect.collecting { color: #023A50; background: #e6f1f5; }
.whq-effect.pending { color: #66757c; background: #eef1f2; }
.whq-fact { display: inline-block; margin: 2px 8px 2px 0; }
@media (max-width: 759px) {
  .whq-flow-svg { display: none; }
  .whq-thread-list { display: block; }
  .whq-rail { flex-wrap: nowrap; overflow-x: auto; justify-content: flex-start; }
  .whq-tile { flex-basis: 46%; }
  .whq-hcard, .whq-gcard, .whq-wcard { flex-basis: 100%; }
}
@media (min-width: 1024px) {
  .whq-tile { flex-basis: 196px; }
}
@media (min-width: 1500px) {
  .whq-page { max-width: 1740px; }
  #weave-body { display: grid; grid-template-columns: 1.02fr .98fr; column-gap: 30px; align-items: start; }
  #whq-sec-pulse, #whq-sec-growth { grid-column: 1 / -1; }
  #whq-sec-flow { grid-column: 1; }
  #whq-sec-health { grid-column: 2; }
  #whq-sec-ledger { grid-column: 1; }
  #whq-sec-work { grid-column: 2; }
  .whq-tile { flex-basis: 300px; }
}

/* ---------- Weave HQ Package 2 — Activity · Algorithms · Tracking
   (Oct 21, 2026; append-only — new classes only, nothing above is
   modified). The registry list and the activity feed follow the
   Ledger's centered measure; the tracking table is a data table
   (Centering Law exception) inside a scroll wrapper so the phone
   keeps the page measure and scrolls the table, never the page. */
.whq-act-card { max-width: 860px; margin: 0 auto; padding: 8px 18px 12px; }
.whq-act-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 8px 2px; border-top: 1px solid #e6edef; }
.whq-act-row:first-child { border-top: none; }
.whq-act-when { font-size: 12px; color: #66757c; white-space: nowrap; }
.whq-act-kind { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; padding: 2px 8px; border-radius: 999px;
  background: #e6f1f5; color: #023A50; white-space: nowrap; }
.whq-act-kind.incident { background: #fdf0da; color: #8a5a00; }
.whq-act-kind.learning { background: #eaf5e2; color: #2e6b00; }
.whq-act-label { font-weight: 700; color: #023A50; font-size: 13.5px; white-space: nowrap; }
.whq-act-text { font-size: 13.5px; flex: 1 1 260px; }
.whq-algo-list { max-width: 980px; margin: 0 auto; display: flex;
  flex-direction: column; gap: 10px; }
.whq-algo { padding: 10px 16px 12px; }
.whq-algo.whq-grey { border: 1.5px dashed #b9c6cb; background: #f7f9fa; }
.whq-algo-sum { cursor: pointer; display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; list-style: none; }
.whq-algo-sum::-webkit-details-marker { display: none; }
.whq-algo-name { font-weight: 700; color: #123c4c; font-size: 15px; }
.whq-algo-meta { margin-left: auto; }
.whq-algo-body { margin-top: 10px; border-top: 1px solid #e6edef; padding-top: 10px; }
.whq-kv { display: grid; grid-template-columns: 96px 1fr; gap: 4px 12px;
  font-size: 13.5px; margin: 0; }
.whq-kv dt { font-weight: 700; color: #023A50; }
.whq-kv dd { margin: 0; }
.whq-track-card { padding: 6px 14px 12px; }
.whq-track-wrap { overflow-x: auto; }
.whq-track { width: 100%; min-width: 920px; border-collapse: collapse; font-size: 12.5px; }
.whq-track th { text-align: left; color: #023A50; font-size: 12px;
  text-transform: uppercase; letter-spacing: .4px; padding: 8px; border-bottom: 2px solid #dcecf1; }
.whq-track td { padding: 8px; border-top: 1px solid #e6edef; vertical-align: top; }
.whq-track th.num, .whq-track td.num { text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 759px) {
  .whq-kv { grid-template-columns: 1fr; gap: 2px; }
  .whq-kv dd { margin-bottom: 6px; }
  .whq-algo-meta { margin-left: 0; }
}
@media (min-width: 1500px) {
  #whq-sec-activity, #whq-sec-algorithms, #whq-sec-tracking { grid-column: 1 / -1; }
}

/* ---------- §AJ. Tool booking flow (Donald's Oct 18, 2026) --------
   Renter Simplicity Law: the buyer tool page is the pictures, the
   description, and one Book now button — the description block below
   is a plain centered section, NOT a card. Book now opens the booking
   calendar as a pop-up (the widget inside renders flat — the modal is
   the surface). After payment the booking page shows the owner's
   pickup location on a map (server-gated to paid/confirmed bookings).
   Desktop/TV: the description block stays a calm centered measure;
   nothing stretches. */
.tool-buyer .tool-desc-block { max-width: 720px; margin: 20px auto 40px; text-align: center; padding: 0 16px; }
.tool-buyer .tool-desc-block h1 { margin: 0 0 6px; }
.tool-desc-rate { font-size: 22px; font-weight: 700; color: var(--navy, #023A50); margin: 0 0 12px; }
.tool-desc-text { color: var(--ink, #1c2b33); line-height: 1.55; margin: 0 auto 20px; max-width: 60ch; }
.tool-buyer .tool-book-now { min-width: 220px; }
.tool-book-popup-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.tool-book-popup-head h3 { margin: 0; }
.tool-book-popup-x { background: none; border: 0; font-size: 18px; line-height: 1; cursor: pointer; color: var(--muted, #6b7a83); padding: 6px; }
#tool-book-popup .tool-book-card { border: 0; box-shadow: none; padding: 0; border-radius: 0; }
.tb-pickup-only, .b-pickup-only { margin-top: 12px; }
.bk-pickup-map { height: 250px; border-radius: 12px; overflow: hidden; margin-top: 10px; background: var(--bg-soft, #eef3f5); }
.bk-pickup-pin { font-size: 26px; line-height: 1; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
@media (min-width: 1024px) {
  .tool-buyer .tool-desc-block { margin-top: 28px; }
  .bk-pickup-map { height: 280px; }
}

/* The menu must stop ABOVE the floating bottom-nav dock on phone widths
   (Donald's Oct 18, 2026 report: the Install button sat under the dock).
   The dock is hidden at ≥1280px, so the taller cap stands there. */
@media (max-width: 1279px) {
  #mobile-menu { max-height: calc(100vh - var(--header-h) - 108px); max-height: calc(100dvh - var(--header-h) - 108px); }
}

/* ---------- Messages v2 (Oct 19, 2026 redesign) ----------
   Three tabs (Chats / Bookings / Tools Nearby), select-and-delete at
   both levels, media bubbles, Seen line, support home, and the
   Large-Screen two-pane layout. House language throughout: Inter,
   centered titles, muted-gray 12px descriptive text, soft shadows,
   cards centered on one shared axis. */
.msg-nav-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 5px; margin-left: 5px;
  border-radius: 999px; background: #d64545; color: #fff;
  font-size: 10.5px; font-weight: 800; vertical-align: 2px;
}
#bottom-nav a[data-nav="messages"] { position: relative; }
#bottom-nav .msg-nav-badge { position: absolute; top: 2px; right: calc(50% - 22px); margin: 0; }

.msgx-page { max-width: 760px; margin: 0 auto; }
.msgx-layout { display: block; }
.msgx-pane-idle { display: none; }
.msgx-tabs { display: flex; background: var(--mist-card-2); border-radius: 12px; padding: 3px; margin-bottom: 10px; }
.msgx-tab {
  flex: 1; text-align: center; font-size: 12px; font-weight: 700; color: var(--muted);
  padding: 8px 2px; border: none; background: none; border-radius: 9px; cursor: pointer; font-family: var(--font);
}
.msgx-tab.on { background: #fff; color: var(--navy); box-shadow: 0 2px 7px rgba(2,58,80,.12); }
.msgx-bdg {
  display: inline-block; min-width: 16px; padding: 1px 4px; border-radius: 999px;
  background: #d64545; color: #fff; font-size: 10px; font-weight: 800; vertical-align: 2px; margin-left: 3px;
}
.msgx-chips { display: flex; gap: 6px; margin-bottom: 10px; align-items: center; flex-wrap: wrap; }
.msgx-chip {
  font-size: 11px; font-weight: 700; color: var(--muted); background: #fff;
  border: 1.5px solid var(--border); padding: 5px 10px; border-radius: 999px; cursor: pointer; font-family: var(--font);
}
.msgx-chip.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.msgx-spacer { flex: 1; }
.msgx-seclabel { font-size: 11px; letter-spacing: .09em; font-weight: 700; color: var(--muted); margin: 12px 2px 7px; }
.msgx-selbar {
  display: flex; justify-content: space-between; align-items: center;
  background: var(--navy); color: #fff; border-radius: 12px; padding: 9px 12px;
  margin-bottom: 10px; font-size: 12.5px; font-weight: 700;
}
.msgx-selbar .msgx-selacts button {
  background: none; border: none; color: #bcd2dc; font-weight: 700; font-size: 12.5px;
  cursor: pointer; font-family: var(--font); padding: 4px 6px;
}
.msgx-delbar { display: flex; gap: 8px; margin-top: 10px; }
.msgx-delbar .msgx-del {
  flex: 1; text-align: center; background: #d64545; color: #fff; font-weight: 700;
  font-size: 13px; padding: 11px 0; border: none; border-radius: 12px; cursor: pointer; font-family: var(--font);
}
.msgx-delbar .msgx-del:disabled { opacity: .45; cursor: not-allowed; }
.msgx-delbar .msgx-keep {
  flex: 1; text-align: center; background: var(--mist-card-2); color: var(--navy); font-weight: 700;
  font-size: 13px; padding: 11px 0; border: none; border-radius: 12px; cursor: pointer; font-family: var(--font);
}
.msgx-archlink { text-align: center; margin: 14px 0 4px; font-size: 12px; }
.msgx-archlink a { color: #029DAA; font-weight: 700; text-decoration: none; }

/* Inbox rows */
.msgx-row {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 9px;
  border: 1.5px solid var(--border); border-radius: 14px; margin-bottom: 8px;
  background: #fff; text-decoration: none; color: var(--text); cursor: pointer;
  box-shadow: 0 4px 12px rgba(2,58,80,.05);
}
.msgx-row:hover { border-color: #bcd2dc; }
.msgx-row.need { border-color: #f0d9a8; background: #fffdf6; box-shadow: 0 4px 12px rgba(183,121,31,.10); }
.msgx-row.pinned { border-color: #bcd2dc; background: #f7fafb; }
.msgx-row.sel { border-color: #029DAA; background: #f2f9fa; }
.msgx-row.active { border-color: var(--navy); }
.msgx-avatar {
  width: 40px; height: 40px; border-radius: 50%; background: var(--navy); color: #fff;
  font-weight: 800; font-size: 14px; display: flex; align-items: center; justify-content: center; flex: none;
}
.msgx-avatar.teal { background: #029DAA; }
.msgx-avatar.green { background: var(--green); }
.msgx-avatar.gray { background: #8fa5b0; }
.msgx-avatar.red { background: #d64545; }
.msgx-avatar.navy { background: var(--navy); }
.msgx-avatar.sq { border-radius: 11px; }
.msgx-thumb {
  width: 40px; height: 40px; border-radius: 11px; flex: none; overflow: hidden;
  background: linear-gradient(135deg, #dbe7ec, #bcd2dc);
  display: flex; align-items: center; justify-content: center; font-size: 19px;
}
.msgx-thumb.round { border-radius: 50%; }
.msgx-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.msgx-logo {
  width: 40px; height: 40px; border-radius: 50%; flex: none; background: #fff;
  border: 2px solid var(--navy); display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.msgx-logo img { width: 26px; height: 26px; }
.msgx-grow { flex: 1; min-width: 0; display: block; }
.msgx-top { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; }
.msgx-name { font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msgx-time { font-size: 11px; color: var(--muted); flex: none; }
.msgx-time.hot { color: #356e06; font-weight: 700; }
.msgx-snip { display: block; font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 2px; overflow-wrap: anywhere; }
.msgx-snip.unread { color: var(--text); font-weight: 600; }
.msgx-meta { display: flex; gap: 5px; align-items: center; margin-top: 5px; flex-wrap: wrap; }
.msgx-unread {
  display: inline-flex; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 999px;
  background: #d64545; color: #fff; font-size: 10.5px; font-weight: 800; align-items: center; justify-content: center;
}
.msgx-chipst { display: inline-block; font-size: 10.5px; font-weight: 800; border-radius: 999px; padding: 3px 8px; }
.msgx-chipst.amber { background: #fdf3e0; color: #96660a; }
.msgx-chipst.green { background: #e6f3da; color: #356e06; }
.msgx-chipst.teal { background: #e0f2f4; color: #027a84; }
.msgx-chipst.navy { background: #e2edf2; color: var(--navy); }
.msgx-chipst.gray { background: #eef1f3; color: var(--muted); }
.msgx-chipst.red { background: #fbe9e7; color: #b03a2e; }
.msgx-wait { font-size: 10.5px; font-weight: 800; color: #96660a; }
.msgx-check {
  width: 21px; height: 21px; border-radius: 50%; border: 2px solid #b9c9d1; flex: none;
  margin-top: 2px; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 12px; font-weight: 800; background: #fff;
}
.msgx-check.on { background: #029DAA; border-color: #029DAA; }
.msgx-empty { text-align: center; padding: 26px 14px 20px; }
.msgx-empty .big { font-size: 34px; margin-bottom: 8px; }
.msgx-empty b { font-size: 13.5px; display: block; margin-bottom: 4px; }
.msgx-empty p { font-size: 12px; color: var(--muted); line-height: 1.5; margin: 0; }

/* Undo toast */
.msgx-undo {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom)); z-index: 2000;
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  background: #16323f; color: #fff; border-radius: 12px; padding: 10px 13px;
  font-size: 12.5px; box-shadow: 0 8px 18px rgba(2,58,80,.25); transition: opacity .25s ease;
  max-width: min(440px, calc(100vw - 24px));
}
.msgx-undo button { background: none; border: none; color: #7fd1d9; font-weight: 800; font-size: 12.5px; cursor: pointer; font-family: var(--font); }

/* Thread screens */
.msgx-thread { max-width: 640px; margin: 0 auto; }
.msgx-thead { display: flex; align-items: center; gap: 9px; padding: 10px 0 9px; border-bottom: 1px solid var(--border); margin-bottom: 10px; }
.msgx-thead .msgx-grow b { font-size: 13.5px; display: block; }
.msgx-thead .msgx-grow span { font-size: 11.5px; color: var(--muted); display: block; }
.msgx-sumbar { border: 1.5px solid var(--navy); border-radius: 14px; padding: 10px 11px; margin-bottom: 11px; box-shadow: 0 4px 10px rgba(2,58,80,.08); background: #fff; }
.msgx-sumr1 { display: flex; gap: 9px; align-items: center; }
.msgx-sumbar b { font-size: 13px; }
.msgx-when { font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.45; }
.msgx-sumacts { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
.msgx-safety {
  display: flex; gap: 8px; background: #f2f7f9; border-radius: 12px; padding: 9px 11px;
  font-size: 12px; color: var(--muted); line-height: 1.5; margin-bottom: 11px;
}
.msgx-msgs { display: flex; flex-direction: column; }
.msgx-sys { text-align: center; margin: 10px 0; }
.msgx-sys span {
  display: inline-block; background: var(--mist-card-2); color: var(--muted); font-size: 11px;
  font-weight: 600; border-radius: 999px; padding: 5px 11px; line-height: 1.4; max-width: 92%;
}
.msgx-bubrow { display: flex; flex-direction: column; margin-bottom: 4px; }
.msgx-bubrow.mine { align-items: flex-end; }
.msgx-bubrow.theirs { align-items: flex-start; }
.msgx-bub {
  max-width: 82%; padding: 8px 11px; border-radius: 14px; font-size: 13.5px; line-height: 1.45;
  position: relative; overflow-wrap: anywhere; min-width: 0;
}
.msgx-bub.them { background: var(--mist-card-2); border-bottom-left-radius: 5px; }
.msgx-bub.me { background: var(--navy); color: #fff; border-bottom-right-radius: 5px; }
.msgx-bub.removed {
  background: var(--mist-card-2); color: var(--muted); font-style: italic; text-align: center; font-size: 12.5px;
}
.msgx-bub.sel { outline: 2.5px solid #029DAA; outline-offset: 1.5px; }
.msgx-bub .msgx-tm { display: block; font-size: 10.5px; margin-top: 4px; opacity: .65; text-align: right; }
.msgx-quote {
  border-left: 3px solid #029DAA; background: rgba(2,157,170,.10); border-radius: 6px;
  padding: 5px 8px; font-size: 12px; margin-bottom: 5px;
}
.msgx-bub.me .msgx-quote { border-left-color: #7fd1d9; background: rgba(255,255,255,.13); }
.msgx-media-img { max-width: 100%; max-height: 260px; border-radius: 10px; display: block; }
.msgx-media-vid { max-width: 100%; max-height: 260px; border-radius: 10px; display: block; background: #16323f; }
.msgx-vidtag { font-size: 10.5px; font-weight: 700; opacity: .75; margin-top: 3px; }
.msgx-media-missing { font-size: 13px; padding: 14px 10px; border: 1.5px dashed var(--border); border-radius: 10px; text-align: center; color: var(--muted); }
.msgx-bubfoot { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; margin: 3px 2px 7px; max-width: 82%; }
.msgx-bubfoot.mine { justify-content: flex-end; }
.msgx-rchip {
  background: #fff; border: 1.5px solid var(--border); border-radius: 999px; font-size: 11px;
  padding: 1px 7px; cursor: pointer; font-family: var(--font); box-shadow: 0 2px 6px rgba(2,58,80,.10);
}
.msgx-rchip.mine { border-color: #029DAA; background: #f2f9fa; font-weight: 700; }
.msgx-mini {
  background: none; border: none; font-size: 11px; color: var(--muted); cursor: pointer;
  font-family: var(--font); font-weight: 700; padding: 2px 4px;
}
.msgx-palette button {
  background: #fff; border: 1.5px solid var(--border); border-radius: 999px; font-size: 13px;
  padding: 1px 6px; cursor: pointer; margin-right: 3px;
}
.msgx-msgcheck {
  display: inline-flex; width: 21px; height: 21px; border-radius: 50%; border: 2px solid #b9c9d1;
  align-items: center; justify-content: center; color: #fff; font-size: 12px; font-weight: 800;
  background: #fff; cursor: pointer; vertical-align: middle; margin-bottom: 5px;
}
.msgx-msgcheck.on { background: #029DAA; border-color: #029DAA; }
.msgx-seen { text-align: right; font-size: 11.5px; color: var(--muted); min-height: 16px; margin: 2px 2px 6px; }
.msgx-replybar {
  display: flex; gap: 8px; align-items: center; background: #f2f9fa; border: 1.5px solid #bcd2dc;
  border-radius: 10px; padding: 7px 10px; font-size: 12px; margin-bottom: 8px;
}
.msgx-replybar button { background: none; border: none; cursor: pointer; font-size: 13px; color: var(--muted); }
.msgx-msgdelbar {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  background: #fff; border: 1.5px solid #f0d9a8; border-radius: 12px; padding: 9px 11px; margin-bottom: 9px;
  font-size: 12.5px; font-weight: 700;
}
.msgx-msgdelbar .msgx-delacts { display: flex; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.msgx-composer { display: flex; gap: 7px; align-items: center; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }
.msgx-attach {
  width: 34px; height: 34px; border-radius: 50%; background: var(--mist-card-2); border: none;
  display: flex; align-items: center; justify-content: center; font-size: 16px; cursor: pointer; flex: none;
}
.msgx-composer input[type="text"] {
  flex: 1; min-width: 0; background: var(--mist-card-2); border: none; border-radius: 999px;
  padding: 10px 13px; font-size: 13.5px; font-family: var(--font); color: var(--text);
}
.msgx-send {
  width: 34px; height: 34px; border-radius: 50%; background: var(--navy); color: #fff; border: none;
  display: flex; align-items: center; justify-content: center; font-size: 14px; cursor: pointer; flex: none;
}
.msgx-case { border: 1.5px solid #bcd2dc; background: #f7fafb; border-radius: 14px; padding: 11px 12px; margin-bottom: 9px; }

/* Large screens: list left, reading pane right, one centered axis. */
@media (min-width: 1024px) {
  .msgx-page { max-width: 1180px; }
  .msgx-layout { display: flex; gap: 16px; align-items: flex-start; }
  .msgx-listpane { width: 340px; flex: none; }
  .msgx-pane { flex: 1; min-width: 0; }
  .msgx-pane-idle {
    display: flex; align-items: center; justify-content: center; min-height: 320px;
    background: #fff; border: 1.5px solid var(--border); border-radius: 16px; box-shadow: 0 8px 22px rgba(2,58,80,.08);
  }
  .msgx-wide .container, .container.msgx-wide { max-width: 1180px; }
  .msgx-side { width: 340px; flex: none; margin-bottom: 0; max-height: calc(100dvh - 140px); overflow-y: auto; }
  .msgx-side-head { text-align: center; font-weight: 700; color: var(--navy); font-size: 14px; padding-bottom: 9px; }
  .msgx-thread { max-width: 660px; }
  .msgx-undo { bottom: 28px; }
}
@media (min-width: 1600px) {
  .msgx-page { max-width: 1240px; }
  .msgx-listpane { width: 380px; }
  .msgx-side { width: 380px; }
  .msgx-thread { max-width: 760px; }
  .msgx-bub { font-size: 14.5px; }
}

/* §INCOME — Income & Payouts home (Donald's design, Oct 19, 2026).
   Mist language; one centered axis at every width (Centering Law);
   laptop/TV get the two-column composition at natural card sizes —
   never stretched (Large-Screen Law). */
.income-page { max-width: 720px; margin: 0 auto; }
.income-page h1 { text-align: center; }
.income-page > p { text-align: center; }
.inc-head { display: flex; flex-direction: column; gap: 16px; margin-bottom: 20px; }
.inc-hero {
  background: var(--mist-navy); color: #fff; border: none; text-align: center;
}
.inc-hero-label { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .85; }
.inc-hero-amount { font-size: 40px; font-weight: 800; line-height: 1.15; margin: 4px 0; }
.inc-hero-sub { font-size: 12px; opacity: .85; max-width: 420px; margin: 0 auto; }
.inc-side { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.inc-side .card { margin-bottom: 0; }
.inc-stat { text-align: center; }
.inc-stat-label { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--mist-muted); }
.inc-stat-amount { font-size: 24px; font-weight: 800; color: var(--mist-navy); margin: 2px 0; }
.inc-stat-sub { font-size: 12px; color: var(--mist-muted); }
.inc-note { text-align: center; max-width: 560px; margin: 0 auto 20px; }
.inc-setup { background: #FFF7E0; border: 1.5px solid var(--mist-amber); text-align: center; }
.inc-setup .btn-row { justify-content: center; }
.inc-request { text-align: center; }
.inc-request .btn-row { justify-content: center; }
.inc-sec-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 24px 0 12px; }
.inc-pills { display: flex; gap: 6px; flex-wrap: wrap; }
.inc-pill {
  border: 1.5px solid var(--mist-line); background: var(--mist-surface); color: var(--mist-ink);
  border-radius: 999px; padding: 6px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
}
.inc-pill.on { background: var(--mist-navy); border-color: var(--mist-navy); color: #fff; }
.inc-source { padding: 0; overflow: hidden; }
.inc-source-head {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: none; border: none; padding: 16px 20px; cursor: pointer; font: inherit;
}
.inc-source-icon { font-size: 22px; }
.inc-source-text { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.inc-source-total { font-size: 17px; font-weight: 800; color: var(--mist-navy); }
.inc-source-chev { color: var(--mist-muted); }
.inc-drill { border-top: 1px solid var(--mist-hairline); padding: 6px 20px 14px; }
.inc-txn { padding: 10px 0; border-top: 1px solid var(--mist-line-2); }
.inc-txn:first-of-type { border-top: none; }
.inc-txn-head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.inc-lines { margin-top: 6px; }
.inc-line { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 2px 0; color: var(--mist-ink); }
.inc-line span:first-child { color: var(--mist-muted); }
.inc-ded span { color: #B45309 !important; }
.inc-total { border-top: 1px solid var(--mist-hairline); margin-top: 4px; padding-top: 6px; font-weight: 700; }
.inc-total span:first-child { color: var(--mist-ink); }
.inc-txn-foot { margin-top: 6px; }
.inc-chip { display: inline-block; font-size: 11px; font-weight: 700; border-radius: 999px; padding: 3px 10px; }
.inc-chip-paid { background: #E7F6E3; color: #2C6E1E; }
.inc-chip-sched { background: #E0F4F6; color: #027A87; }
.inc-chip-wait { background: #FDF3D7; color: #8A6D00; }
.inc-history .card { margin-bottom: 12px; }
.inc-payout .inc-txn-head { align-items: center; }
.inc-opt {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  border: 1.5px solid var(--mist-line); border-radius: 12px; padding: 12px 14px; margin: 10px 0; cursor: pointer;
}
.inc-opt.on { border-color: var(--mist-navy); background: #F2F8FA; }
.inc-opt-amt { font-weight: 700; color: var(--mist-navy); text-align: right; }
@media (min-width: 1024px) {
  .income-page { max-width: 1180px; }
  .inc-layout { display: grid; grid-template-columns: 380px 1fr; gap: 20px; align-items: start; }
  .inc-head { margin-bottom: 0; }
  .inc-rail .card { margin-bottom: 20px; }
  .inc-rail { position: sticky; top: 16px; }
  .inc-note { margin: 0 0 20px; text-align: left; }
  .inc-sources { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
  /* Centering Law: a lone final source card centers as a group at
     its natural (half-row) width — never stretched to fill. */
  .inc-sources > .inc-source:last-child:nth-child(odd) {
    grid-column: 1 / -1; width: calc(50% - 10px); margin: 0 auto;
  }
  .inc-sources .card { margin-bottom: 0; }
  .inc-main > h3.mt { margin-top: 28px; }
}
@media (min-width: 1600px) {
  .income-page { max-width: 1240px; }
  .inc-hero-amount { font-size: 46px; }
  .inc-stat-amount { font-size: 27px; }
  .inc-source-total { font-size: 19px; }
}

/* ================================================================
   Account Recognition kit (Donald's Oct 21, 2026 — approved design:
   files/account-recognition-design.html). One identity language
   everywhere a person appears, always in this order:
   ringed picture · name · ✓ Trusted medallion · tier chip · role.
   Classes are kit- prefixed so they can never collide with the
   app's existing chip/role styles. The ring says what an account
   BOUGHT; the green ✓ says who finished all 6 verification steps.
   The two signals never merge. Free accounts get NO chip — the
   white ring only (Donald's ruling, Oct 21, 2026).
   ================================================================ */
/* SHARP STRONG DROP SHADOW on EVERY ring (Donald's Oct 22, 2026
   order): a firm offset shadow with a small blur (defined edge)
   plus a tight contact shadow, so a ringed picture lifts off any
   surface — cream, white cards, and photos alike. Defined once,
   here, so every ring on every surface matches. */
/* Flex-stretch hardening (Oct 23, 2026): flex:none already pins the main
   axis (0 0 auto), but a ring placed as a direct flex item in a row whose
   parent sets NO align-items was stretched by the default
   align-items:stretch into a tall oval (found in the group thread).
   fit-content sizing takes the ring out of stretch entirely — stretch
   only acts on an auto cross size — in both axes, while center and
   flex-start parents keep aligning the same content-sized box as
   before, so no existing layout moves. One base rule covers every
   ring size (xs/sm/base/lg all share .kit-ring). */
.kit-ring { display: inline-flex; border-radius: 50%; padding: 3px; flex: none; width: fit-content; height: fit-content; vertical-align: middle; box-shadow: 0 3px 8px rgba(20,26,34,.45), 0 1px 2px rgba(20,26,34,.35); }
.kit-ring img, .kit-ring .kit-face { border-radius: 50%; display: block; }
.kit-ring .kit-face { display: flex; align-items: center; justify-content: center; font-weight: 700; color: #fff; overflow: hidden; }
.kit-face { border-radius: 50%; }
.kit-ring-lg { padding: 4px; }
.kit-ring-sm { padding: 2.5px; }
/* Free edge strengthened Oct 23, 2026 (booking-ring recurrence #2):
   the old silver #CECFD4 at 1.5px on the white detail card was
   effectively invisible at 32px — Donald read a Free counterparty's
   picture as ringless. The Free BAND stays white (tier color
   unchanged); only its silver edge deepens to #8A96A1 so the ring
   reads at every size, on white and on cream.
   Recurrence #3 (Oct 23 late): #8A96A1 at 2px STILL washed out on a
   PHOTO at 32px (parent screenshot proof against the live CSS — the
   hairline competes with photo content and loses). The edge deepens
   to slate #475569 everywhere, and the small (28–39px) range goes
   to a 3px edge. The band stays white; tier colors unchanged. */
.kit-ring-free { background: #ffffff; border: 1.5px solid #475569; }
.kit-ring-sm.kit-ring-free { border-width: 3px; }
.kit-ring-plus { background: #023A50; }
.kit-ring-pro { background: #F97316; }
.kit-ring-biz { background: #C4040B; }
/* Under 28px the ring degrades to a single 2px outline (no gap);
   Free's outline is its silver edge — white alone vanishes on cream.
   The xs outline carries the same strong shadow, tightened a step
   for the small size. */
.kit-ring-xs { padding: 0; background: transparent; border: 2px solid #023A50; box-shadow: 0 2px 5px rgba(20,26,34,.50), 0 1px 2px rgba(20,26,34,.40); }
.kit-ring-xs.kit-ring-free { border-color: #475569; }
.kit-ring-xs.kit-ring-plus { border-color: #023A50; }
.kit-ring-xs.kit-ring-pro { border-color: #F97316; }
.kit-ring-xs.kit-ring-biz { border-color: #C4040B; }
.kit-chip { display: inline-flex; align-items: center; font-size: 10px; font-weight: 800; letter-spacing: .6px; padding: 2.5px 7px; border-radius: 999px; color: #fff; white-space: nowrap; }
.kit-chip-plus { background: #023A50; }
.kit-chip-pro { background: #F97316; }
.kit-chip-biz { background: #C4040B; }
.kit-tcheck { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: #43A002; color: #fff; font-size: 10.5px; font-weight: 800; flex: none; }
.kit-role { display: inline-flex; align-items: center; font-size: 10px; font-weight: 700; letter-spacing: .3px; padding: 2.5px 7px; border-radius: 999px; background: #f4f1ea; color: #6b6252; border: 1px solid #e3ddd0; white-space: nowrap; }
.kit-role-team { background: #023A50; color: #FBD184; border-color: #023A50; }
.kit-name { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; font-weight: 700; color: #1c2733; }
/* Tier-themed profiles — the profile wears its tier. Structure never
   changes; only this color finish escalates. */
.kit-band { height: 58px; }
.kit-band-free { background: linear-gradient(180deg,#ffffff,#eef0f1); border-bottom: 1.5px solid #475569; }
.kit-band-plus { background: linear-gradient(135deg,#0B4A66,#023A50 55%,#01293B); }
.kit-band-pro { background: linear-gradient(135deg,#FB923C,#F97316 55%,#EA580C); }
.kit-band-biz { background: linear-gradient(135deg,#F6040C,#C4040B 55%,#8C030A); }
.kit-sec { margin: 14px 0 10px; padding-top: 10px; font-size: 11px; font-weight: 800; letter-spacing: 1.2px; text-transform: uppercase; }
.kit-sec-free { color: #6b7684; border-top: 1.5px solid #475569; }
.kit-sec-plus { color: #023A50; border-top: 2px solid #FBD184; }
.kit-sec-pro { color: #9A3412; border-top: 2px solid #F97316; }
.kit-sec-biz { color: #8C030A; border-top: 2px solid #C4040B; }
.kit-btn-plus { background: linear-gradient(135deg,#0B4A66,#023A50); color: #FBD184; }
.kit-btn-pro { background: #EA580C; color: #fff; }
.kit-btn-biz { background: linear-gradient(135deg,#C4040B,#8C030A); color: #fff; }
.kit-bd { font-size: 10.5px; font-weight: 700; padding: 5px 9px; border-radius: 999px; white-space: nowrap; }
.kit-bd-free { background: #F1F2F4; color: #43505e; }
.kit-bd-plus { background: #EAF1F5; color: #023A50; }
.kit-bd-pro { background: #FFF1E6; color: #9A3412; }
.kit-bd-biz { background: #FDECEC; color: #8C030A; }
/* "How to read an account" legend rows (Profile + Help). */
.kit-legend-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 4px; }
.kit-legend-row + .kit-legend-row { border-top: 1px solid #eef0ee; }
.kit-legend-row .kit-mean { font-size: 12.5px; color: #43505e; line-height: 1.55; }
.kit-legend-row .kit-mean strong { color: #1c2733; }
/* Listing-card owner line (Discover / search / storefront grids):
   24px outline ring · name · ✓ · chip, one quiet line. */
.kit-owner-line { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.kit-owner-name { font-size: 12px; font-weight: 600; color: #43505e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Reaction bar (Donald's Oct 21, 2026 design) — one slim row of pill
   buttons under a listing / ad / pool tool. The lit button wears the
   navy brand fill; counts ride inside their button; the row never
   grows a card of its own. */
.reaction-bar { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.reaction-btn { display: inline-flex; align-items: center; gap: 4px; border: 1.5px solid #CECFD4; background: #fff; color: #43505e; border-radius: 999px; padding: 5px 11px; font-size: 13.5px; line-height: 1.2; cursor: pointer; }
.reaction-btn:hover { border-color: #023A50; }
.reaction-btn.on { background: #023A50; border-color: #023A50; color: #fff; }
.reaction-btn .reaction-n { font-weight: 700; font-size: 12.5px; }
.reaction-share { color: #023A50; font-weight: 600; }
.reaction-counts-line { font-size: 12.5px; color: #6b7684; font-weight: 600; }
/* The ad unit (Oct 21, 2026 — the all-pages structural fix for
   Donald's grid distortion report): AdSlot.render and the Discover
   top slot wrap the card + its reaction row in ONE .ad-unit, the
   slot's only child. The unit is a vertical stack at full width —
   the card flexes, the row takes its natural height UNDER it — so
   no slot container (flex-row, grid cell, anything) can ever put
   the row beside the card and crush it again. In a plain block
   slot the flex properties are inert and it renders exactly as
   the bare card + row did. */
.ad-unit { display: flex; flex-direction: column; width: 100%; min-width: 0; flex: 1 1 auto; min-height: 0; }
.ad-unit > .ad-card { flex: 1 1 auto; min-height: 0; }
.ad-unit > .ad-reaction-row { flex: none; }
/* The reaction row an ad carries under its card (Oct 21, 2026 design:
   the same small row on every surface the ad runs). */
.ad-reaction-row { margin-top: 6px; }
/* Grid cells (Merch / storefront): the row is a full-width strip under
   the card — never a side rail (Donald's Oct 21, 2026 distortion
   report: beside the card it crushed the creative into a narrow
   column and stacked the buttons vertically). Slightly tighter here
   so the cell keeps its one-product-cell total height. */
.merch-grid .merch-ad-cell .ad-reaction-row,
#pub-tools .tool-grid .sf-ad-cell .ad-reaction-row { margin-top: 4px; }
.merch-grid .merch-ad-cell .ad-reaction-row .reaction-btn,
#pub-tools .tool-grid .sf-ad-cell .ad-reaction-row .reaction-btn { padding: 4px 9px; font-size: 12.5px; }
/* One line, always: in a half-width phone cell the four buttons only
   fit on a single line with the Share label icon-only (its accessible
   name rides the button's aria-label/title as everywhere else). */
.merch-grid .merch-ad-cell .ad-reaction-row .reaction-share-label,
#pub-tools .tool-grid .sf-ad-cell .ad-reaction-row .reaction-share-label { display: none; }
.merch-grid .merch-ad-cell .ad-reaction-row .reaction-bar,
#pub-tools .tool-grid .sf-ad-cell .ad-reaction-row .reaction-bar { flex-wrap: nowrap; gap: 4px; }

/* ---- Price Coach Box (Oct 21, 2026 — competitor-beating price coach).
   First instance of the Dynamic Platform motion tokens: 260ms reveal on
   --mist-ease, transform/opacity only, house shadow, centered title,
   muted 12px descriptive text (house style). prefers-reduced-motion
   collapses every animation below — content simply appears. ---- */
.pcb { background:#EDF6E4; border:1px solid rgba(67,160,2,.35); border-radius:14px;
  box-shadow: var(--mist-shadow); padding:12px 14px; margin-bottom:12px; text-align:center; }
.pcb-in { animation: pcbIn .26s var(--mist-ease) both; }
@keyframes pcbIn { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }
.pcb-title { font-size:13px; font-weight:700; color:var(--navy); text-align:center; margin:0 0 2px; }
.pcb-sub { font-size:12px; color:var(--muted); margin:0; }
.pcb-price { font-size:24px; font-weight:800; color:var(--navy); line-height:1.15; margin:4px 0 2px; font-variant-numeric:tabular-nums; }
.pcb-price small { font-size:13px; font-weight:600; color:var(--muted); }
.pcb-guide { font-size:12px; margin:6px 0 0; min-height:15px; }
.pcb-guide.above { color:#9a6a00; }
.pcb-guide.good { color:#2f7d0a; }
.pcb-use { margin-top:8px; }
.pcb-skel { height:14px; border-radius:7px; background:rgba(2,58,80,.10); margin:6px auto; animation:pcbPulse 1.2s ease-in-out infinite; }
@keyframes pcbPulse { 50% { opacity:.4; } }
@media (prefers-reduced-motion: reduce) {
  .pcb-in { animation:none; }
  .pcb-skel { animation:none; }
}

/* Garages pause (Donald's Oct 21, 2026 order): TNFlags adds
   .tn-garages-off to <html> while GET /api/features reports
   garages_enabled=false — hides the header Garages nav link and the
   account-menu Garages row. Removed automatically when garages return. */
html.tn-garages-off a[data-nav="garages"],
html.tn-garages-off #mobile-menu a[href="#/garages"] { display: none !important; }

/* Centered kit name line (Donald's Oct 22, 2026 — appended at the
   end of this file by the profile-centering build; the blink rules
   above are untouched). The name stays dead-center under the
   profile picture in every badge state: the visible ✓/chip bits on
   the right are balanced by an invisible mirror of the same bits on
   the left (.kit-cname-mirror), so the pair weighs the same on both
   sides and adding a badge can never push the name off-center.
   Stacked form (.kit-cname-stack, long names): the mirror hides and
   the bits take their own centered row under the name. The 5px
   internal gap matches .kit-name so the ✓ and chip keep the same
   spacing they have everywhere else. */
.kit-cname { display: inline-flex; align-items: center; gap: .3em; }
.kit-cname-name { flex: none; white-space: nowrap; }
.kit-cname-mirror { display: inline-flex; align-items: center; gap: 5px; visibility: hidden; flex: none; }
.kit-cname-bits { display: inline-flex; align-items: center; gap: 5px; flex: none; }
.kit-cname-stack { flex-direction: column; gap: 0; max-width: 100%; }
.kit-cname-stack .kit-cname-mirror { display: none; }
.kit-cname-stack .kit-cname-name { white-space: normal; text-align: center; }
.kit-cname-stack .kit-cname-bits { margin-top: 4px; }

/* ==================================================================
   §MSGX-REDESIGN — message thread redesign (Donald's Oct 22, 2026:
   "Re design the message store owner page… Not to my esthetic
   standard"). Appended at EOF; every rule is scoped to the thread's
   own msgx- classes and nothing above is edited. What it does:
   (1) the thread column gains a small inset — the phone shell hands
   the view a bare host, so the old layout ran edge-to-edge;
   (2) the flat header strip becomes a CARD (identity row + actions
   row) and its actions leave the .btn family: .btn-sm under the
   coarse-pointer 48px rule is what blew "Select" up into a giant
   circle on touch devices — .msgx-actbtn is a scoped 34px quiet
   button that rule can never reach;
   (3) the composer becomes one designed bar with a single 44px
   control family (attach · input · send);
   (4) the helper line is one clean muted 12px line (no duplicate
   camera glyph, non-breaking units + balanced wrap — no orphan);
   (5) the empty state is the composed house empty, centered in the
   conversation area instead of floating at the top of a blank page;
   (6) the back link becomes a designed back row (chevron + label,
   no raw underline). Bubbles, dividers, chips and bars keep their
   existing rules above.
   ================================================================== */
.msgx-thread { padding-left: 14px; padding-right: 14px; }

/* (6) Back row */
.msgx-backrow { margin: 6px 0 10px; }
/* Designed back row (DA-07): the thread back row promoted platform-wide —
   chevron + label, navy, no underline; replaces the raw "←" text links. */
.backrow { margin: 6px 0 10px; }
.back {
  display: inline-flex; align-items: center; gap: 3px;
  color: var(--navy); font-weight: 700; font-size: 13px;
  text-decoration: none; padding: 4px 2px;
}
.back:hover { text-decoration: underline; }
.back-chev { font-size: 21px; line-height: .8; font-weight: 400; transform: translateY(-1px); }
.msgx-back {
  display: inline-flex; align-items: center; gap: 3px;
  color: var(--navy); font-weight: 700; font-size: 13px;
  text-decoration: none; padding: 4px 2px;
}
.msgx-back:hover { text-decoration: underline; }
.msgx-back-chev { font-size: 21px; line-height: .8; font-weight: 400; transform: translateY(-1px); }

/* (2) Header card */
.msgx-thead.msgx-thead2 {
  display: block; background: #fff;
  border: 1.5px solid var(--border); border-radius: 16px;
  box-shadow: 0 10px 24px rgba(2, 58, 80, .09);
  padding: 13px 14px 11px; margin: 0 0 12px;
}
.msgx-thead-main { display: flex; align-items: center; gap: 11px; }
.msgx-thead-av { flex: none; display: inline-flex; }
.msgx-thead-av .msgx-avatar { width: 46px; height: 46px; font-size: 16px; }
.msgx-thead2 .msgx-grow { min-width: 0; }
.msgx-thead2 .msgx-grow b.msgx-tname { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 15.5px; font-weight: 700; line-height: 1.25; }
/* The legacy subtitle rule (.msgx-thead .msgx-grow span — display:block,
   11.5px, muted) is a descendant selector: it also stomps the Kit bits
   (✓ + tier chip) that live inside the name and the group chip in the
   subtitle, stretching the tier chip into a full-width bar. Inside the
   redesigned header only, the bits keep their Kit rendering. */
.msgx-thead2 .msgx-grow .kit-tcheck { display: inline-flex; font-size: 10.5px; color: #fff; }
.msgx-thead2 .msgx-grow .kit-chip { display: inline-flex; font-size: 10px; color: #fff; }
.msgx-thead2 .msgx-tsub .msgx-chipst { display: inline-block; font-size: 10.5px; }
.msgx-thead2 .msgx-tsub .msgx-chipst.navy { color: var(--navy); }
.msgx-thead2 .msgx-grow .msgx-tsub { font-size: 12px; color: var(--muted); display: block; margin-top: 2px; line-height: 1.45; }
.msgx-thead-actions {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--border);
}
.msgx-ta-links { display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.msgx-ta-btns { display: inline-flex; align-items: center; gap: 7px; margin-left: auto; }
.msgx-actbtn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 34px; min-height: 34px; padding: 0 13px; border-radius: 999px;
  border: 1.5px solid #bcd2dc; background: #fff; color: var(--navy);
  font-size: 12px; font-weight: 700; font-family: var(--font); line-height: 1;
  cursor: pointer; text-decoration: none; box-shadow: 0 2px 6px rgba(2, 58, 80, .06);
}
.msgx-actbtn.on { background: var(--navy); border-color: var(--navy); color: #fff; }

/* (3) Composer bar — one 44px family */
.msgx-composer {
  background: #fff; border: 1.5px solid var(--border); border-radius: 18px;
  box-shadow: 0 10px 24px rgba(2, 58, 80, .08);
  padding: 8px; gap: 8px; margin-top: 10px;
}
.msgx-attach { width: 44px; height: 44px; font-size: 19px; }
.msgx-composer input[type="text"] { height: 44px; padding: 0 15px; font-size: 14px; }
.msgx-send { width: 44px; height: 44px; font-size: 16px; }

/* (4) Helper line */
.msgx-helpline {
  text-align: center; font-size: 12px; color: var(--muted);
  margin: 8px 6px 0; line-height: 1.5; text-wrap: balance;
}

/* (5) Composed empty state */
.msgx-msgs.is-empty { min-height: 34vh; align-items: center; justify-content: center; }
.msgx-tempty { text-align: center; padding: 18px 12px; }
.msgx-tempty-ic {
  width: 64px; height: 64px; margin: 0 auto 12px; border-radius: 50%;
  background: var(--mist-card-2); box-shadow: inset 0 0 0 1.5px var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 30px;
}
.msgx-tempty h3 { margin: 0 0 4px; font-size: 15px; color: var(--text); }
.msgx-tempty p { margin: 0; font-size: 12.5px; color: var(--muted); }

/* People section in the Discover result slide (Donald's Oct 22,
   2026 — appended at the end of this file by the discover-names
   build; everything above is untouched). Same calm centered card
   family as the drawer group cards: the ringed picture sits on top,
   the Kit name under it, one muted facts line below. */
#drawer-people { margin: 2px 0 18px; }
.drawer-person-card { display: block; text-align: center; background: var(--card); border: 1px solid var(--border); border-radius: 18px; padding: 14px 16px; box-shadow: 0 10px 24px rgba(38,35,30,.08); text-decoration: none; color: var(--text); transition: transform var(--tn-motion-fast, .18s) ease, box-shadow var(--tn-motion-fast, .18s) ease; }
.drawer-person-card:hover { transform: translateY(-1px); box-shadow: 0 14px 28px rgba(38,35,30,.12); }
.dpc-face { display: flex; justify-content: center; margin-bottom: 8px; }

/* Storefront row on the Discover person card (Donald's Oct 22, 2026
   steering — appended by the discover-names build): the card is a
   container now — the face/name/facts zone is the profile link
   (.dpc-main), and a person with a public storefront gets a clearly
   tappable storefront row under it, in the profile page's own
   "Visit storefront →" language. */
.drawer-person-card { padding: 0; overflow: hidden; }
.dpc-main { display: block; padding: 14px 16px; text-decoration: none; color: inherit; }
.drawer-person-card.has-store .dpc-main { padding-bottom: 10px; }
.dpc-store { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 9px 12px 11px; border-top: 1px solid var(--border); text-decoration: none; color: var(--text); font-size: 13px; }
.dpc-store-name { font-weight: 650; }
.dpc-store-go { color: var(--red); font-weight: 700; white-space: nowrap; }

/* ---------- Online presence (Donald's Oct 25, 2026; binary
   since Oct 26, 2026) ----------
   The derived state drawn by js/presence.js: a dot beside the tier
   ring (green = online now, gray = not online) and, where a surface
   has room, the words beside it. Hidden members render nothing at
   all — no dot, no words. */
.presence-dot { display: inline-block; width: 11px; height: 11px; border-radius: 50%; background: #1E9E5A; box-shadow: 0 0 0 2.5px #fff; flex: none; }
.presence-dot.offline { background: #A8B3BE; }
.presence-label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap; }
.presence-label.presence-online { color: #157347; font-weight: 700; }
.presence-label.presence-offline { color: #6B7684; font-weight: 600; }
.presence-anchor { position: relative; display: inline-flex; flex: none; }
.presence-anchor > .presence-dot { position: absolute; right: -2px; bottom: -2px; z-index: 1; }
.msgx-tpresence { display: block; margin-top: 1px; }
.presence-line-center { text-align: center; margin-top: 6px; }
