/* Rather Be Properties — Flask skeleton.
   Colors lifted from the React app so look-and-feel stays continuous.
   The :root block defines the light theme; [data-theme="dark"] overrides
   the same variables for dark mode. CSS variables propagate everywhere,
   so the toggle re-themes the whole UI in one assignment.

   Inter is self-hosted as a variable WOFF2 — one file covers every
   weight 100-900 so we can use 400/500/600/700 (or any value) without
   shipping multiple font files. `font-display: swap` shows the system
   stack first, then upgrades to Inter when the WOFF2 finishes loading
   — no FOIT. */
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/InterVariable.woff2") format("woff2-variations"),
       url("/static/fonts/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/InterVariable-Italic.woff2") format("woff2-variations"),
       url("/static/fonts/InterVariable-Italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
:root {
  --accent: #E8637A;
  --accent-soft: #F4A5B4;
  --accent-cool: #3A9BC1;
  --text: #2A3540;
  --text-soft: #5C6B7A;
  --text-mute: #94A0AC;
  --border: rgba(42,53,64,0.10);
  --bg: #FCFAF7;
  --bg-mesh-1: rgba(232,99,122,0.12);
  --bg-mesh-2: rgba(58,155,193,0.10);
  --surface: rgba(255,255,255,0.78);
  --surface-solid: #FFFFFF;
  --sidebar-bg: linear-gradient(180deg, rgba(252,250,247,0.92) 0%, rgba(253,244,246,0.88) 100%);
  --sidebar-border: rgba(232,99,122,0.12);
  --info-bg: #F5F0FB;
  --info-border: rgba(123,94,167,0.20);
  --header-tab-bg: #fff;
  --header-tab-border: #E3EDF5;
  --progress-track: rgba(44,36,25,0.06);
  --note-bg: #FFFBEA;
  --note-border: rgba(245,200,66,0.40);
  --jay: #3DAA6E;
  --kaye: #7B5EA7;
  --mairene: #1A8AC0;
  --elissa: #E8637A;
  --al: #888888;
  --yellow: #F5C842;
  --shadow: 0 1px 4px rgba(0,0,0,0.05);
  --shadow-lg: 0 20px 60px -20px rgba(232,99,122,0.18);

  /* ---- Cohesion tokens — single source of truth for cross-component
     spacing, sizing, and theme-able color groups. Added during the
     UI cohesion sweep so every page reads from the same scale. ---- */

  /* Channel colors (Airbnb / BDC / Direct / Marriott / VRBO). Previously
     hardcoded as inline hex on the launch form. Now overridable per theme. */
  --channel-airbnb:   #FF5A5F;
  --channel-bdc:      #003580;
  --channel-direct:   #14B8A6;
  --channel-marriott: #A41E22;
  --channel-vrbo:     #3D67FF;

  /* Status / semantic colors — map to existing owner hues to keep
     visual continuity (jay=green=success, accent=coral=error, etc.). */
  --success: var(--jay);
  --warning: var(--yellow);
  --error:   var(--accent);
  --info:    var(--accent-cool);

  /* Page-level layout — uniform breathing room across Home, Properties,
     Property detail, Launch, Notifications, Settings. */
  --page-max-width: 1080px;
  --page-pad-top: 56px;
  --page-pad-side: 36px;
  --page-pad-bottom: 80px;

  /* Cohesive button + icon-button geometry. */
  --btn-radius: 999px;
  --btn-pad-y: 10px;
  --btn-pad-x: 22px;
  --btn-pad-y-sm: 6px;
  --btn-pad-x-sm: 12px;
  --btn-shadow: 0 8px 20px -8px color-mix(in srgb, var(--accent) 55%, transparent);
  /* 28px matches the existing card-pin / card-delete footprint so the
     unified .btn-icon doesn't shift fixed layouts that depended on it. */
  --icon-btn-size: 28px;
  --icon-btn-radius: 10px;

  /* Standardized tint scale for color-mix() backgrounds. Replaces the
     ad-hoc 8/10/12/14% values scattered across hover rules. */
  --tint-hover: 8%;
  --tint-bg:    12%;
  --tint-strong: 22%;
  --tint-border: 35%;

  /* Themed scrollbar — single rule applied via .scroll-themed below. */
  --scrollbar-thumb: color-mix(in srgb, var(--text-mute) 50%, transparent);
  --scrollbar-thumb-hover: color-mix(in srgb, var(--text-mute) 70%, transparent);

  /* ------------------------------------------------------------------ *
   * Phase A — Typography                                              *
   * ------------------------------------------------------------------ *
   * Inter loaded above via @font-face. System stack is the fallback   *
   * while WOFF2 streams in (font-display: swap), and stays in place   *
   * for users on networks/devices where Inter never loads.            */
  --font-sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont,
               "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* Type scale — strict T-shirt scale, applied via semantic tokens.
     Use these instead of one-off font-size literals so the scale stays
     coherent. Line-heights are tuned per size: tighter at display
     sizes, generous at body for legibility. */
  --fs-eyebrow: 11px;   --lh-eyebrow: 1.4;
  --fs-small:   12px;   --lh-small:   1.45;
  --fs-body:    13px;   --lh-body:    1.55;
  --fs-input:   14px;   --lh-input:   1.4;
  --fs-card-title: 17px; --lh-card-title: 1.3;
  --fs-section: 24px;   --lh-section: 1.25;
  --fs-page:    32px;   --lh-page:    1.2;
  --fs-hero:    42px;   --lh-hero:    1.1;

  /* Weight scale */
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-bold:    700;

  /* ------------------------------------------------------------------ *
   * Phase A — Semantic color roles                                    *
   * ------------------------------------------------------------------ *
   * Components SHOULD reference these, not the raw tokens above.      *
   * Dark mode overrides the role; raw tokens stay the same.           *
   * Maps:                                                             *
   *   bg-canvas    = whole-page background                            *
   *   bg-surface   = standard card / panel background                 *
   *   bg-elevated  = popovers, modals, dropdowns                      *
   *   text-primary = body text + headings                             *
   *   text-secondary = sub-labels, lede paragraphs                    *
   *   text-muted   = placeholders, eyebrows, hints                    *
   *   text-inverse = text on accent backgrounds (white on coral)      *
   *   action-primary = primary action color (coral)                   *
   *   action-secondary = secondary accent (blue)                      *
   *   state-success / warning / error / info                          *
   *   border-subtle / border-strong                                   */
  --bg-canvas:      var(--bg);
  --bg-surface:     var(--surface);
  --bg-surface-solid: var(--surface-solid);
  --bg-elevated:    var(--surface-solid);
  --text-primary:   var(--text);
  --text-secondary: var(--text-soft);
  --text-muted:     var(--text-mute);
  --text-inverse:   #fff;
  --action-primary:   var(--accent);
  --action-secondary: var(--accent-cool);
  --state-success: var(--success);
  --state-warning: var(--warning);
  --state-error:   var(--error);
  --state-info:    var(--info);
  --border-subtle: var(--border);
  --border-strong: color-mix(in srgb, var(--text) 20%, transparent);
}

/* Dark theme — softer charcoal-navy (lifted from the previous near-black
   #0F1115 to #171A24) so long sessions don't feel like staring into a
   void. Three-tier surface hierarchy (bg → surface → elevated). Accents
   pulled back to a kinder pink. Sidebar shares the canvas tone but is
   subtly lighter so it reads as a defined region without a hard border.
   Mesh-gradient opacity boosted from 7% → 12% so the warm/cool wash is
   actually visible — it gives the canvas depth instead of looking flat. */
[data-theme="dark"] {
  --accent:      #EC8FA1;
  --accent-soft: #F4B0BD;
  --accent-cool: #82C4DD;
  --text:        #E6EAF0;
  --text-soft:   #A8B0BD;
  --text-mute:   #6A7280;
  --border:      rgba(255, 255, 255, 0.08);
  --bg:          #171A24;
  --bg-mesh-1:   rgba(236, 143, 161, 0.12);
  --bg-mesh-2:   rgba(130, 196, 221, 0.12);
  --surface:        rgba(255, 255, 255, 0.045);
  --surface-solid:  #1F232E;
  --sidebar-bg:     #1B1F2A;
  --sidebar-border: rgba(255, 255, 255, 0.07);
  --info-bg:     rgba(140, 110, 200, 0.10);
  --info-border: rgba(140, 110, 200, 0.24);
  --header-tab-bg:     #1F232E;
  --header-tab-border: rgba(255, 255, 255, 0.06);
  --progress-track: rgba(255, 255, 255, 0.08);
  --note-bg:     rgba(245, 200, 66, 0.07);
  --note-border: rgba(245, 200, 66, 0.32);
  --shadow:    0 1px 2px rgba(0, 0, 0, 0.32);
  --shadow-lg: 0 24px 60px -28px rgba(0, 0, 0, 0.55),
               0 0 0 1px rgba(255, 255, 255, 0.025);

  /* Dark-mode channel colors: lift luminance ~12% so brand reds and
     deep blues stay readable on the dark canvas without losing identity. */
  --channel-airbnb:   #FF7B7F;
  --channel-bdc:      #5586D9;
  --channel-direct:   #3FCDB8;
  --channel-marriott: #D44A50;
  --channel-vrbo:     #6E89FF;

  --scrollbar-thumb: color-mix(in srgb, var(--text-mute) 60%, transparent);
  --scrollbar-thumb-hover: color-mix(in srgb, var(--text-mute) 85%, transparent);

  /* Dark-mode semantic role overrides — only the values that need
     different mappings in dark mode. Most roles inherit the same
     raw token (which itself flipped above). */
  --bg-elevated:   #262B36;          /* one notch above --surface-solid for popovers */
  --border-strong: color-mix(in srgb, #FFFFFF 14%, transparent);
}
/* Dual radial wash + a vertical tonal fade — gives the canvas real
   depth so it doesn't read as a flat slab. The opacity comes from the
   tokens above so this is one place to dial intensity. */
[data-theme="dark"] body {
  background-image:
    radial-gradient(ellipse 90% 60% at 0% 0%,     var(--bg-mesh-1) 0%, transparent 60%),
    radial-gradient(ellipse 80% 60% at 100% 100%, var(--bg-mesh-2) 0%, transparent 60%),
    linear-gradient(180deg, rgba(255,255,255,0.012) 0%, transparent 40%);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  color: var(--text-primary);
  background: var(--bg-canvas);
  /* Softer single accent wash — was two competing radial gradients before. */
  background-image: radial-gradient(ellipse 80% 60% at 100% 0%, var(--bg-mesh-2) 0%, transparent 50%);
  background-attachment: fixed;
  min-height: 100vh;
  line-height: var(--lh-body);
  font-size: var(--fs-body);
  /* Render Inter at its designed weight, with OpenType features that
     improve text rhythm: contextual alternates (cv11 for nicer 1/4/6),
     ligatures, kerning. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "cv11", "ss01", "ss03", "calt", "kern";
  transition: background-color 0.25s ease, color 0.25s ease;
}
/* Tabular numerals wherever digit columns line up: stat strip, progress
   percentages, counters, kbd shortcuts. Keeps numbers from jittering as
   they update. */
.stat-value,
.prog-pct,
.prog-summary,
.my-tasks-count,
.bulk-bar-count,
.launch-progress-count,
#launch-progress-filled,
.timeline-time,
.notif-row-when,
.api-key-status code,
kbd { font-variant-numeric: tabular-nums; }

h1, h2, h3, h4, h5, h6 { line-height: 1.2; }
h1 { letter-spacing: -0.5px; }
h2 { letter-spacing: -0.2px; }

a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

/* Layout */
.layout {
  display: flex;
  min-height: 100vh;
}

/* Sidebar */
.sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
  padding: 14px 12px;
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: width 0.22s ease, background 0.25s ease, border-color 0.25s ease;
}

/* Header row: just the hamburger toggle now (logo removed — lives on
   Home hero + login). Toggle is left-aligned because that's where
   nav-menu controls live in every modern app (Linear / Notion / Slack). */
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 4px 2px 8px;
  border-bottom: 1px solid var(--border);
}
.sidebar-toggle {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-soft);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.sidebar-toggle:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  margin-top: 4px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 10px;
  color: var(--text-soft);
  font-size: 12.5px;
  font-weight: 600;
  border: 1.5px solid transparent;
  transition: background 0.2s, border-color 0.2s, padding 0.22s ease;
  white-space: nowrap;
  overflow: hidden;
}
.nav-item:hover { background: color-mix(in srgb, var(--text-mute) 8%, transparent); }
.nav-item.is-active {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent-soft) 30%, transparent),
    color-mix(in srgb, var(--accent-cool) 20%, transparent));
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--text);
}
.nav-item svg { flex-shrink: 0; }
.nav-label { transition: opacity 0.15s ease; }

/* Collapsed sidebar: 56px wide, labels hidden, icons centered. The
   hamburger toggle stays the same in both states — no rotation needed
   since the icon reads identically either way. */
[data-sidebar="collapsed"] .sidebar { width: 56px; }
[data-sidebar="collapsed"] .sidebar-header { justify-content: center; }
[data-sidebar="collapsed"] .nav-item {
  justify-content: center;
  padding: 9px 0;
}
[data-sidebar="collapsed"] .nav-label { display: none; }

/* (Sidebar user pill removed — user controls live in the topbar now.) */

/* ---------- Auth page (login) ---------- */
.auth-body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  background-image:
    radial-gradient(ellipse 70% 55% at 10% 5%,  var(--bg-mesh-1) 0%, transparent 55%),
    radial-gradient(ellipse 65% 50% at 95% 95%, var(--bg-mesh-2) 0%, transparent 55%);
  background-attachment: fixed;
  font-family: var(--font-sans);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
}
.auth-shell {
  width: 100%;
  max-width: 440px;
}
.auth-card {
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  -webkit-backdrop-filter: blur(40px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px 32px 28px;
  box-shadow: var(--shadow-lg);
  text-align: center;
}
.auth-logo {
  display: block;
  margin: 0 auto 18px;
  width: 96px;
  height: auto;
  max-height: 96px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,0.08));
}
[data-theme="dark"] .auth-logo {
  filter: drop-shadow(0 4px 16px rgba(0,0,0,0.45));
}
.auth-eyebrow {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.auth-title {
  font-size: 26px;
  font-weight: 300;
  letter-spacing: -0.4px;
  margin: 0 0 10px;
}
.auth-lede {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-soft);
  margin: 0 0 22px;
}
.auth-notice,
.auth-error {
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 12.5px;
  margin-bottom: 16px;
  text-align: left;
  line-height: 1.4;
}
.auth-notice {
  background: color-mix(in srgb, var(--accent-cool) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-cool) 30%, transparent);
  color: var(--text);
}
.auth-error {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  color: color-mix(in srgb, var(--accent) 80%, var(--text));
}
/* Tab toggle between Sign in and Create account. Two short pills that
   share one rounded container, matching the rest of the app's pill
   language (filter-chips, status-pills). The "active" tab uses the
   accent gradient so it reads as the current state at a glance. */
.auth-tabs {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  margin: 0 auto 16px;
  background: color-mix(in srgb, var(--text-mute) 8%, transparent);
  border: 1px solid var(--border);
  border-radius: var(--btn-radius);
}
.auth-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 18px;
  border-radius: var(--btn-radius);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--text-soft);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.auth-tab:hover { color: var(--text); }
.auth-tab.is-active {
  background: linear-gradient(135deg, var(--accent), var(--accent-cool));
  color: #fff;
  box-shadow: var(--btn-shadow);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: left;
}
.auth-field { display: flex; flex-direction: column; gap: 5px; }
.auth-field-label {
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.auth-field input {
  width: 100%;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  height: 38px;
  padding: 0 13px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-solid);
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.auth-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.auth-field input[readonly] {
  background: color-mix(in srgb, var(--text-mute) 8%, transparent);
  color: var(--text-soft);
}
.auth-submit {
  width: 100%;
  margin-top: 6px;
  font-size: 14px;
  padding: 12px 18px;
}
.auth-footer {
  margin-top: 22px;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-style: italic;
}

/* ---------- Settings page ---------- */
.settings-page {
  max-width: 760px;
  margin: 0 auto;
  padding: 56px 36px 80px;
}
.settings-eyebrow {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
  margin-bottom: 8px;
}
.settings-title {
  font-size: 32px;
  font-weight: 300;
  letter-spacing: -0.5px;
  margin: 0 0 8px;
}
.settings-lede {
  font-size: 13px;
  color: var(--text-soft);
  margin: 0 0 28px;
  line-height: 1.55;
}
.settings-flash {
  margin: 0 0 18px;
}
.settings-card {
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  -webkit-backdrop-filter: blur(40px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.settings-card-head { margin-bottom: 16px; }
.settings-card-eyebrow {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
  margin-bottom: 4px;
}
.settings-card-title {
  font-size: 17px;
  font-weight: 600;
  margin: 0 0 6px;
  letter-spacing: -0.2px;
}
.settings-card-lede {
  font-size: 12.5px;
  color: var(--text-soft);
  margin: 0;
  line-height: 1.5;
}
.settings-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  align-items: end;
}
.settings-field { display: flex; flex-direction: column; gap: 5px; }
.settings-field-label {
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.settings-field input {
  width: 100%;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  height: 38px;
  padding: 0 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-solid);
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.settings-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.settings-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 10px;
  margin-top: 8px;
}
.settings-meta {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  padding-top: 6px;
}
.settings-meta-key {
  display: block;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
  margin-bottom: 3px;
}
.settings-meta-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
/* (Old .btn-danger override removed — the unified button family above
   defines .btn-danger as a real component, no !important needed.) */

/* (Sidebar bell badge removed — notifications live in the topbar now.) */


/* ---------- Notifications page ---------- */
.notif-page {
  max-width: 880px;
  margin: 0 auto;
  padding: 56px 36px 80px;
}
.notif-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.notif-eyebrow {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
  margin-bottom: 8px;
}
.notif-title {
  font-size: 32px;
  font-weight: 300;
  letter-spacing: -0.5px;
  margin: 0 0 6px;
}
.notif-lede {
  font-size: 13px;
  color: var(--text-soft);
  margin: 0;
}
.notif-empty {
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 16px;
  padding: 60px 28px;
  text-align: center;
  box-shadow: var(--shadow);
}
.notif-empty-title {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.2px;
  margin-bottom: 8px;
}
.notif-empty-body {
  font-size: 13px;
  color: var(--text-soft);
  margin: 0;
}
.notif-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.notif-item {
  position: relative;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  transition: border-color 0.15s, transform 0.15s;
}
.notif-item:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  transform: translateY(-1px);
}
.notif-item.is-unread {
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 4%, var(--surface-solid));
}
.notif-link {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 18px;
  cursor: pointer;
}
.notif-item:hover { transform: translateY(-1px); }
.notif-row-main {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  flex-wrap: wrap;
}
.notif-row-arrow { color: var(--text-mute); font-weight: 400; }
.notif-row-task { font-weight: 500; color: var(--text-soft); }
.notif-row-hint {
  margin-left: auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0;
  transition: opacity 0.14s ease;
  pointer-events: none;
}
.notif-link:hover .notif-row-hint { opacity: 1; }
.notif-row-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: var(--text-mute);
  flex-wrap: wrap;
}
.notif-status-pill {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  border: 1.5px solid;
  border-radius: 999px;
  padding: 2px 10px;
}
.notif-row-who { font-weight: 600; color: var(--text-soft); }
.notif-row-when { font-style: italic; }
.notif-mark-read {
  position: absolute;
  top: 10px;
  right: 12px;
  margin: 0;
}
/* notif-mark-read button now extends .btn-icon — see the SVG X in
   notifications.html. The legacy 8px dot was invisible and had no focus
   ring; the unified .btn-icon--close gives it a real affordance. */
.notif-mark-read button {
  width: 26px;
  height: 26px;
}

/* (Old sidebar-footer theme toggle removed — replaced by the icon-only
   button in the topbar. See .topbar-iconbtn below.) */

/* ---------- Main column ---------- */
.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.main-content {
  flex: 1;
  min-width: 0;
  /* No top padding — the topbar itself provides the gap above page
     content. Adding more here created a visible empty strip between
     the topbar and any page header (especially noticeable on the
     property page with its own .prop-header). */
  animation: rbp-fade-up 0.35s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---------- Topbar (notifications / theme / profile) ----------
   Horizontal padding uses the page-side spacing token so the topbar's
   search bar lines up with the page sections beneath it AND there's
   real breathing room between the sidebar's right edge and the
   topbar content (was 24px — too tight against the sidebar). */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px var(--page-pad-side);
  background: color-mix(in srgb, var(--bg) 75%, transparent);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-bottom: 1px solid var(--border);
  min-height: 60px;
}
.topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-right { display: flex; align-items: center; gap: 8px; }

/* Icon button (used for Notifications + Theme) */
.topbar-iconbtn {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.topbar-iconbtn:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--text);
}
.topbar-iconbtn.is-active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}
.topbar-iconbtn-icon { display: inline-flex; align-items: center; }
.topbar-badge {
  position: absolute;
  top: 5px;
  right: 5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border: 2px solid var(--bg);
}

/* Profile trigger + dropdown */
.profile { position: relative; }
.profile-trigger {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 5px 12px 5px 5px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-solid);
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  transition: border-color 0.15s, background 0.15s;
  max-width: 220px;
}
.profile-trigger:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
}
.profile.is-open .profile-trigger {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-solid));
}
.profile-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-cool));
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.profile-trigger-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  min-width: 0;
  line-height: 1.1;
}
.profile-trigger-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
}
.profile-trigger-email {
  font-size: 10.5px;
  color: var(--text-mute);
  max-width: 140px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.profile-trigger svg { color: var(--text-mute); transition: transform 0.18s ease; }
.profile.is-open .profile-trigger svg { transform: rotate(180deg); }

/* Dropdown panel */
.profile-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 240px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 20px 50px -20px rgba(0,0,0,0.25),
              0 0 0 1px rgba(0,0,0,0.02);
  padding: 6px;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top right;
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
  z-index: 50;
}
.profile.is-open .profile-dropdown {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.profile-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 12px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
.profile-card-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-cool));
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.profile-card-meta { min-width: 0; }
.profile-card-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.profile-card-email {
  font-size: 11.5px;
  color: var(--text-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 180px;
}
.profile-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-soft);
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  font-family: inherit;
  text-align: left;
  transition: background 0.12s, color 0.12s;
}
.profile-link:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); color: var(--text); }
.profile-link svg { color: var(--text-mute); }
.profile-link--danger { color: var(--accent); }
.profile-link--danger:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
}
.profile-link--danger svg { color: var(--accent); }
.profile-form { margin: 0; }

/* ---------- Topbar global search ---------- */
.global-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 380px;
  min-height: 36px;
  max-width: 100%;
  padding: 0 14px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-soft);
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s,
              width 0.18s ease;
}
.global-search:focus-within {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--border));
  outline: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
  outline-offset: 2px;
}
/* Magnifier — also the click target that expands the icon-only state. */
.global-search-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: text;
}
.global-search input {
  flex: 1;
  border: none;
  background: transparent;
  outline: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  padding: 0;
  min-width: 0;
}
.global-search input::placeholder { color: var(--text-mute); }

/* Icon-only collapsed state (mobile / narrow). JS toggles .is-expanded
   when the user clicks the magnifier. */
@media (max-width: 900px) {
  .global-search {
    width: 36px;
    padding: 0;
    justify-content: center;
    cursor: pointer;
  }
  .global-search-icon { cursor: pointer; }
  .global-search input,
  .global-search-results { display: none; }
  .global-search.is-expanded {
    width: 260px;
    padding: 0 14px;
    justify-content: flex-start;
    cursor: text;
  }
  .global-search.is-expanded input { display: block; }
  .global-search.is-expanded .global-search-results { display: block; }
}

.global-search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  width: 100%;
  max-height: 360px;
  overflow-y: auto;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 28px 64px -24px rgba(0,0,0,0.35),
              0 0 0 1px rgba(0,0,0,0.02);
  padding: 4px;
  z-index: 60;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease;
  /* Slim scrollbar — Firefox + WebKit. */
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--text-mute) 60%, transparent) transparent;
}
.global-search-results::-webkit-scrollbar { width: 6px; }
.global-search-results::-webkit-scrollbar-track { background: transparent; }
.global-search-results::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-mute) 50%, transparent);
  border-radius: 999px;
}
.global-search.is-open .global-search-results {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.global-search-count {
  display: block;
  padding: 8px 12px 4px;
  font-size: 9.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.global-search-row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.1s;
}
/* Right-arrow hover affordance intentionally removed — felt noisy. */
.global-search-row.is-active,
.global-search-row:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.global-search-row-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.2;
}
.global-search-row-meta {
  font-size: 11px;
  font-weight: 400;
  color: var(--text-mute);
  line-height: 1.2;
}
.global-search-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 20px 12px;
  font-size: 12px;
  color: var(--text-mute);
  text-align: center;
}
.global-search-empty::before {
  content: "";
  width: 22px;
  height: 22px;
  opacity: 0.45;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='7' cy='7' r='4.5' fill='none' stroke='black' stroke-width='1.5'/><path d='M10.5 10.5L14 14' stroke='black' stroke-width='1.5' stroke-linecap='round'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='7' cy='7' r='4.5' fill='none' stroke='black' stroke-width='1.5'/><path d='M10.5 10.5L14 14' stroke='black' stroke-width='1.5' stroke-linecap='round'/></svg>") no-repeat center / contain;
}

/* ---------- Recently-viewed chips (sidebar) ---------- */
.recent-section {
  padding: 10px 6px 6px;
  border-top: 1px solid var(--border);
  margin-top: 8px;
}
.recent-heading {
  font-size: 9.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
  margin: 0 4px 6px;
}
.recent-chips {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.recent-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 10px;
  font-size: 11.5px;
  color: var(--text-soft);
  transition: background 0.12s, color 0.12s;
}
.recent-chip:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--text);
}
.recent-chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
  opacity: 0.7;
}
.recent-chip-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
[data-sidebar="collapsed"] .recent-section { display: none; }

/* ---------- Notification popover (bell) ---------- */
.notif-popover { position: relative; }
.notif-popover-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 340px;
  max-width: 400px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 24px 60px -20px rgba(0,0,0,0.30),
              0 0 0 1px rgba(0,0,0,0.02);
  padding: 6px;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top right;
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
  z-index: 50;
}
.notif-popover.is-open .notif-popover-panel {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.notif-popover-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.notif-popover-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.1px;
}
.notif-popover-count {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--accent);
  text-transform: uppercase;
}
.notif-popover-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  max-height: 360px;
  overflow-y: auto;
}
.notif-popover-item { margin: 0; }
.notif-popover-link {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 9px;
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s;
}
.notif-popover-link:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.notif-popover-hint {
  position: absolute;
  right: 12px;
  bottom: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0;
  transition: opacity 0.14s ease;
  pointer-events: none;
}
.notif-popover-link:hover .notif-popover-hint { opacity: 1; }
.notif-popover-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-top: 5px;
  flex-shrink: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 10%, transparent);
}
.notif-popover-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.notif-popover-prop {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.notif-popover-task {
  font-size: 12px;
  color: var(--text-soft);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notif-popover-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  color: var(--text-mute);
  margin-top: 2px;
}
.notif-popover-status { font-weight: 700; }
.notif-popover-sep { opacity: 0.5; }
.notif-popover-empty {
  padding: 28px 16px;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-soft);
}
.notif-popover-footer {
  display: block;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
  font-size: 12px;
  color: var(--accent);
  font-weight: 600;
  text-align: center;
  border-radius: 0 0 10px 10px;
  transition: background 0.12s;
}
.notif-popover-footer:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* ---------- My Open Tasks widget (Home) ---------- */
.my-tasks {
  max-width: 1080px;
  margin: 0 auto 32px;
  padding: 22px 28px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 16px;
  box-shadow: var(--shadow);
}
.my-tasks-eyebrow {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.my-tasks-title {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.2px;
  margin: 0 0 4px;
}
.my-tasks-count {
  color: var(--accent);
  font-weight: 700;
}
.my-tasks-lede {
  font-size: 12.5px;
  color: var(--text-soft);
  margin: 0;
}
.my-tasks-list {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.my-tasks-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--accent) 3%, transparent);
}
.my-tasks-prop {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.my-tasks-phases {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.my-tasks-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ch, var(--accent)) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--ch, var(--accent)) 35%, transparent);
  color: var(--ch, var(--accent));
  font-size: 11.5px;
  font-weight: 700;
  transition: transform 0.12s ease, background 0.12s;
}
.my-tasks-chip:hover {
  background: color-mix(in srgb, var(--ch, var(--accent)) 22%, transparent);
  transform: translateY(-1px);
}
.my-tasks-chip-count {
  background: var(--ch, var(--accent));
  color: #fff;
  font-size: 10.5px;
  border-radius: 999px;
  padding: 1px 7px;
  font-weight: 800;
}

/* ---------- Filter chips (property page) ---------- */
/* Slim, inline-with-phase-header chips. The .phase-head's flex layout pushes
   the .filter-chips group to the right end of the row. */
.filter-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 0 auto;     /* right-align inside .phase-head */
  padding: 2px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: none;
}
.filter-chip {
  height: 28px;
  padding: 0 12px;
  line-height: 1;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  box-shadow: none;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.filter-chip:hover { color: var(--text); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.filter-chip.is-active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  box-shadow: none;
}
.task-row.is-hidden-by-filter { display: none !important; }

/* ---------- Task select checkbox + bulk bar ---------- */
.task-select {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  margin-right: 2px;
}
.task-checkbox {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.task-checkbox-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 5px;
  border: 1.5px solid color-mix(in srgb, var(--text-mute) 40%, transparent);
  background: var(--surface-solid);
  transition: background 0.12s, border-color 0.12s;
}
.task-checkbox-mark::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--accent);
  transform: scale(0);
  transition: transform 0.12s;
}
.task-checkbox:checked ~ .task-checkbox-mark {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface-solid));
}
.task-checkbox:checked ~ .task-checkbox-mark::after { transform: scale(1); }
.task-checkbox:focus-visible ~ .task-checkbox-mark {
  outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
  outline-offset: 2px;
}

/* Screen-reader-only utility (visible label removed from bulk-bar select). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Floating pill toolbar — anchored to the bottom of the viewport, centered.
   Opens by toggling .is-visible (opacity + translateY) for a smooth fade. */
.bulk-bar {
  position: fixed;
  bottom: 18px;
  left: 50%;
  transform: translate(-50%, 8px);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  max-width: 520px;
  padding: 8px 12px;
  background: color-mix(in srgb, var(--surface-solid) 82%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 24px 56px -18px rgba(0,0,0,0.45),
              0 2px 6px -2px rgba(0,0,0,0.18);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms cubic-bezier(0.4, 0, 0.2, 1),
              transform 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
.bulk-bar.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
/* Small accent-filled count chip — replaces the "N selected" label. */
.bulk-bar-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1;
}
.bulk-bar-status {
  display: inline-flex;
  align-items: center;
}
.bulk-bar-status select {
  height: 32px;
  border: 1px solid var(--border);
  background: var(--surface-solid);
  color: var(--text);
  padding: 4px 10px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  outline: none;
  cursor: pointer;
}
.bulk-bar-status select:focus-visible {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent);
}
.bulk-bar-apply {
  padding: 6px 16px;
  font-size: 12.5px;
  border-radius: 999px;
}
/* bulk-bar-clear extends .btn-icon.btn-icon--close.btn-icon--ghost — see
   property.html. Only the size override is needed to fit the pill. */
.bulk-bar-clear {
  width: 28px;
  height: 28px;
}

/* ---------- Pin / favorite button on property cards ---------- */
.card-pin {
  position: absolute;
  top: 12px;
  right: 50px;  /* sits next to .card-delete */
  z-index: 3;
  width: 28px;
  height: 28px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-mute);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s, transform 0.15s;
}
.card-pin:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.card-pin.is-pinned { color: var(--yellow); }
.card-pin.is-pinned:hover { color: color-mix(in srgb, var(--yellow) 80%, var(--text)); }
.card-pin-mark {
  color: var(--yellow);
  margin-right: 4px;
  font-size: 13px;
}

/* ---------- @Mention autocomplete popup ---------- */
.mention-popup {
  position: absolute;
  min-width: 220px;
  max-width: 320px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 36px -14px rgba(0,0,0,0.30);
  padding: 4px;
  z-index: 200;
}
.mention-row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border-radius: 10px;
  font-size: 12.5px;
  cursor: pointer;
  color: var(--text);
}
.mention-row.is-active,
.mention-row:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.mention-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-cool));
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}
.mention-display { font-weight: 600; }
.mention-email { font-size: 11px; color: var(--text-mute); margin-left: auto; }

/* ---------- Focused task (arrived via notification) ---------- */
.task-row.is-focused {
  animation: rbp-task-pulse 1.6s ease-out 2;
  border-color: var(--accent) !important;
  position: relative;
  z-index: 1;
}
@keyframes rbp-task-pulse {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 22%, transparent); }
}

/* ---------- Cmd+K trigger (left side of topbar) ---------- */
.cmdk-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px 7px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface-solid);
  color: var(--text-mute);
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.cmdk-trigger:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  color: var(--text);
}
.cmdk-trigger-label { min-width: 110px; text-align: left; }
.cmdk-trigger-kbd {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 6px;
  color: var(--text-mute);
}

/* ---------- Cmd+K palette (modal) ---------- */
.cmdk {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 14vh;
}
.cmdk.is-open { display: flex; animation: cmdk-fade 0.16s ease both; }
@keyframes cmdk-fade { from { opacity: 0; } to { opacity: 1; } }
.cmdk-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--bg) 60%, transparent);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
}
.cmdk-panel {
  position: relative;
  width: min(560px, 92vw);
  max-height: 60vh;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 30px 80px -30px rgba(0,0,0,0.45),
              0 0 0 1px rgba(255,255,255,0.02);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: cmdk-scale 0.18s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes cmdk-scale {
  from { opacity: 0; transform: translateY(-8px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.cmdk-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.cmdk-search-icon { color: var(--text-mute); flex-shrink: 0; }
.cmdk-input-row input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 15px;
  color: var(--text);
}
.cmdk-input-row input::placeholder { color: var(--text-mute); }
.cmdk-esc {
  font-family: ui-monospace, monospace;
  font-size: 10.5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 7px;
  color: var(--text-mute);
}
.cmdk-results { flex: 1; overflow-y: auto; padding: 6px; }
.cmdk-group {
  padding: 10px 12px 6px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
}
.cmdk-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  color: var(--text);
  cursor: pointer;
}
.cmdk-item.is-active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--text);
}
.cmdk-item-label { font-size: 14px; font-weight: 500; }
.cmdk-item-hint {
  font-size: 12px;
  color: var(--text-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.cmdk-empty {
  padding: 30px 16px;
  text-align: center;
  color: var(--text-mute);
  font-size: 13px;
}
.cmdk-footer {
  display: flex;
  gap: 18px;
  justify-content: flex-end;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-mute);
}
.cmdk-footer kbd {
  font-family: ui-monospace, monospace;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 5px;
  font-size: 10px;
  margin-right: 4px;
  color: var(--text-soft);
}

/* ---------- Scroll-to-top FAB ---------- */
.scrolltop {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-solid);
  color: var(--text-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, color 0.15s, border-color 0.15s;
  box-shadow: var(--shadow-lg);
  z-index: 150;
}
.scrolltop.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
.scrolltop:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

/* ---------- Dark-mode-specific refinements ---------- */
/* These rules layer on top of the base CSS to give dark mode the lifted,
   premium feel that flat surfaces alone don't convey. Light mode stays
   untouched. */
[data-theme="dark"] body { color-scheme: dark; }

/* Subtle white inner border on cards so they feel lifted above the bg. */
[data-theme="dark"] .card,
[data-theme="dark"] .stat-strip,
[data-theme="dark"] .empty-state,
[data-theme="dark"] .launch-card,
[data-theme="dark"] .launch-fieldset,
[data-theme="dark"] .settings-card,
[data-theme="dark"] .notif-item,
[data-theme="dark"] .auth-card,
[data-theme="dark"] .owner-progress,
[data-theme="dark"] .prop-info {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset,
              0 16px 40px -22px rgba(0, 0, 0, 0.5);
}

/* (Sidebar logo removed — used to live here. Brand identity now sits
   on the Home hero + login screen. No dark-mode logo styling needed. */

/* Topbar: a hint of accent at the very top so dark mode has a horizon line. */
[data-theme="dark"] .topbar {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 6%, var(--bg)) 0%,
    var(--bg) 80%);
}

/* Card hover glow in dark mode. */
[data-theme="dark"] .card:hover {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset,
              0 20px 50px -22px color-mix(in srgb, var(--accent) 40%, rgba(0,0,0,0.6));
}

/* Soften the hero coral text in dark mode — was over-saturated before. */
[data-theme="dark"] .hero-accent { color: var(--accent-soft); }

/* ---------- Launch form: completion progress + sticky submit ---------- */
.launch-progress {
  position: sticky;
  top: 56px;           /* sits under the topbar */
  z-index: 10;
  margin-bottom: 22px;
  padding: 10px 18px;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 999px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12.5px;
}
.launch-progress-bar {
  flex: 1;
  height: 6px;
  background: var(--progress-track);
  border-radius: 999px;
  overflow: hidden;
}
.launch-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-cool));
  border-radius: 999px;
  transition: width 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.launch-progress-count {
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.launch-progress-count.is-complete { color: var(--jay); }
.launch-progress-label { color: var(--text-soft); }

/* ---------- Keyboard shortcuts overlay (?) ---------- */
.shortcuts {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.shortcuts.is-open { display: flex; animation: cmdk-fade 0.16s ease both; }
.shortcuts-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.shortcuts-panel {
  position: relative;
  width: min(440px, 92vw);
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 30px 80px -30px rgba(0,0,0,0.4);
  animation: cmdk-scale 0.18s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.shortcuts-title {
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 4px;
}
.shortcuts-lede {
  font-size: 12.5px;
  color: var(--text-soft);
  margin: 0 0 18px;
}
.shortcuts-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.shortcuts-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--surface);
  font-size: 13px;
}
.shortcuts-list kbd {
  font-family: ui-monospace, monospace;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 7px;
  font-size: 11px;
  color: var(--text-soft);
  margin-left: 4px;
}

/* ---------- Supabase error banner ---------- */
.sb-error-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 880px;
  margin: 18px auto 0;
  padding: 12px 16px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  color: color-mix(in srgb, var(--accent) 70%, var(--text));
  font-size: 13px;
  line-height: 1.45;
}
.sb-error-banner svg { flex-shrink: 0; margin-top: 1px; }
.sb-error-detail {
  display: block;
  font-size: 11.5px;
  color: var(--text-mute);
  font-family: ui-monospace, monospace;
  margin-top: 4px;
}

/* Hero (home) — used to be a 2-column layout (logo + copy). With the
   logo removed it's a single text column. .hero--compact widens the
   text up to a comfortable reading length and lifts the title since
   there's nothing competing with it visually. */
.hero {
  max-width: 880px;
  margin: 56px auto 40px;
  padding: 0 36px;
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}
.hero--compact {
  margin-top: 64px;
  margin-bottom: 32px;
}
.hero-copy { flex: 1; min-width: 280px; max-width: 720px; }
.hero--compact .hero-title { font-size: 46px; }
.hero-logo {
  position: relative;
  width: 160px;
  height: 160px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero-logo-halo {
  position: absolute;
  inset: -20px;
  border-radius: 40%;
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--accent-soft) 50%, transparent) 0%, transparent 70%);
  filter: blur(12px);
  pointer-events: none;
  animation: rbp-halo 6s ease-in-out infinite;
}
.hero-logo-img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 1;
  /* Dark mode: lift the logo slightly so the white background reads cleanly. */
  filter: drop-shadow(0 6px 18px rgba(0,0,0,0.10));
}
[data-theme="dark"] .hero-logo-img {
  filter: drop-shadow(0 6px 22px rgba(0,0,0,0.55));
}
@keyframes rbp-halo {
  0%, 100% { opacity: 0.6; transform: scale(1); }
  50%      { opacity: 0.85; transform: scale(1.04); }
}
.hero-eyebrow {
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-mute);
  margin-bottom: 14px;
}
.hero-title {
  font-size: 42px;
  font-weight: 300;
  letter-spacing: -0.5px;
  line-height: 1.1;
  margin: 0 0 14px;
}
.hero-accent { color: var(--accent); font-style: italic; font-weight: 400; }
.hero-lede {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 480px;
  margin: 0 0 26px;
}
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* ------------------------------------------------------------------ *
 * Button family — unified geometry, transitions, focus, and hover    *
 * across primary / ghost / secondary / danger. Token-driven so any   *
 * future tweak lands in one place.                                   *
 * ------------------------------------------------------------------ */
.btn-primary,
.btn-ghost,
.btn-secondary,
.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: var(--btn-radius);
  padding: var(--btn-pad-y) var(--btn-pad-x);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  line-height: 1;
  transition: transform 0.15s ease, box-shadow 0.15s ease,
              background 0.15s ease, border-color 0.15s ease, filter 0.15s ease;
  text-decoration: none;
  white-space: nowrap;
}

.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-cool));
  color: #fff;
  border: 1px solid transparent;
  box-shadow: var(--btn-shadow);
}
.btn-primary:hover { transform: translateY(-1px); filter: brightness(1.05); }
.btn-primary:active { transform: translateY(0); filter: brightness(0.98); }

.btn-ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}
.btn-ghost:hover {
  background: color-mix(in srgb, var(--accent) var(--tint-hover), transparent);
  border-color: color-mix(in srgb, var(--accent) var(--tint-border), var(--border));
}

.btn-secondary {
  background: var(--surface-solid);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.btn-secondary:hover {
  border-color: color-mix(in srgb, var(--accent) var(--tint-border), var(--border));
  transform: translateY(-1px);
}

.btn-danger {
  background: transparent;
  color: var(--error);
  border: 1px solid color-mix(in srgb, var(--error) 40%, transparent);
}
.btn-danger:hover {
  background: color-mix(in srgb, var(--error) var(--tint-bg), transparent);
}

.btn-primary:disabled,
.btn-ghost:disabled,
.btn-secondary:disabled,
.btn-danger:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  filter: none;
}

/* ------------------------------------------------------------------ *
 * Icon button family — used wherever we render a circular/rounded   *
 * action without a text label. The `--close` variant is the         *
 * canonical X (modals, banners, bulk-bar, notification dismiss).     *
 * ------------------------------------------------------------------ */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-btn-size);
  height: var(--icon-btn-size);
  border-radius: var(--icon-btn-radius);
  border: 1px solid var(--border);
  background: var(--surface-solid);
  color: var(--text-soft);
  cursor: pointer;
  padding: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
}
.btn-icon:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--accent) var(--tint-hover), var(--surface-solid));
  border-color: color-mix(in srgb, var(--accent) var(--tint-border), var(--border));
}
.btn-icon:active { transform: translateY(0); }

.btn-icon--close { color: var(--text-mute); }
.btn-icon--close:hover { color: var(--error); }

.btn-icon--ghost {
  background: transparent;
  border-color: transparent;
}
.btn-icon--ghost:hover {
  background: color-mix(in srgb, var(--accent) var(--tint-hover), transparent);
  border-color: transparent;
}

/* Stat strip */
.stat-strip {
  max-width: 880px;
  margin: 0 auto 60px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.stat {
  padding: 18px 22px;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.stat.last { border-right: none; }
.stat-label {
  font-size: 10px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
}
.stat-value {
  font-size: 26px;
  font-weight: 300;
  letter-spacing: -0.8px;
  color: var(--text);
}
.stat-value.accent { color: var(--accent); font-weight: 400; }

/* Section + portfolio grid */
.section { max-width: 1080px; margin: 0 auto; padding: 0 36px; }
.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 22px;
}
.section-title {
  font-size: 18px;
  font-weight: 400;
  letter-spacing: -0.2px;
  margin: 0;
}
.section-meta {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
}

.empty-state {
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  border: 1px dashed var(--border);
  border-radius: 16px;
  padding: 60px 28px;
  text-align: center;
  box-shadow: var(--shadow-lg);
}
.empty-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 8px;
  letter-spacing: -0.2px;
}
.empty-body {
  font-size: 13px;
  color: var(--text-soft);
  margin: 0 0 22px;
}
.inline-create {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  max-width: 100%;
}
.inline-create input {
  border: 1.5px solid var(--border);
  border-radius: 999px;
  padding: 10px 16px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  background: var(--surface-solid);
  /* width: auto + max-width:100% lets the input shrink with the form
     instead of holding a 220px floor that pushed the "+ New Property"
     button off-screen at narrow viewports. */
  width: 220px;
  max-width: 100%;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
  /* Align the grid with the toolbar above (.page-head + .filter-bar)
     by sharing the same max-width + auto margins + page padding. Inside
     `.section` (Home), the parent already constrains width — these
     repeats are harmless there. */
  max-width: var(--page-max-width);
  margin: 0 auto;
  padding: 0 var(--page-pad-side);
}
/* When .card-grid sits inside .section, .section already handles
   max-width + padding; clear them here so they don't double-stack. */
.section .card-grid {
  max-width: none;
  padding: 0;
  margin: 0;
}
.card {
  position: relative;
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 130px;
  box-shadow: var(--shadow-lg);
  transition: border-color 0.15s, transform 0.15s;
}
.card:hover { border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); transform: translateY(-2px); }
.card-with-delete { padding: 0; }
.card-with-delete .card-link {
  display: block;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 130px;
}
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
}
.card-name {
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-sub {
  font-size: 12px;
  color: var(--text-soft);
  margin-top: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-sub-soft {
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.badge-done {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--jay);
  background: color-mix(in srgb, var(--jay) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--jay) 30%, transparent);
  border-radius: 999px;
  padding: 3px 9px;
  flex-shrink: 0;
}
.card-delete {
  position: absolute;
  top: 12px;
  right: 12px;
  margin: 0;
}
/* card-delete also uses .btn-icon.btn-icon--close — see properties.html.
   Slight opacity reveal on hover is the only card-specific tweak. */
.card-delete button {
  opacity: 0.55;
}
.card-delete button:hover { opacity: 1; }

/* Progress bar */
.card-progress { display: flex; flex-direction: column; gap: 6px; }
.progress-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.progress-label {
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
}
.progress-value {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.2px;
}
.progress-value.is-done { color: var(--jay); }
.progress-bar {
  height: 3px;
  background: var(--progress-track);
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar.small { height: 6px; }
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-cool));
  transition: width 0.6s cubic-bezier(0.16,1,0.3,1);
}
.progress-fill.is-done { background: var(--jay); }

/* Page heads — uses the same page-max-width token as .content so the
   toolbar lines up vertically with the page sections below it (was an
   oddball 1180px; now 1080px). Padding token keeps left/right edges
   consistent with .topbar. flex-wrap kicks in cleanly at narrower
   widths because the inputs inside no longer hold a fixed min-width. */
.page-head {
  max-width: var(--page-max-width);
  margin: 56px auto 8px;
  padding: 0 var(--page-pad-side);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.page-eyebrow {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
  margin-bottom: 8px;
}
.page-title {
  font-size: 32px;
  font-weight: 300;
  letter-spacing: -0.5px;
  margin: 0;
}
.page-meta {
  font-size: 13px;
  color: var(--text-soft);
}

/* Filter bar — same width + padding tokens as .page-head and .content.
   `min-width: 0` on the search input lets flex actually shrink it so
   neighboring buttons aren't pushed off the viewport at narrow widths
   (without this, `flex: 1 1 280px` plants a 280px floor even when there
   isn't room). At small viewports the row wraps cleanly. */
.filter-bar {
  max-width: var(--page-max-width);
  margin: 18px auto 28px;
  padding: 0 var(--page-pad-side);
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}
.filter-bar .search {
  flex: 1 1 220px;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 12px 18px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  box-shadow: var(--shadow);
}
.filter-bar select {
  flex: 0 0 auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 12px 20px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  box-shadow: var(--shadow);
}

/* Back-to-Properties link in prop-header. Sits above the eyebrow as
   a small subdued chrome row — always present, never the focus, but
   one-click reachable so the user isn't trapped on the detail page. */
.prop-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-small);
  font-weight: var(--fw-semi);
  color: var(--text-muted);
  margin-bottom: 6px;
  letter-spacing: 0.2px;
  transition: color 0.15s;
}
.prop-back:hover { color: var(--text-primary); }
.prop-back svg { flex-shrink: 0; }

/* Count chip on tabs ("Assigned to Me [12]") and phase headers
   ("Phase 3 [86]"). Small accent-tinted pill, tabular-nums so it doesn't
   wobble as counts update. */
.tab-count,
.phase-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  margin-left: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--action-primary) 14%, transparent);
  color: var(--action-primary);
  font-size: 10px;
  font-weight: var(--fw-bold);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.tab.is-active .tab-count {
  background: var(--action-primary);
  color: var(--text-inverse);
}

/* Property detail header — was a full-width tinted bar with the inner
   content centered in a 1060px column, which left visible empty "tint
   bars" on either side of the content. Now: background transparent, the
   element lives at the same max-width + page padding as everything
   else, so it reads as a unified page header instead of a separate
   tinted region.  */
.prop-header {
  background: transparent;
  border-bottom: 1px solid var(--border-subtle);
}
.prop-header-inner {
  max-width: var(--page-max-width);
  margin: 0 auto;
  padding: 18px var(--page-pad-side) 14px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
}
.prop-eyebrow {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.prop-name {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  margin-top: 2px;
}
.prop-owner {
  font-size: 12px;
  color: var(--text-soft);
  margin-top: 1px;
}
.prop-progress-track {
  max-width: var(--page-max-width);
  margin: 0 auto;
  height: 4px;
  background: var(--progress-track);
}
.prop-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-cool));
  transition: width 0.6s cubic-bezier(0.16,1,0.3,1);
}

#header-progress { text-align: right; }
.prog-eyebrow {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
  margin-bottom: 3px;
}
.prog-pct {
  font-size: 28px;
  font-weight: 700;
  color: var(--elissa);
  line-height: 1;
  margin-bottom: 4px;
}
.prog-pct.is-done { color: var(--jay); }
.prog-pct-suffix {
  font-size: 12px;
  color: var(--text-mute);
  margin-left: 5px;
  font-weight: 400;
}
.prog-summary {
  font-size: 11px;
  color: var(--text-mute);
  font-weight: 600;
}
.prog-summary.is-done { color: var(--jay); font-weight: 700; }
.muted { color: var(--text-mute); }

/* Tabs — same max-width as the prop-header so they line up directly
   underneath. Background transparent so the empty space on either side
   blends with the page rather than reading as separate strips. */
.tabs {
  background: transparent;
  border-bottom: 1px solid var(--border-subtle);
  display: flex;
  overflow-x: auto;
  padding: 0 var(--page-pad-side);
  max-width: var(--page-max-width);
  margin: 0 auto;
}
.tab {
  padding: 11px 14px;
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-mute);
  border-bottom: 3px solid transparent;
  white-space: nowrap;
  cursor: pointer;
}
.tab.is-active {
  color: var(--kaye);
  border-bottom-color: var(--kaye);
}
.tab-disabled { color: color-mix(in srgb, var(--text-mute) 60%, transparent); cursor: not-allowed; }

/* Content — uses the same page padding tokens as Settings / Launch /
   Notifications so the Property detail page no longer feels squeezed
   against the viewport edges. */
.content {
  max-width: var(--page-max-width);
  margin: 0 auto;
  padding: 32px var(--page-pad-side) var(--page-pad-bottom);
}

/* Property info card */
.prop-info {
  background: var(--info-bg);
  border: 1px solid var(--info-border);
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 20px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
/* --kaye (purple) tints info / admin context — keep eyebrow + label tokens. */
/* Accent variant — tinted by the active phase color (set inline via
   --phase-accent so the property info card shifts color as work progresses). */
.prop-info--accent {
  border-color: color-mix(in srgb, var(--phase-accent) 45%, var(--info-border));
  border-left: 4px solid var(--phase-accent);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--phase-accent) 22%, transparent) inset,
              0 10px 32px -16px color-mix(in srgb, var(--phase-accent) 35%, transparent);
}
.phase-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-weight: 700;
  border: 1px solid;
  border-radius: 999px;
  padding: 2px 8px;
  margin-left: 8px;
  vertical-align: middle;
}
.prop-info-eyebrow {
  font-size: 11px;
  font-weight: 700;
  color: var(--kaye);
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-bottom: 14px;
}
.prop-info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 12px;
}
.prop-field { display: block; }
.prop-field.full { display: block; margin-top: 12px; }
.prop-field-label {
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--kaye);
  font-weight: 700;
  display: block;
  margin-bottom: 3px;
}
.prop-input {
  width: 100%;
  border: 1.5px solid color-mix(in srgb, var(--kaye) 27%, transparent);
  border-radius: 10px;
  height: 38px;
  padding: 0 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-solid);
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.prop-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
textarea.prop-input { height: auto; padding: 10px 12px; }
textarea.prop-input { resize: vertical; line-height: 1.55; }

/* Owner progress panel */
.owner-progress {
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 20px;
  box-shadow: var(--shadow);
}
/* secondary/inline card padding (16 18) */
.owner-progress-head {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 10px;
}
.owner-progress-eyebrow {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.owner-progress-meta { font-size: 10px; color: var(--text-mute); }
.owner-progress-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
}
.owner-card {
  background: color-mix(in srgb, var(--owner-color) 5%, var(--surface-solid));
  border: 1.5px solid color-mix(in srgb, var(--owner-color) 20%, transparent);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.owner-card-head { display: flex; align-items: center; justify-content: space-between; }
.owner-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--owner-color);
  flex-shrink: 0;
  display: inline-block;
  margin-right: 6px;
}
.owner-name {
  font-size: 12px;
  font-weight: 700;
  color: var(--owner-color);
  flex: 1;
}
.owner-pct {
  font-size: 11px;
  font-weight: 700;
  color: var(--owner-color);
}
.owner-stats {
  font-size: 10px;
  color: var(--text-mute);
  display: flex;
  justify-content: space-between;
}
.owner-left { color: var(--owner-color); font-weight: 600; }

/* Phase section */
.phase-section { margin-bottom: 32px; }
.phase-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.phase-bullet {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
  box-shadow: 0 3px 10px color-mix(in srgb, var(--kaye) 27%, transparent);
}
.phase-title {
  /* Aligned with .settings-card-title / .launch-card-title (17px/600) so
     all card-level titles read as one type scale. */
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  margin: 0;
}

/* Task list / rows */
.task-list { display: flex; flex-direction: column; gap: 4px; }
.task-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1.5px solid;
  border-radius: 10px;
  background: var(--surface-solid);
  transition: all 0.13s;
}
.task-row.is-sub { padding: 5px 8px; }
.task-row.is-archived { opacity: 0.55; font-style: italic; }
.task-row.is-complete .task-label { color: var(--jay); text-decoration: line-through; }
.task-label {
  flex: 1;
  font-size: 13px;
  color: var(--text);
  line-height: 1.4;
  word-break: break-word;
}
.task-row.is-sub .task-label { font-size: 12px; }
.task-row.is-archived .task-label { color: var(--text-mute); }
.owner-badge {
  font-size: 9px;
  padding: 1px 7px;
  border-radius: 999px;
  flex-shrink: 0;
  font-weight: 700;
  letter-spacing: 0.5px;
  border: 1px solid;
}
.status-form { margin: 0; flex-shrink: 0; }
.status-pill {
  font-size: 10px;
  padding: 4px 24px 4px 10px;
  border-radius: 12px;
  border: 1.5px solid;
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 12 8'><path d='M1 2l5 5 5-5' fill='none' stroke='%23555' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
}

.task-subs {
  margin-left: 24px;
  padding-left: 12px;
  border-left: 2px solid color-mix(in srgb, var(--kaye) 27%, transparent);
  margin-top: 2px;
  margin-bottom: 8px;
}
.task-subs-label {
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--kaye);
  font-weight: 700;
  margin: 4px 0 6px;
}

/* Skeleton hint */
.skeleton-note {
  background: var(--note-bg);
  border: 1px solid var(--note-border);
  border-left: 4px solid var(--yellow);
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 12px;
  color: var(--text);
  line-height: 1.5;
  margin-top: 24px;
}

/* Footer */
.footer-tag {
  text-align: center;
  margin-top: 80px;
  padding-bottom: 40px;
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-style: italic;
  font-weight: 500;
}

/* ---------- Polish: entry animations, toast, focus, launch page ---------- */

/* Animations — match the React app's rbp-fade-up cubic-bezier. */
@keyframes rbp-fade-up {
  0%   { opacity: 0; transform: translateY(12px); }
  100% { opacity: 1; transform: none; }
}
.rbp-fade-up {
  animation: rbp-fade-up 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Main content gets a subtle enter on page load so navigation feels alive. */
.main > * { animation: rbp-fade-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
.main > * + * { animation-delay: 60ms; }
.main > * + * + * { animation-delay: 120ms; }
.main > * + * + * + * { animation-delay: 180ms; }

/* Toast (auto-save / status confirmation). */
.toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-solid);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 9px 16px 9px 12px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.18);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
  z-index: 200;
}
.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.toast-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--jay);
}

/* Smoother focus rings — accessible without being shouty.
   Matches the input focus spec: 3px accent-18% box-shadow, no outline offset. */
:where(input, textarea, select, button, a):focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
  outline-offset: 0;
  border-radius: 10px;
}

/* Smoother card / link hover (used on Home + Properties cards). */
.card, .nav-item, .btn-primary, .btn-ghost, .theme-toggle, .sidebar-toggle {
  will-change: transform;
}
.btn-primary { transition: transform 0.18s ease, box-shadow 0.18s ease, filter 0.18s ease; }
.btn-primary:hover { transform: translateY(-1px); filter: brightness(1.05); }
.btn-primary:active { transform: translateY(0); filter: brightness(0.98); }

/* ---------- Launch form page ---------- */
.launch-page {
  max-width: 1000px;
  margin: 0 auto;
  padding: 56px 36px 80px;
}
.launch-header { margin-bottom: 22px; }
.launch-eyebrow {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
  margin-bottom: 8px;
}
.launch-title {
  font-size: 32px;
  font-weight: 300;
  letter-spacing: -0.5px;
  margin: 0 0 8px;
}
.launch-lede {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 620px;
  margin: 0;
}

/* Flash banners */
.launch-flash {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  border-radius: 12px;
  padding: 14px 18px;
  margin-bottom: 18px;
  font-size: 13.5px;
  line-height: 1.45;
}
.launch-flash svg { flex-shrink: 0; margin-top: 1px; }
.launch-flash code {
  background: color-mix(in srgb, currentColor 12%, transparent);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 11.5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.launch-flash--success {
  background: color-mix(in srgb, var(--jay) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--jay) 40%, transparent);
  color: color-mix(in srgb, var(--jay) 78%, var(--text));
}
.launch-flash--error {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  color: color-mix(in srgb, var(--accent) 78%, var(--text));
}

/* Form layout */
.launch-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.launch-card {
  background: var(--surface);
  backdrop-filter: blur(40px) saturate(140%);
  -webkit-backdrop-filter: blur(40px) saturate(140%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px 24px;
  box-shadow: var(--shadow);
}
.launch-card-head { margin-bottom: 18px; }
.launch-card-eyebrow {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
  margin-bottom: 4px;
}
.launch-card-title {
  font-size: 17px;
  font-weight: 600;
  margin: 0 0 6px;
  letter-spacing: -0.2px;
}
.launch-card-lede {
  font-size: 12.5px;
  color: var(--text-soft);
  line-height: 1.5;
  margin: 0;
}

.launch-grid { display: grid; gap: 14px; }
.launch-grid--one { grid-template-columns: 1fr; }
.launch-grid--two { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 18px; }
.launch-grid--four { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

/* Text / number inputs */
.launch-field { display: flex; flex-direction: column; gap: 6px; }
.launch-field--full { grid-column: 1 / -1; }
.launch-field-label {
  font-size: 10.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.launch-field input,
.launch-field select,
.launch-field textarea {
  width: 100%;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  height: 38px;
  padding: 0 14px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-solid);
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.launch-field textarea { height: auto; padding: 10px 14px; }
.launch-field select {
  /* Native chevron + match input height (line-height carries the cap). */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4l4 4 4-4' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
  padding-right: 34px;
  cursor: pointer;
}
.launch-field textarea {
  resize: vertical;
  min-height: 76px;
  line-height: 1.5;
  height: auto;
}
.launch-field input:focus,
.launch-field select:focus,
.launch-field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.req { color: var(--accent); margin-left: 2px; }

/* Property Launch (final stage) card — green left rail + green eyebrow.
   --jay is reserved for completion / launch, which is exactly this card. */
.launch-card--final {
  border-left: 4px solid var(--jay);
}
.launch-card-eyebrow--final { color: var(--jay); }

/* Inline-wrap radios for short option sets (e.g. Ready / Pending QC / Blocked). */
.launch-radios--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 6px 10px;
}
.launch-radios--inline .launch-radio {
  flex: 0 1 auto;
  min-width: 140px;
}

/* Launch checklist + confirm checkboxes. Built off the radio look so the
   final card reads as a single coherent component. */
.launch-checks {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.launch-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 11px;
  border-radius: 9px;
  cursor: pointer;
  border: 1.5px solid transparent;
  background: transparent;
  user-select: none;
  transition: background 0.12s, border-color 0.12s;
}
.launch-check:hover {
  background: color-mix(in srgb, var(--jay) 8%, transparent);
}
.launch-check.is-checked {
  background: color-mix(in srgb, var(--jay) 12%, transparent);
  border-color: color-mix(in srgb, var(--jay) 45%, transparent);
}
.launch-check input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.launch-check-box {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  border-radius: 5px;
  border: 1.8px solid var(--border);
  background: var(--surface-solid);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: border-color 0.12s, background 0.12s;
}
.launch-check-box::after {
  content: "";
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--jay);
  border-bottom: 2px solid var(--jay);
  transform: rotate(-45deg) translate(1px, -1px) scale(0);
  transition: transform 0.12s ease;
}
.launch-check.is-checked .launch-check-box {
  border-color: var(--jay);
  background: color-mix(in srgb, var(--jay) 14%, var(--surface-solid));
}
.launch-check.is-checked .launch-check-box::after {
  transform: rotate(-45deg) translate(1px, -1px) scale(1);
}
.launch-check input:focus-visible + .launch-check-box {
  outline: 2px solid color-mix(in srgb, var(--jay) 60%, transparent);
  outline-offset: 3px;
}
.launch-check-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
}
.launch-confirm-row {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.launch-check--confirm .launch-check-text { font-weight: 600; }

/* Form completion progress */
.launch-progress {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 18px;
  font-size: 12px;
}
.launch-progress-label {
  font-size: 10.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.launch-progress-bar {
  flex: 1;
  height: 6px;
  background: var(--progress-track);
  border-radius: 999px;
  overflow: hidden;
}
.launch-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-cool));
  transition: width 0.5s cubic-bezier(0.16,1,0.3,1);
}
.launch-progress-count { color: var(--text-soft); white-space: nowrap; }
#launch-progress-filled { color: var(--text); font-weight: 700; }
.launch-form.is-complete .launch-progress-fill { background: var(--jay); }

/* Radio fieldset — each channel gets its own accent stripe + chip for
   instant visual recognition. --ch-color is set inline per fieldset. */
.launch-fieldset {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  margin: 0;
  background: var(--surface-solid);
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s;
  overflow: hidden;
}
.launch-fieldset::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--ch-color, var(--accent));
  opacity: 0.7;
}
.launch-fieldset:hover {
  border-color: color-mix(in srgb, var(--ch-color, var(--accent)) 35%, var(--border));
  box-shadow: 0 6px 20px -10px color-mix(in srgb, var(--ch-color, var(--accent)) 35%, transparent);
}
.launch-fieldset-legend {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  margin: 0 0 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.1px;
}
.launch-fieldset-legend::before {
  content: attr(data-letter);
  width: 22px;
  height: 22px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--ch-color, var(--accent)) 18%, transparent);
  color: var(--ch-color, var(--accent));
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.launch-radios {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.launch-radio {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 11px;
  border-radius: 9px;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition: background 0.12s, border-color 0.12s, transform 0.12s;
  background: transparent;
  user-select: none;
}
.launch-radio:hover {
  background: color-mix(in srgb, var(--ch-color, var(--accent)) 8%, transparent);
}
.launch-radio.is-checked {
  background: color-mix(in srgb, var(--ch-color, var(--accent)) 12%, transparent);
  border-color: color-mix(in srgb, var(--ch-color, var(--accent)) 45%, transparent);
}
.launch-radio input {
  /* Hide the native radio — we draw our own dot. */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.launch-radio-dot {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  border-radius: 50%;
  border: 1.8px solid var(--border);
  background: var(--surface-solid);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: border-color 0.12s, background 0.12s;
}
.launch-radio-dot::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  transform: scale(0);
  transition: transform 0.12s ease;
}
.launch-radio.is-checked .launch-radio-dot {
  border-color: var(--ch-color, var(--accent));
}
.launch-radio.is-checked .launch-radio-dot::after {
  transform: scale(1);
  background: var(--ch-color, var(--accent));
}
.launch-radio input:focus-visible + .launch-radio-dot {
  outline: 2px solid color-mix(in srgb, var(--ch-color, var(--accent)) 60%, transparent);
  outline-offset: 3px;
}
.launch-radio-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
}

/* Submit row */
.launch-submit-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.launch-submit { padding: 12px 22px; font-size: 14px; }
.launch-submit-hint {
  font-size: 11.5px;
  color: var(--text-mute);
  letter-spacing: 0.2px;
}

/* Recent submissions */
.launch-recent {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}
.launch-recent-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 14px;
}
.launch-recent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.launch-recent-item {
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
}
.launch-recent-main {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.launch-recent-property {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.launch-recent-when {
  font-size: 10.5px;
  color: var(--text-mute);
  font-style: italic;
}
.launch-recent-meta {
  font-size: 11.5px;
  color: var(--text-soft);
  margin-top: 4px;
}

/* ---------- Skeleton loader (used by lazy/HTMX phases) ---------- */
.skeleton {
  display: block;
  min-height: 14px;
  border-radius: 10px;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--text-mute) 14%, transparent) 0%,
    color-mix(in srgb, var(--text-mute) 26%, transparent) 50%,
    color-mix(in srgb, var(--text-mute) 14%, transparent) 100%
  );
  background-size: 200% 100%;
  animation: rbp-skel 1.4s infinite linear;
}
@keyframes rbp-skel {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Skeleton placeholder card — matches .card dimensions while content loads.
   Padding/radius mirror .card so swapping in real content doesn't reflow. */
.skeleton-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 130px;
  box-shadow: var(--shadow-lg);
  pointer-events: none;
}
.skeleton-card:hover { transform: none; border-color: var(--border); }

/* ---------- Property page: presence + print row ---------- */
.prop-meta-row {
  max-width: var(--page-max-width);
  margin: 14px auto 0;
  padding: 0 var(--page-pad-side);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.presence-row {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.presence-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg,
    var(--owner-color, var(--accent)),
    color-mix(in srgb, var(--owner-color, var(--accent)) 65%, var(--accent-cool)));
  border: 2px solid var(--surface-solid);
  margin-left: -8px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.10);
  cursor: default;
  transition: transform 0.14s ease;
}
.presence-avatar:first-child { margin-left: 0; }
.presence-avatar:hover { transform: translateY(-1px); z-index: 1; }

.btn-sm {
  padding: 6px 12px;
  font-size: 11.5px;
  height: 28px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
}

/* ---------- External resources card ---------- */
.ext-links {
  /* Re-uses the .prop-info base; minor tweak: drop the heavy left rule when
     it isn't variant-accented. */
  border-left: 1px solid var(--info-border);
}
.ext-links-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-bottom: 10px;
}
@media (max-width: 640px) {
  .ext-links-grid { grid-template-columns: 1fr; }
}
.ext-links-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
.ext-link-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--kaye);
  background: color-mix(in srgb, var(--kaye) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--kaye) 30%, transparent);
  transition: background 0.12s, transform 0.12s;
}
.ext-link-chip::after {
  content: "↗";
  font-size: 10px;
  opacity: 0.7;
}
.ext-link-chip:hover {
  background: color-mix(in srgb, var(--kaye) 18%, transparent);
  transform: translateY(-1px);
}

/* ---------- Activity timeline ---------- */
.activity-card {
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  margin-top: 18px;
  box-shadow: var(--shadow);
}
.activity-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.activity-eyebrow {
  font-size: 10.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 700;
}
.activity-sub {
  font-size: 10.5px;
  color: var(--text-mute);
  font-style: italic;
}
.activity-empty {
  font-size: 12.5px;
  color: var(--text-soft);
  padding: 12px 4px 4px;
}

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}
.timeline-item {
  position: relative;
  padding: 8px 0 12px 22px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.timeline-item::before {
  /* Vertical connector through the dot. */
  content: "";
  position: absolute;
  left: 5px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: color-mix(in srgb, var(--text-mute) 18%, transparent);
}
.timeline-item:first-child::before { top: 10px; }
.timeline-item:last-child::before  { bottom: calc(100% - 16px); }
.timeline-dot {
  position: absolute;
  left: 0;
  top: 11px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid var(--surface-solid);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bg-color, var(--text-mute)) 18%, transparent);
  background: var(--accent);
}
.timeline-item--status .timeline-dot { background: var(--accent); }
.timeline-item--field  .timeline-dot { background: var(--accent-cool); }

/* ---------- API & Integrations card (Settings page) -----------------
   Pared-down: one row for the API key (status + regenerate), one row for
   the webhook URL. The one-shot reveal banner sits on top when present. */
.api-section {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.api-block-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-weight: 700;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.api-form { margin: 0; }
.api-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.api-key-status {
  flex: 1 1 auto;
  font-size: 13px;
  color: var(--text-soft);
}
.api-key-status code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 5px;
  color: var(--text);
}
.api-input {
  flex: 1 1 320px;
  min-width: 0;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12.5px;
  height: 38px;
  padding: 0 12px;
  background: var(--surface-solid);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.api-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* Revealed-key banner: one-shot secret with a soft pulse so the user
   can't miss it on first paint. Shown only right after regenerate. */
.api-key-revealed {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-solid));
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 0 8px 28px -14px color-mix(in srgb, var(--accent) 60%, transparent);
  animation: api-key-pulse 1.8s ease-out 1;
}
.api-key-revealed-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-weight: 700;
  color: var(--accent);
}
@keyframes api-key-pulse {
  0%   { box-shadow: 0 0 0 0   color-mix(in srgb, var(--accent) 50%, transparent); }
  60%  { box-shadow: 0 0 0 14px color-mix(in srgb, var(--accent) 0%,  transparent); }
  100% { box-shadow: 0 8px 28px -14px color-mix(in srgb, var(--accent) 60%, transparent); }
}

/* Compact ghost button variant — used for inline actions like "Copy" and
   the Properties "Export CSV" link. Matches the .btn-ghost shape but with
   tighter padding so it sits comfortably next to inputs / selects. */
.btn-ghost.btn-sm {
  padding: 6px 14px;
  font-size: 12px;
  border-radius: 999px;
  line-height: 1.2;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.timeline-item--mention .timeline-dot { background: var(--yellow); }
.timeline-body { min-width: 0; }
.timeline-desc {
  font-size: 13px;
  color: var(--text);
  line-height: 1.45;
}
.timeline-meta {
  display: flex;
  gap: 10px;
  margin-top: 2px;
  font-size: 11px;
  color: var(--text-mute);
}
.timeline-time { font-variant-numeric: tabular-nums; }
.timeline-actor {
  font-weight: 700;
  color: var(--text-soft);
}

/* ---------- Confetti (property complete) ---------- */
.confetti-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  overflow: hidden;
}
.confetti-piece {
  position: absolute;
  top: -20px;
  width: 8px;
  height: 12px;
  border-radius: 1px;
  opacity: 1;
  animation: rbp-confetti 2.4s ease-out forwards;
}
@keyframes rbp-confetti {
  0%   { transform: translate(0, 0) rotate(0deg);   opacity: 1; }
  100% { transform: translate(var(--dx, 0), 80vh) rotate(720deg); opacity: 0; }
}

/* ---------- Responsive: collapse + stack at 700px ----------
   Force the sidebar into icon-only mode (mirrors data-sidebar=collapsed),
   wrap the topbar items, and drop card grids to a single column. */
@media (max-width: 700px) {
  .sidebar { width: 56px; }
  .sidebar-logo { padding: 2px; }
  .sidebar-logo-img { max-height: 36px; }
  .sidebar-toggle { transform: rotate(180deg); }
  .nav-item {
    justify-content: center;
    padding: 9px 0;
  }
  .nav-label { display: none; }
  .recent-section { display: none; }

  .topbar {
    flex-wrap: wrap;
    padding: 10px 14px;
    gap: 8px;
  }
  .topbar-left,
  .topbar-right {
    flex-wrap: wrap;
  }

  .card-grid {
    grid-template-columns: 1fr;
  }

  .hero,
  .section,
  .page-head,
  .filter-bar { padding-left: 18px; padding-right: 18px; }
}

/* ---------- Print: clean, paper-friendly property page ---------- */
@media print {
  html, body {
    background: #fff !important;
    color: #000 !important;
  }
  body { background-image: none !important; }
  .sidebar,
  .topbar,
  .filter-chips,
  .bulk-bar,
  .task-select,
  .task-checkbox,
  .task-checkbox-mark,
  .status-pill,
  .status-form,
  .scrolltop,
  .toast,
  .cmdk,
  .shortcuts,
  .prop-meta-row,
  .notif-popover,
  .profile,
  .skeleton-note {
    display: none !important;
  }
  .layout { display: block; }
  .main-content { padding: 0; }
  .content { max-width: none; padding: 16px; }
  .prop-header { box-shadow: none; border-bottom: 1px solid #000; }
  .prop-info, .ext-links, .owner-progress, .activity-card, .phase-section {
    background: #fff !important;
    box-shadow: none !important;
    border-color: #ccc !important;
    page-break-inside: avoid;
  }
  .task-row {
    break-inside: avoid;
    page-break-inside: avoid;
    background: #fff !important;
    border-color: #ccc !important;
  }
  .timeline-item, .ext-link-chip { color: #000 !important; }
  a { color: #000 !important; text-decoration: underline; }
}

/* =====================================================================
 * Cohesion sweep additions
 *
 * Everything below was added during the UI/UX cohesion pass. New rules
 * are grouped here (vs scattered inline) so the diff is easy to review
 * and so we can easily lift them into a separate `_cohesion.css` later.
 * ===================================================================== */

/* ---- Unified themed scrollbar ---------------------------------------
   Apply `.scroll-themed` (or rely on this rule via element selector
   below) to any scrollable container so all of them share the slim,
   color-matched scrollbar. */
.scroll-themed,
.global-search-results,
.notif-popover-list,
.notif-popover-panel,
.profile-dropdown,
.cmdk-results,
.cmdk-panel,
.mention-popup,
.main-content {
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) transparent;
}
.scroll-themed::-webkit-scrollbar,
.global-search-results::-webkit-scrollbar,
.notif-popover-list::-webkit-scrollbar,
.notif-popover-panel::-webkit-scrollbar,
.profile-dropdown::-webkit-scrollbar,
.cmdk-results::-webkit-scrollbar,
.cmdk-panel::-webkit-scrollbar,
.mention-popup::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.scroll-themed::-webkit-scrollbar-track,
.global-search-results::-webkit-scrollbar-track,
.notif-popover-list::-webkit-scrollbar-track,
.notif-popover-panel::-webkit-scrollbar-track,
.profile-dropdown::-webkit-scrollbar-track,
.cmdk-results::-webkit-scrollbar-track,
.cmdk-panel::-webkit-scrollbar-track,
.mention-popup::-webkit-scrollbar-track {
  background: transparent;
}
.scroll-themed::-webkit-scrollbar-thumb,
.global-search-results::-webkit-scrollbar-thumb,
.notif-popover-list::-webkit-scrollbar-thumb,
.notif-popover-panel::-webkit-scrollbar-thumb,
.profile-dropdown::-webkit-scrollbar-thumb,
.cmdk-results::-webkit-scrollbar-thumb,
.cmdk-panel::-webkit-scrollbar-thumb,
.mention-popup::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 999px;
}
.scroll-themed::-webkit-scrollbar-thumb:hover,
.global-search-results::-webkit-scrollbar-thumb:hover,
.notif-popover-list::-webkit-scrollbar-thumb:hover,
.notif-popover-panel::-webkit-scrollbar-thumb:hover,
.profile-dropdown::-webkit-scrollbar-thumb:hover,
.cmdk-results::-webkit-scrollbar-thumb:hover,
.cmdk-panel::-webkit-scrollbar-thumb:hover,
.mention-popup::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover);
}

/* Whole-page scrollbar (overrides browser default). */
html { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
html::-webkit-scrollbar { width: 10px; }
html::-webkit-scrollbar-track { background: transparent; }
html::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 999px;
  border: 2px solid var(--bg);
}
html::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }

/* ---- Launch form: Monday sync pills + info banner -----------------
   Surfaced inline in the launch-flash banner after a submission so the
   user knows whether the push to Monday actually went through. */
.launch-sync-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  border: 1px solid;
  vertical-align: middle;
}
.launch-sync-pill--ok {
  color: var(--success);
  background: color-mix(in srgb, var(--success) var(--tint-bg), transparent);
  border-color: color-mix(in srgb, var(--success) var(--tint-border), transparent);
}
.launch-sync-pill--err {
  color: var(--error);
  background: color-mix(in srgb, var(--error) var(--tint-bg), transparent);
  border-color: color-mix(in srgb, var(--error) var(--tint-border), transparent);
}
.launch-sync-pill--pending {
  color: var(--text-soft);
  background: color-mix(in srgb, var(--text-mute) var(--tint-bg), transparent);
  border-color: color-mix(in srgb, var(--text-mute) var(--tint-border), transparent);
}
.launch-sync-detail {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--text-mute);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.launch-flash--info {
  background: color-mix(in srgb, var(--info) var(--tint-bg), transparent);
  border: 1px solid color-mix(in srgb, var(--info) 40%, transparent);
  color: color-mix(in srgb, var(--info) 78%, var(--text));
}

/* ---- Property page: meta-action row (presence + buttons) ----------- */
.prop-meta-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.prop-meta-actions .btn-sm svg { flex-shrink: 0; }

/* Compact size modifier shared across all buttons in the family. */
.btn-primary.btn-sm,
.btn-ghost.btn-sm,
.btn-secondary.btn-sm,
.btn-danger.btn-sm {
  padding: var(--btn-pad-y-sm) var(--btn-pad-x-sm);
  font-size: 12px;
  height: 28px;
  line-height: 1;
}

/* ---- Task row: subtle lift so it reads as a card family member ----- */
.task-row {
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
}
[data-theme="dark"] .task-row {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.02);
}

/* ---- Settings page: btn-ghost.btn-sm legacy compat ----------------- */
/* The earlier .btn-ghost.btn-sm rule above (line ~3629) is preserved
   for backward compatibility; the new shared .btn-sm modifier supersedes
   it but won't conflict (same shape, same height). */

/* =====================================================================
 * PHASE B — Shared components
 *
 * Four reusable building blocks: pill / form-field / avatar-chip /
 * empty-state. Existing legacy classes (.filter-chip, .status-pill,
 * .notif-status-pill, .auth-field, .settings-field, .launch-field,
 * .prop-field, .profile-avatar, .presence-avatar, .mention-avatar,
 * .notif-empty, .cmdk-empty, .global-search-empty) participate in the
 * shared geometry via grouped selectors so they inherit consistent
 * shape / typography / spacing without needing template rewrites.
 *
 * Templates can also use the new component classes directly going
 * forward — both paths produce the same visual result.
 * ===================================================================== */

/* ---- .pill — chips, tags, badges, status indicators ----------------
   Foundation: 999px radius, inline-flex, --fs-small, --fw-semi, with
   color slots driven by --pill-color (text + border) and --pill-bg
   (background). Variants set those slots so the geometry stays one
   place and color tweaks land in one place. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: inherit;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-semi);
  letter-spacing: 0.2px;
  white-space: nowrap;
  border: 1px solid;
  cursor: default;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  /* The slot pattern — variants override these two custom props */
  color: var(--pill-color, var(--text-primary));
  background: var(--pill-bg, color-mix(in srgb, var(--text-muted) var(--tint-bg), transparent));
  border-color: var(--pill-border, color-mix(in srgb, var(--text-muted) var(--tint-border), transparent));
}
.pill[role="button"], button.pill, a.pill { cursor: pointer; }
.pill > svg { flex-shrink: 0; }

/* Size modifiers */
.pill--sm { padding: 2px 8px; font-size: 10.5px; letter-spacing: 0.4px; }
.pill--lg { padding: 6px 14px; font-size: var(--fs-body); }

/* Intent variants (soft style: tinted bg + colored text/border) */
.pill--accent  { --pill-color: var(--action-primary); --pill-bg: color-mix(in srgb, var(--action-primary) var(--tint-bg), transparent); --pill-border: color-mix(in srgb, var(--action-primary) var(--tint-border), transparent); }
.pill--success { --pill-color: var(--state-success); --pill-bg: color-mix(in srgb, var(--state-success) var(--tint-bg), transparent); --pill-border: color-mix(in srgb, var(--state-success) var(--tint-border), transparent); }
.pill--warning { --pill-color: var(--state-warning); --pill-bg: color-mix(in srgb, var(--state-warning) var(--tint-bg), transparent); --pill-border: color-mix(in srgb, var(--state-warning) var(--tint-border), transparent); }
.pill--error   { --pill-color: var(--state-error);   --pill-bg: color-mix(in srgb, var(--state-error) var(--tint-bg), transparent);   --pill-border: color-mix(in srgb, var(--state-error) var(--tint-border), transparent); }
.pill--info    { --pill-color: var(--state-info);    --pill-bg: color-mix(in srgb, var(--state-info) var(--tint-bg), transparent);    --pill-border: color-mix(in srgb, var(--state-info) var(--tint-border), transparent); }
.pill--neutral { --pill-color: var(--text-secondary); --pill-bg: color-mix(in srgb, var(--text-muted) var(--tint-bg), transparent); --pill-border: color-mix(in srgb, var(--text-muted) var(--tint-border), transparent); }

/* Style modifier — solid (filled bg, white text) */
.pill--solid {
  color: var(--text-inverse);
  background: var(--pill-color, var(--action-primary));
  border-color: var(--pill-color, var(--action-primary));
}
/* Style modifier — outline (transparent bg, colored border) */
.pill--outline {
  background: transparent;
  /* color + border-color come from --pill-color slot already */
}

/* Interactive (chip-style) — for clickable filter pills */
.pill--interactive { cursor: pointer; }
.pill--interactive:hover {
  background: color-mix(in srgb, var(--pill-color, var(--text-secondary)) calc(var(--tint-bg) + 6%), transparent);
}
.pill--interactive.is-active {
  --pill-bg: var(--pill-color, var(--action-primary));
  color: var(--text-inverse);
  border-color: var(--pill-color, var(--action-primary));
}

/* Legacy compat — existing pill-like classes inherit the geometry so
   they read as one component family. Each can still add its own
   one-off rules below for size/color tweaks. */
.badge-done,
.phase-pill,
.notif-status-pill,
.notif-popover-count,
.my-tasks-chip,
.ext-link-chip,
.recent-chip { /* base ring shape — many of these already had something
                  similar, this just keeps them coherent. */ }

/* ---- .form-field — label + input + hint + error pattern -----------
   Foundation: vertical stack of label / input / optional hint / optional
   error. Inputs share the same height, border, focus ring across the app
   regardless of which form they're in.

   Existing classes (.auth-field, .settings-field, .launch-field) are
   grouped here so they all read identically. .prop-field is separate
   because the property page uses tighter inline labels (will revisit
   in Phase D). */
.form-field,
.auth-field,
.settings-field,
.launch-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0; /* lets the field shrink inside a flex/grid parent */
}
.form-field__label,
.auth-field-label,
.settings-field-label,
.launch-field-label {
  font-size: var(--fs-eyebrow);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: var(--fw-bold);
  line-height: var(--lh-eyebrow);
}
.form-field__input,
.form-field input[type="text"],
.form-field input[type="email"],
.form-field input[type="password"],
.form-field input[type="number"],
.form-field input[type="search"],
.form-field input[type="url"],
.form-field input[type="date"],
.form-field select,
.form-field textarea {
  width: 100%;
  border: 1.5px solid var(--border-subtle);
  border-radius: 10px;
  height: 38px;
  padding: 0 13px;
  font-size: var(--fs-input);
  font-family: inherit;
  color: var(--text-primary);
  background: var(--bg-surface-solid);
  outline: none;
  outline-offset: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.form-field textarea,
.form-field__input--multiline {
  height: auto;
  padding: 10px 13px;
  line-height: var(--lh-input);
  resize: vertical;
  min-height: 76px;
}
.form-field__input:focus,
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  border-color: var(--action-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--action-primary) 18%, transparent);
}
.form-field__hint {
  font-size: var(--fs-eyebrow);
  color: var(--text-muted);
  line-height: var(--lh-eyebrow);
}
.form-field__error {
  font-size: var(--fs-eyebrow);
  color: var(--state-error);
  line-height: var(--lh-eyebrow);
  display: flex;
  align-items: center;
  gap: 4px;
}
/* Invalid state — colors the input border/ring, hint switches to error */
.form-field--invalid .form-field__input,
.form-field--invalid input,
.form-field--invalid select,
.form-field--invalid textarea {
  border-color: var(--state-error);
}
.form-field--invalid .form-field__input:focus,
.form-field--invalid input:focus,
.form-field--invalid select:focus,
.form-field--invalid textarea:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--state-error) 18%, transparent);
}

/* ---- .avatar-chip — initial in circle, optional name label ---------
   Foundation: a colored circle with an inline initial. Supports
   size variants (sm/md/lg) and an optional inline label. Used for
   presence rows, mention popup, profile menu, owner tags.
   Replaces the ad-hoc rules across .profile-avatar, .presence-avatar,
   .mention-avatar, .profile-card-avatar — those rules still exist
   below for backward compat, just sharing the base geometry now. */
.avatar-chip,
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  font-family: inherit;
  font-weight: var(--fw-bold);
  color: var(--text-inverse);
  line-height: 1;
  letter-spacing: 0;
  user-select: none;
  /* Default colored gradient — overridable per avatar via --av-color */
  background: linear-gradient(135deg,
    var(--av-color, var(--action-primary)),
    color-mix(in srgb, var(--av-color, var(--action-primary)) 65%, var(--action-secondary)));
}
.avatar--sm { width: 22px; height: 22px; font-size: 11px; }
.avatar      { width: 26px; height: 26px; font-size: 12px; }
.avatar--md  { width: 26px; height: 26px; font-size: 12px; }
.avatar--lg  { width: 38px; height: 38px; font-size: 15px; }
.avatar--xl  { width: 64px; height: 64px; font-size: 22px; }

/* avatar-chip = avatar + label in a single line */
.avatar-chip {
  width: auto;
  height: auto;
  border-radius: 999px;
  background: transparent;
  color: var(--text-primary);
  padding: 3px 10px 3px 3px;
  gap: 8px;
  font-weight: var(--fw-semi);
  font-size: var(--fs-small);
  border: 1px solid var(--border-subtle);
  cursor: default;
}
.avatar-chip > .avatar { width: 22px; height: 22px; font-size: 11px; }

/* ---- .empty-state — heading + body + optional action ---------------
   Foundation: centered stack inside a soft dashed card. Refines the
   existing .empty-state with a --compact variant for popovers
   (notif popover, command palette, search results). */
.empty-state {
  background: var(--bg-surface);
  backdrop-filter: blur(40px) saturate(140%);
  -webkit-backdrop-filter: blur(40px) saturate(140%);
  border: 1px dashed var(--border-subtle);
  border-radius: 16px;
  padding: 60px 28px;
  text-align: center;
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.empty-state__title,
.empty-title {
  font-size: var(--fs-card-title);
  font-weight: var(--fw-medium);
  letter-spacing: -0.2px;
  color: var(--text-primary);
  margin: 0;
}
.empty-state__body,
.empty-body {
  font-size: var(--fs-body);
  color: var(--text-secondary);
  margin: 0;
  max-width: 420px;
  line-height: var(--lh-body);
}
.empty-state__action { margin-top: 8px; }

/* Compact variant for popovers / inline empty states. No card chrome,
   smaller text, less padding. */
.empty-state--compact {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: none;
  border-radius: 0;
  padding: 28px 16px;
  box-shadow: none;
  gap: 6px;
}
.empty-state--compact .empty-state__title { font-size: var(--fs-body); font-weight: var(--fw-semi); }
.empty-state--compact .empty-state__body { font-size: var(--fs-small); }

/* Legacy compat — existing inline empty states get the compact
   look via grouping. */
.notif-popover-empty,
.cmdk-empty,
.global-search-empty {
  /* Already mostly compact; this just unifies typography */
  font-family: inherit;
  font-size: var(--fs-small);
  color: var(--text-secondary);
}

/* =====================================================================
 * PHASE C — Property card content
 *
 * The card-head now carries the active-phase pill (or "Done" pill at
 * 100%). Below it, the owner row shows an avatar + name; the address
 * line sits underneath when present. Progress is unchanged.
 * ===================================================================== */
.card-owner {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.card-owner-name {
  font-size: var(--fs-body);
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.card-address {
  font-size: var(--fs-small);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The card-head needs a bit more breathing room for the right-side pill
   without pushing the title into ellipsis prematurely. */
.card-head {
  align-items: center;
}
.card-head > .pill { flex-shrink: 0; }

/* On .card-with-delete the .card-pin (star) and .card-delete (trash)
   sit absolutely in the top-right corner (pin at right:50px, delete at
   right:12px — combined ~78px wide column). The phase pill inside
   .card-head would otherwise flex-end to the same x position and
   overlap. Reserve a right gutter so the pill aligns to the left of
   the icon column instead. */
.card-with-delete .card-head {
  padding-right: 76px;
}

/* =====================================================================
 * Cancellation policy dropdowns (launch form)
 *
 * Was 5 radio-card fieldsets; now 5 selects laid out in a 2-col grid.
 * Each select gets a colored letter chip inline with the field label
 * so the channel identity is still readable at a glance.
 * ===================================================================== */
.cancellation-select-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-transform: none;          /* let the policy label keep normal case */
  letter-spacing: 0.1px;
  font-size: var(--fs-small);
  color: var(--text-primary);
  font-weight: var(--fw-semi);
}
.cancellation-select-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--ch-color, var(--accent)) 18%, transparent);
  color: var(--ch-color, var(--accent));
  font-size: 10.5px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.5px;
  flex-shrink: 0;
}
.cancellation-select select {
  border: 1.5px solid color-mix(in srgb, var(--ch-color, var(--accent)) 28%, var(--border-subtle));
}
.cancellation-select select:focus {
  border-color: var(--ch-color, var(--accent));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ch-color, var(--accent)) 18%, transparent);
}

/* =====================================================================
 * Themed confirmation modal — replaces window.confirm()
 * ===================================================================== */
.confirm-modal {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.confirm-modal.is-open {
  display: flex;
  animation: cmdk-fade 0.16s ease both;
}
.confirm-modal-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--bg-canvas) 60%, transparent);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
}
.confirm-modal-panel {
  position: relative;
  width: min(420px, 92vw);
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: 16px;
  padding: 24px 24px 20px;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.45);
  animation: cmdk-scale 0.18s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.confirm-modal-title {
  font-size: var(--fs-card-title);
  font-weight: var(--fw-semi);
  letter-spacing: -0.2px;
  margin: 0 0 8px;
  color: var(--text-primary);
}
.confirm-modal-body {
  font-size: var(--fs-body);
  color: var(--text-secondary);
  line-height: var(--lh-body);
  margin: 0 0 20px;
}
.confirm-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* =====================================================================
 * PHASE F — Home stat trends + Notification recency buckets
 * ===================================================================== */

/* Home stat strip — small caption under each stat value. Up-trend
   captions use the success tone, flat uses muted. */
.stat-trend {
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-semi);
  letter-spacing: 0.3px;
  margin-top: 4px;
}
.stat-trend--up   { color: var(--state-success); }
.stat-trend--flat { color: var(--text-muted); }
.stat-trend--down { color: var(--state-error); }

/* Notifications page — Today / This week / Earlier section grouping.
   Each bucket gets a small eyebrow heading + count chip, and the list
   inside reuses the existing .notif-list styling. */
.notif-bucket {
  margin-bottom: 22px;
}
.notif-bucket:last-of-type { margin-bottom: 0; }
.notif-bucket-title {
  font-size: var(--fs-eyebrow);
  letter-spacing: 2.4px;
  text-transform: uppercase;
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.notif-bucket-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--text-muted) 14%, transparent);
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: var(--fw-bold);
  letter-spacing: 0;
}

/* =====================================================================
 * PHASE E — Launch form sticky section nav
 *
 * A pill-strip nav that sits right under the progress bar (which is
 * itself sticky under the topbar) so the user can jump between
 * Property / Cancellation / Pricing / Property Launch at any scroll
 * position. The active chip updates as the user scrolls (driven by
 * IntersectionObserver in launch.html's inline script).
 * ===================================================================== */
.launch-section-nav {
  position: sticky;
  /* Sits below the topbar (~60px) and the launch-progress bar (~44px). */
  top: 104px;
  z-index: 9;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 22px;
  padding: 6px;
  background: color-mix(in srgb, var(--bg-canvas) 80%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
}
.launch-section-link {
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: var(--fs-small);
  font-weight: var(--fw-semi);
  color: var(--text-secondary);
  cursor: pointer;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
}
.launch-section-link:hover {
  color: var(--text-primary);
  background: color-mix(in srgb, var(--action-primary) var(--tint-hover), transparent);
}
.launch-section-link.is-active {
  background: linear-gradient(135deg, var(--action-primary), var(--action-secondary));
  color: var(--text-inverse);
  box-shadow: var(--btn-shadow);
}
.launch-section-link:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--action-primary) 55%, transparent);
  outline-offset: 2px;
}

/* Section anchor offset — scroll-margin-top so when the user clicks a
   nav chip the section title doesn't land underneath the sticky nav. */
.launch-card[id^="sec-"] {
  scroll-margin-top: 160px;
}

/* =====================================================================
 * PHASE D — Property detail two-column layout
 *
 * .content-grid splits the property page into a primary main column
 * (left, ~2fr) and an awareness rail (right, ~320px). The rail is
 * sticky on wide viewports so it stays visible while the user works
 * through tasks. Below 960px the grid collapses to single column and
 * the rail re-flows after the main content (so people on phones / split
 * screens still see everything in a sensible reading order).
 * ===================================================================== */
.content-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 320px);
  gap: 24px;
  align-items: start;
}
.content-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.content-rail {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: sticky;
  /* Stick just below the topbar (~60px) plus a comfortable gap. */
  top: 76px;
  align-self: start;
  /* Rail's own vertical scroll so a long activity feed doesn't push
     the whole sticky block taller than the viewport. */
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) transparent;
}
.content-rail::-webkit-scrollbar { width: 6px; }
.content-rail::-webkit-scrollbar-track { background: transparent; }
.content-rail::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 999px;
}

/* In single-column-wrap mode the rail's owner-progress grid can
   stretch wide; constrain it to the same max-width as the main column. */
.content-main > *,
.content-rail > * { margin: 0; }

/* The right rail's owner-progress grid was 2-up on the wider stand-alone
   layout. In the narrower rail it reads better as a single column. */
.content-rail .owner-progress-grid {
  grid-template-columns: 1fr;
}

/* Below 960px: stack everything. Drop sticky positioning so the rail
   flows naturally after the main column. */
@media (max-width: 960px) {
  .content-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .content-rail {
    position: static;
    max-height: none;
    overflow: visible;
  }
  .content-rail .owner-progress-grid {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  }
}

/* Tighter vertical gap inside cards now that we have more rows. */
.card,
.card-with-delete .card-link {
  gap: 10px;
}
