/* Liquid Glass design system. TenantMatch surfaces only. */

/* dev-0.28.0: the shared motion scale. Every animation added in the
   experience pass consumes these tokens; nothing new carries ad-hoc timing.
   Legacy animations keep their historical values but every one of them is
   covered by the reduced-motion block at the end of this file. */
:root {
  --lg-dur-fast: 160ms;
  --lg-dur-base: 280ms;
  --lg-dur-slow: 550ms;
  --lg-dur-beat: 700ms;
  --lg-dur-cine: 1300ms;
  --lg-ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --lg-ease-enter: cubic-bezier(0.2, 0.8, 0.3, 1.18);
  --lg-ease-linear: linear;
}

.conciergematch-bg {
  position: relative;
  min-height: 100vh;
  background: linear-gradient(135deg, #F5EFE6 0%, #EFE6D6 100%);
  overflow-x: hidden;
}

/* Floating soft radial-gradient blobs give backdrop-filter chromatic content to refract. */
.conciergematch-bg::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle 480px at 18% 12%, rgba(184, 149, 107, 0.48), transparent 60%),
    radial-gradient(circle 600px at 82% 25%, rgba(30, 41, 59, 0.32), transparent 65%),
    radial-gradient(circle 520px at 25% 78%, rgba(184, 149, 107, 0.40), transparent 60%),
    radial-gradient(circle 440px at 78% 88%, rgba(245, 239, 230, 0.62), transparent 60%),
    radial-gradient(circle 360px at 50% 50%, rgba(184, 149, 107, 0.22), transparent 70%);
  animation: lg-float 24s ease-in-out infinite alternate;
}

/* Subtle grain so the frosted surfaces have texture to soften. */
.conciergematch-bg::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.55;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

@keyframes lg-float {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-3%, 2%) scale(1.04); }
}

/* Keep TenantMatch content above the background layers. */
.conciergematch-bg > * {
  position: relative;
  z-index: 1;
}

/* dev-0.13.3 (Phase A root cause): the rule above sets position:relative on EVERY
   direct child of body, including the shared header and the body-appended auth
   dropdown, both of which must stay position:fixed. On the listing detail page
   (the only top-level page with body.conciergematch-bg) this forced the OPEN
   dropdown to render as a relative block at the very bottom of the document
   instead of under the person icon, so the click appeared to do nothing. The
   .open rule only re-asserted z-index, never position, which is why three prior
   z-index patches failed. Restore fixed positioning with a higher-specificity
   selector (0,2,0 beats the universal 0,1,0); top/right still come from
   .auth-dropdown. */
.conciergematch-bg > .auth-dropdown { position: fixed; z-index: 10000; }

/* dev-0.32 (CM mobile nav fix): the same .conciergematch-bg > * rule above gave
   the shared header z-index:1, trapping its descendant off-canvas mobile menu
   (z-index:999) BELOW the page card (.cm-wrap, also a z-index:1 sibling painted
   later in the DOM). The open hamburger menu therefore slid in behind the card.
   A higher-specificity rule (0,2,0 beats the universal 0,1,0) restores the
   header's own stacking level so its menu paints above the card. */
.conciergematch-bg > .site-header { z-index: 1000; }

@media (prefers-reduced-motion: reduce) {
  .conciergematch-bg::before { animation: none; }
}

.lg-surface {
  background: rgba(255, 255, 255, 0.42);
  backdrop-filter: blur(22px) saturate(1.7) contrast(1.06);
  -webkit-backdrop-filter: blur(22px) saturate(1.7) contrast(1.06);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 22px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.85) inset,
    0 0 0 1px rgba(184, 149, 107, 0.10),
    0 14px 48px rgba(30, 41, 59, 0.14);
  will-change: backdrop-filter;
}

.lg-elevated {
  background: rgba(255, 255, 255, 0.58);
  backdrop-filter: blur(32px) saturate(1.85) contrast(1.08);
  -webkit-backdrop-filter: blur(32px) saturate(1.85) contrast(1.08);
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 26px;
  padding: 36px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.95) inset,
    0 0 0 1px rgba(184, 149, 107, 0.12),
    0 22px 64px rgba(30, 41, 59, 0.18);
  will-change: backdrop-filter;
}

.lg-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: linear-gradient(180deg, rgba(184, 149, 107, 0.98), rgba(184, 149, 107, 0.85));
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 14px;
  color: white;
  font-weight: 600;
  font-family: 'Montserrat', Arial, sans-serif;
  padding: 14px 28px;
  font-size: 15px;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.3) inset,
    0 4px 16px rgba(184, 149, 107, 0.30);
}

.lg-button:hover { transform: translateY(-1px); box-shadow: 0 1px 0 rgba(255,255,255,0.4) inset, 0 8px 24px rgba(184, 149, 107, 0.40); }
.lg-button:active { transform: translateY(0); }
.lg-button:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }
.lg-button.lg-listening { background: linear-gradient(180deg, #b91c1c, #991b1b); animation: lg-pulse 1.4s ease-in-out infinite; }
@keyframes lg-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(185, 28, 28, 0.4); } 50% { box-shadow: 0 0 0 12px rgba(185, 28, 28, 0); } }

.lg-modal {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(34px) saturate(1.9);
  -webkit-backdrop-filter: blur(34px) saturate(1.9);
  border-radius: 24px;
  box-shadow: 0 30px 80px rgba(30, 41, 59, 0.30);
}

.lg-missing { box-shadow: 0 0 0 2px rgba(184, 149, 107, 0.7), 0 0 16px rgba(184, 149, 107, 0.25); animation: lg-missing-pulse 2.4s ease-in-out infinite; }
@keyframes lg-missing-pulse { 0%, 100% { box-shadow: 0 0 0 2px rgba(184, 149, 107, 0.7), 0 0 16px rgba(184, 149, 107, 0.25); } 50% { box-shadow: 0 0 0 2px rgba(184, 149, 107, 0.9), 0 0 24px rgba(184, 149, 107, 0.45); } }

/* Enriched signal cards */
.lg-signal-card { background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(16px) saturate(1.5); -webkit-backdrop-filter: blur(16px) saturate(1.5); border: 1px solid rgba(184, 149, 107, 0.22); border-radius: 16px; padding: 16px 20px; margin-bottom: 12px; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.7) inset, 0 6px 20px rgba(30, 41, 59, 0.08); }
.lg-signal-category { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #B8956B; margin-bottom: 6px; }
.lg-signal-observation { font-size: 14px; color: #1E293B; margin-bottom: 6px; line-height: 1.5; }
/* dev-refine-v3a: same trailing-margin defect, two levels up and one level in.
   The last signal card's 12px bottom margin sat inside the "What else we
   noticed" section (21/34), and the observation's own 6px sat inside the signal
   card (16/22). Both are separators between siblings, so both are dropped on
   the last one only; the containers' symmetric padding is untouched. */
.lg-signal-card:last-child { margin-bottom: 0; }
.lg-signal-observation:last-child { margin-bottom: 0; }
.lg-signal-quote { font-size: 12px; color: var(--text-muted-readable); font-style: italic; }
.lg-signal-polarity { display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 999px; margin-left: 8px; }
.lg-signal-positive { background: rgba(34, 197, 94, 0.15); color: #166534; }
.lg-signal-negative { background: rgba(239, 68, 68, 0.15); color: #991b1b; }
.lg-signal-neutral { background: rgba(156, 163, 175, 0.15); color: #374151; }
.lg-signal-dismiss { float: right; background: none; border: none; color: var(--text-muted-readable); cursor: pointer; font-size: 16px; }
.lg-signal-dismissed { opacity: 0.4; text-decoration: line-through; }

/* Chrome refraction (silently no-ops elsewhere) */
@supports (backdrop-filter: url(#lg-refraction)) {
  .lg-refractive { backdrop-filter: url(#lg-refraction) blur(12px) saturate(1.6); }
}

/* Tier 1 blurred photo container */
.tier1-photo-wrap { position: relative; overflow: hidden; border-radius: 18px 18px 0 0; aspect-ratio: 16/10; }
.tier1-photo { width: 100%; height: 100%; object-fit: cover; filter: blur(28px) saturate(1.15); transform: scale(1.08); transition: filter 0.4s ease; }
/* dev-0.32: gold "Private" / "NAH Listed" pill on a Tier 1 match card. */
.tier1-badge { position: absolute; top: 12px; left: 12px; z-index: 3; padding: 4px 10px; background: linear-gradient(135deg, #B8956B, #a6845d); color: #fff; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; border-radius: 6px; box-shadow: 0 2px 8px rgba(184, 149, 107, 0.4); }
.tier1-card:hover .tier1-photo { filter: blur(24px) saturate(1.25); }
.tier1-lock {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: rgba(30, 41, 59, 0.55); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-radius: 50%; width: 64px; height: 64px; display: flex; align-items: center; justify-content: center;
  color: white; font-size: 28px;
}
.tier1-lock-microcopy {
  position: absolute; bottom: 16px; left: 16px; right: 16px; text-align: center;
  color: white; font-size: 13px; font-weight: 500;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* TenantMatch layout helpers */
.cm-wrap { max-width: 820px; margin: 0 auto; padding: calc(var(--header-height) + var(--space-xs)) 20px 80px; }
.cm-wrap-wide { max-width: 1140px; margin: 0 auto; padding: calc(var(--header-height) + var(--space-md)) 20px 80px; }
@media (max-width: 768px) {
  .cm-wrap, .cm-wrap-wide { padding-top: calc(var(--header-height) + var(--space-xs)); }
}
/* dev-0.41: trim the dead space between the fixed header and the card heading on TenantMatch pages. The card carries its own 36px top pad on top of the header clearance, which read as too much air above the H1. */
/* dev-refine-v3a: the header clearance stays trimmed on .cm-wrap (above), but
   the card's own top pad does NOT. Cutting it to 10px (8px on phones) against
   the unchanged 36px bottom left every hero, header and CTA card on the funnel
   26 to 29px top-weighted, measured on 10 rendered cards across 4 routes
   (docs/diag/padding-audit/report.md), which reads as "text high, dead space
   below". It also put the first line inside the card's own 26px corner radius.
   The pair is balanced again: 36/36 on desktop, matching the 36px sides the
   base rule already sets, and a tighter 28/28 on phones where the sides drop to
   18px and vertical room is scarce. The trimmed .cm-wrap is what keeps the
   dev-0.41 symptom fixed. */
.conciergematch-bg .cm-wrap { padding-top: calc(var(--header-height) - var(--space-sm)); }
.conciergematch-bg .lg-elevated { padding-top: 36px; }
@media (max-width: 768px) {
  .conciergematch-bg .cm-wrap { padding-top: calc(var(--header-height) - var(--space-sm)); }
  .conciergematch-bg .lg-elevated { padding-top: 28px; padding-bottom: 28px; }
}
.cm-textarea {
  width: 100%; box-sizing: border-box; border-radius: 14px; border: 1px solid rgba(184, 149, 107, 0.35);
  background: rgba(255, 255, 255, 0.7); padding: 16px 18px; font-family: 'Outfit', 'Montserrat', Arial, sans-serif;
  font-size: 16px; line-height: 1.6; color: #1E293B; resize: vertical;
}
.cm-textarea:focus { outline: none; border-color: #B8956B; box-shadow: 0 0 0 3px rgba(184, 149, 107, 0.18); }
/* dev-0.9.0: explicit readable placeholder (was the browser default). Light
   here; the dark value is set in the dark-mode block at the end of this file. */
.cm-textarea::placeholder { color: var(--text-muted-readable); opacity: 1; }
.cm-counter { text-align: right; font-size: 12px; color: var(--text-muted-readable); margin-top: 6px; }
.cm-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 16px; flex-wrap: wrap; }
.cm-link { color: #B8956B; font-size: 14px; font-weight: 600; text-decoration: none; }
.cm-link:hover { text-decoration: underline; }
.cm-full { width: 100%; text-align: center; margin-top: 22px; }
.cm-field { display: block; margin-bottom: 14px; }
/* dev-refine-v3a: the trailing field's own 14px bottom margin stacked on top of
   the section's symmetric 22px pad, so the Areas card read 21 top against 36
   bottom while its neighbours (Basics, Timing and lease) read 21/22. The
   section's padding is correct and is left alone; only the last field's
   redundant trailing margin goes. Scoped to a direct child so a field that is a
   grid item keeps the margin its row spacing depends on. */
.cm-section > .cm-field:last-child { margin-bottom: 0; }
.cm-field label { display: block; font-size: 13px; font-weight: 600; color: #374151; margin-bottom: 6px; }
.cm-field input, .cm-field select { width: 100%; box-sizing: border-box; padding: 11px 14px; border-radius: 10px; border: 1px solid rgba(184, 149, 107, 0.3); background: rgba(255,255,255,0.8); font-size: 16px; color: #1E293B; }
.cm-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.cm-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
.cm-section { margin-bottom: 20px; padding: 22px 26px; }
/* dev-0.28.0: accordion heads are real <button> elements (keyboard + aria-expanded);
   the rule styles both the button form and any legacy div form identically. */
.cm-accordion-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; cursor: pointer; user-select: none; width: 100%; background: none; border: 0; padding: 0; font: inherit; color: inherit; text-align: left; min-height: 48px; }
.cm-accordion-head h3 { margin: 0; font-size: 18px; color: #1E293B; }
.cm-acc-h { margin: 0; }
.cm-acc-title { font-size: 18px; font-weight: 700; color: #1E293B; }
.cm-accordion-icon { transition: transform 0.25s ease; color: #B8956B; display: inline-flex; }
.cm-accordion.open .cm-accordion-icon { transform: rotate(180deg); }
.cm-accordion-body { display: none; margin-top: 14px; }
.cm-accordion.open .cm-accordion-body { display: block; }
.cm-microcopy { font-size: 13px; color: var(--text-muted-readable); line-height: 1.55; margin: 6px 0 14px; }
.cm-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.cm-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px; border: 1px solid rgba(184, 149, 107, 0.35); background: rgba(255,255,255,0.7); font-size: 13px; color: #1E293B; cursor: default; }
.cm-chip button { background: none; border: none; color: var(--text-muted-readable); cursor: pointer; font-size: 14px; line-height: 1; padding: 0; }
.cm-chip-want { border-color: rgba(34, 197, 94, 0.4); background: rgba(34, 197, 94, 0.08); }
.cm-chip-nice { border-color: rgba(184, 149, 107, 0.4); background: rgba(184, 149, 107, 0.08); }
.cm-chip-avoid { border-color: rgba(239, 68, 68, 0.4); background: rgba(239, 68, 68, 0.08); }
.cm-add-row { display: flex; gap: 8px; margin-top: 10px; }
.cm-add-row input { flex: 1; padding: 9px 12px; border-radius: 10px; border: 1px solid rgba(184,149,107,0.3); font-size: 16px; }
.cm-add-row select { padding: 9px 12px; border-radius: 10px; border: 1px solid rgba(184,149,107,0.3); font-size: 16px; }
.cm-add-btn { background: rgba(184, 149, 107, 0.15); border: 1px solid rgba(184,149,107,0.4); color: #7A5F3E; border-radius: 10px; padding: 9px 16px; font-size: 14px; cursor: pointer; }
/* dev-refine-v3 (P2): minmax(0, 1fr), never a bare 1fr. `1fr` is
   minmax(auto, 1fr) and that `auto` MINIMUM lets a track grow to its item's
   min-content, which is how the Tier 2 grid overflowed its own 1100px container
   by 324px at every desktop width. Capping the minimum at 0 makes each track
   exactly its share; the card contents (see .cm-tier2-address in
   conciergematch-results.html) then wrap inside it. */
.cm-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; margin-top: 28px; }
.tier1-card { display: flex; flex-direction: column; overflow: hidden; }
.tier1-body { padding: 18px 20px 22px; }
.tier1-archetype { font-size: 16px; font-weight: 700; color: #1E293B; margin: 0 0 4px; }
.tier1-band { font-size: 15px; color: #B8956B; font-weight: 600; margin: 0 0 10px; }
.tier1-specs { font-size: 13px; color: var(--text-muted-readable); margin: 0 0 14px; }
.tier1-score { font-size: 30px; font-weight: 800; color: #1E293B; line-height: 1; }
.tier1-score-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted-readable); margin-bottom: 14px; }
.tier1-bullets { list-style: none; padding: 0; margin: 0 0 18px; }
.tier1-bullets li { font-size: 13px; color: #374151; padding-left: 18px; position: relative; margin-bottom: 6px; }
.tier1-bullets li::before { content: '\2713'; position: absolute; left: 0; color: #B8956B; font-weight: 700; }
.cm-radio-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.cm-radio-row label { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: #374151; padding: 8px 14px; border: 1px solid rgba(184,149,107,0.3); border-radius: 10px; background: rgba(255,255,255,0.7); cursor: pointer; }

@media (max-width: 860px) {
  .cm-cards { grid-template-columns: 1fr; }
  .cm-grid-3 { grid-template-columns: 1fr; }
  .cm-grid-2 { grid-template-columns: 1fr; }
}

/* dev-0.6.1: Lucide inline icon helpers */
.lg-icon { display: inline-block; vertical-align: middle; flex-shrink: 0; }
.lg-icon-lg { width: 32px; height: 32px; }
.lg-icon-sm { width: 14px; height: 14px; }

/* dev-0.6.1: header clearance for TenantMatch routes that do NOT manage
   their own top padding. dev-0.12: cm-wrap / cm-wrap-wide are excluded because
   this element-qualified selector (specificity 0,1,1) was silently overriding
   their lighter .cm-wrap rule (0,1,0), reintroducing a ~84px gap below the
   header no matter how much .cm-wrap padding was reduced. Let cm-wrap own it. */
.conciergematch-bg main:not(.cm-wrap):not(.cm-wrap-wide),
.conciergematch-bg .conciergematch-main {
  padding-top: calc(var(--header-height, 80px) + var(--space-2xl, 64px));
  padding-bottom: var(--space-3xl, 96px);
}

/* dev-0.6.2: let the floating blobs show through the legacy form's opaque
   section so the glass surfaces have chromatic content to refract. */
.conciergematch-bg .intake-section { background: transparent; }

/* dev-0.6.1: "Need inspiration?" collapsible on intake */
.lg-inspiration { margin: 16px 0; }
.lg-inspiration-trigger {
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; color: #374151; font-weight: 500; user-select: none;
  list-style: none;
}
.lg-inspiration-trigger::-webkit-details-marker { display: none; }
.lg-inspiration[open] .lg-inspiration-trigger .lg-icon { transform: rotate(180deg); }
.lg-inspiration-trigger .lg-icon { transition: transform 0.25s ease; color: #B8956B; }
.lg-inspiration-body { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.lg-inspiration-hint { font-size: 12px; color: var(--text-muted-readable); margin: 0 0 4px; }
.lg-example {
  text-align: left; background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(184, 149, 107, 0.2); border-radius: 12px;
  padding: 14px 16px; cursor: pointer; font-family: inherit; font-size: 13px;
  color: #374151; line-height: 1.5; transition: all 0.2s ease;
}
.lg-example:hover { background: rgba(255, 255, 255, 0.85); border-color: rgba(184, 149, 107, 0.4); transform: translateY(-1px); }

/* dev-0.6.1: loading spinner */
.lg-spinner { display: inline-block; animation: lg-spin 1.2s linear infinite; }
@keyframes lg-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* dev-0.6.1: signal-card dismiss icon button */
.lg-signal-dismiss .lg-icon { display: block; }

/* dev-0.6.2: per-card "Why this match" explainer bullets */
.match-explainers { margin: 4px 0 14px; }
.match-explainers-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted-readable); margin-bottom: 8px; }
.explainer-list, .explainer-mismatches { list-style: none; padding: 0; margin: 0 0 6px 0; }
.explainer-list li, .explainer-mismatches li { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 5px; font-size: 13px; line-height: 1.4; }
.explainer-positive { color: #166534; }
.explainer-info { color: #b45309; }
.explainer-list .lg-icon, .explainer-mismatches .lg-icon { flex-shrink: 0; margin-top: 1px; }

/* dev-0.6.2: empty-state relaxation suggestions */
.empty-state-relaxations { margin: 28px 0; }
.relaxation-options { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.relaxation-apply { display: flex; align-items: center; justify-content: space-between; width: 100%; text-align: left; gap: 16px; }
.relaxation-label { flex: 1; }
.relaxation-action { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.relaxation-action .lg-icon { stroke: #ffffff; }

/* ============================================================
   dev-0.10.0: mobile UX pass for the TenantMatch funnel.
   ============================================================ */

/* The chat FAB (js/nah-chat.js) is fixed bottom-right and sits over the funnel's
   full-width / bottom-right primary CTA on every step, overlapping it at every
   scroll position (a bottom-right bubble cannot clear a full-width button by an
   offset alone, only shift where the overlap lands). Hide the whole chat widget
   on the TenantMatch / liquid-glass surfaces (body.conciergematch-bg); this
   higher-specificity selector overrides the widget's own scoped rules. Chat stays
   available on every other page, including the primary listing detail. */
body.conciergematch-bg .nah-chat { display: none; }

@media (max-width: 640px) {
  /* Phase 6: widen the choked column by trimming the card side padding on phones
     (top/bottom rhythm is left to the existing .conciergematch-bg overrides). */
  .lg-elevated { padding-left: 18px; padding-right: 18px; }
  .cm-section { padding-left: 18px; padding-right: 18px; }

  /* Phase 5: add-detail rows wrap so the text input takes its own full-width row
     and the slot select + "+ Add" share the row below it, instead of squeezing
     the input to a sliver at 390px. */
  .cm-add-row { flex-wrap: wrap; }
  .cm-add-row input { order: -1; flex: 1 1 100%; }
  .cm-add-row select { flex: 1 1 auto; min-height: 44px; }
  .cm-add-btn { min-height: 44px; }

  /* Phase 7: tap targets toward ~44px. The x buttons keep a small glyph but gain
     a real hit area via padding, pulled back with negative margin so the chip and
     the signal card do not visibly grow. */
  .cm-chip button { min-width: 28px; min-height: 28px; padding: 6px; margin: -6px -8px -6px -2px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
  .lg-signal-dismiss { min-width: 28px; min-height: 28px; padding: 6px; margin: -6px -6px 0 0; display: inline-flex; align-items: center; justify-content: center; }
  .cm-radio-row label { min-height: 44px; }

  /* Phase 9: scale the funnel card heading down on narrow screens so the L0
     intake textarea is visible without scrolling past a 5-line title. */
  .conciergematch-bg .lg-elevated h1 { font-size: 1.5rem; line-height: 1.25; }
}

/* ============================================================
   dev-0.9.0: Dark mode for the TenantMatch funnel surfaces.
   The funnel cards, fields, and chips were hardcoded light and never flipped,
   so in dark mode the theme-driven text turned champagne over a cream card
   (washed-out light-on-light). These overrides flip each surface to the slate
   dark palette from the styles.css :root dark block (bg #1E293B / #263244,
   border #3D4A5C, text champagne / #D1CCC3 / #B0B7C3), so each surface goes
   dark WITH its text. Some funnel text is hardcoded dark hex rather than
   variable-driven, so it is remapped to the matching light palette value here
   too, to avoid trading light-on-light for dark-on-dark. Light mode is
   untouched: every rule lives inside this media query. Surfaces use a
   translucent slate so the glass backdrop-filter still refracts the (now dark)
   background blobs.
   ============================================================ */
@media (prefers-color-scheme: dark) {
  /* Page background: cream gradient -> slate gradient */
  .conciergematch-bg {
    background: linear-gradient(135deg, #1E293B 0%, #151D2B 100%);
  }

  /* Card surfaces */
  .lg-surface,
  .cm-section {
    background: rgba(38, 50, 68, 0.55);
    border-color: rgba(61, 74, 92, 0.6);
  }
  .lg-elevated {
    background: rgba(38, 50, 68, 0.7);
    border-color: rgba(61, 74, 92, 0.65);
  }
  .lg-signal-card {
    background: rgba(38, 50, 68, 0.5);
    border-color: rgba(61, 74, 92, 0.55);
  }
  .lg-example {
    background: rgba(38, 50, 68, 0.5);
    border-color: rgba(61, 74, 92, 0.5);
    color: var(--text-secondary);
  }
  .lg-example:hover {
    background: rgba(48, 62, 82, 0.72);
    border-color: rgba(184, 149, 107, 0.5);
  }

  /* Form fields and chips: dark field over the dark card, champagne text */
  .cm-textarea,
  .cm-field input,
  .cm-field select,
  .cm-add-row input,
  .cm-add-row select {
    background: rgba(21, 29, 43, 0.6);
    border-color: #3D4A5C;
    color: var(--color-champagne);
  }
  .cm-textarea::placeholder { color: #B0B7C3; }
  .cm-chip {
    background: rgba(21, 29, 43, 0.55);
    border-color: rgba(61, 74, 92, 0.6);
    color: var(--color-champagne);
  }
  .cm-radio-row label {
    background: rgba(21, 29, 43, 0.5);
    border-color: rgba(61, 74, 92, 0.6);
    color: var(--text-secondary);
  }

  /* Hardcoded-dark funnel text remapped to the light palette */
  .cm-field label { color: var(--text-secondary); }
  .cm-accordion-head h3 { color: var(--text-primary); }
  .cm-microcopy { color: var(--text-muted-readable); }
  .cm-add-btn { color: #D4B88C; }
  .tier1-archetype { color: var(--text-primary); }
  .tier1-score { color: var(--text-primary); }
  .tier1-specs { color: var(--text-muted-readable); }
  .tier1-bullets li { color: var(--text-secondary); }
  .lg-signal-observation { color: var(--text-primary); }
  .lg-signal-quote { color: var(--text-muted-readable); }
  .lg-inspiration-trigger { color: var(--text-secondary); }

  /* Semantic accents lightened so they read on the dark card */
  .lg-signal-neutral { color: var(--text-secondary); }
  .lg-signal-positive { color: #4ADE80; }
  .lg-signal-negative { color: #F87171; }
  .explainer-positive { color: #4ADE80; }
  .explainer-info { color: #FBBF24; }

  /* dev-0.11.0: .lg-modal is not currently rendered, but it carried a hardcoded
     white glass surface; flip it so a future use inherits the dark treatment. */
  .lg-modal { background: rgba(38, 50, 68, 0.85); }
}

/* ============================================================
   dev-0.28.0: TenantMatch experience pass (presentation and motion only).
   One orchestrated moment per surface; every new animation rides the
   motion tokens at the top of this file; transform and opacity only on
   input-driven hot paths; reserved space wherever a number counts up.
   ============================================================ */

/* --- Intake: description card with a focus-within ring --- */
.lg-ta-card { margin-top: 18px; border: 1px solid rgba(184, 149, 107, 0.3); border-radius: 18px; background: rgba(255, 255, 255, 0.55); padding: 12px 14px 14px; transition: border-color var(--lg-dur-base) var(--lg-ease-out), box-shadow var(--lg-dur-base) var(--lg-ease-out); }
.lg-ta-card:focus-within { border-color: #B8956B; box-shadow: 0 0 0 4px rgba(184, 149, 107, 0.16); }
.lg-ta-card .cm-textarea { border: none; background: transparent; padding: 8px 6px; }
.lg-ta-card .cm-textarea:focus { box-shadow: none; }
.lg-ta-wrap { position: relative; }

/* --- dev-0.29.0: inset control row inside the field's frame. Dictate sits
       bottom-left, the counter bottom-right; the row lives in normal flow
       BELOW the textarea (never an overlay), so it can never cover typed
       text or the resize handle. --- */
.ta-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 4px; padding-top: 10px; border-top: 1px solid rgba(184, 149, 107, 0.22); }
.ta-foot #btn-dictate { min-height: 44px; padding: 10px 18px; font-size: 14px; }
.ta-foot .cm-counter { margin-top: 0; flex-shrink: 0; }

/* --- Intake: rotating typewriter ghost (decoration; never holds a value) --- */
.lg-ghost { position: absolute; inset: 0; padding: 8px 6px; pointer-events: none; overflow: hidden; color: var(--text-muted-readable); font-family: 'Outfit', 'Montserrat', Arial, sans-serif; font-size: 16px; line-height: 1.6; }
.lg-ghost-cursor { display: inline-block; width: 2px; height: 1.05em; background: #B8956B; vertical-align: -0.15em; animation: lg-caret 1s steps(1) infinite; }
@keyframes lg-caret { 50% { opacity: 0; } }

/* --- Intake: live recognition row (one row reserved so the first chips
       never shift the layout) --- */
.lg-reco { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; min-height: 32px; }
.lg-got { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: #1E293B; background: rgba(184, 149, 107, 0.14); border: 1px solid rgba(184, 149, 107, 0.55); border-radius: 999px; padding: 5px 11px; opacity: 0; transform: translateY(6px) scale(0.95); animation: lg-got-pop var(--lg-dur-base) var(--lg-ease-enter) forwards; }
.lg-got .lg-icon { width: 12px; height: 12px; color: #B8956B; }
@keyframes lg-got-pop { to { opacity: 1; transform: none; } }

/* --- Intake: clarity meter with the travelling key bow (coaching only;
       transform-driven, never width, so the input path stays 60fps) --- */
.lg-meter { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.lg-meter-track { position: relative; flex: 1; height: 16px; }
.lg-meter-rail { position: absolute; left: 0; right: 0; top: 6px; height: 4px; border-radius: 3px; background: rgba(184, 149, 107, 0.22); }
.lg-meter-fill { position: absolute; left: 0; right: 0; top: 6px; height: 4px; border-radius: 3px; background: linear-gradient(90deg, #B8956B, #CBAE8A); transform-origin: left center; transform: scaleX(0.04); transition: transform var(--lg-dur-slow) var(--lg-ease-out); will-change: transform; }
/* dev-0.29.0: the marker is the real brand key (130x76 viewBox, so 34x20 keeps
   its aspect), slate in the light scheme and gold in dark, sized to the track
   and centered on the rail. Absolutely positioned with transform-only travel:
   zero layout shift, stays on the compositor. */
.lg-meter-bow { position: absolute; left: 0; top: -2px; width: 34px; height: 20px; background-image: url('/images/NAH_key_slate_transparent.svg'); background-repeat: no-repeat; background-size: contain; background-position: center; transition: transform var(--lg-dur-slow) var(--lg-ease-out); will-change: transform; }
.lg-meter-label { font-size: 12.5px; color: var(--text-muted-readable); min-width: 104px; text-align: right; }
.lg-meter-label.lg-hot { color: #7A5F3E; font-weight: 600; }

/* --- Refine: grouped-card headers and the boxed signed-in line --- */
.cm-group-title { font-size: 11.5px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: #7A5F3E; margin: 0 0 12px; }
.lg-signed-line { background: rgba(255, 255, 255, 0.6); border: 1px solid rgba(184, 149, 107, 0.3); border-radius: 12px; padding: 12px 14px; }
#btn-not-you { min-height: 44px; }

/* --- Refine: polarity emphasis on signal cards --- */
.lg-signal-card { border-left-width: 3px; }
.lg-sig-pos { border-left-color: #16a34a; }
.lg-sig-neg { border-left-color: #dc2626; }
.lg-sig-neu { border-left-color: #B8956B; }

/* --- Refine: accordion body settle + selected radio pills --- */
.cm-accordion.open .cm-accordion-body { animation: lg-fade-in var(--lg-dur-base) var(--lg-ease-out); }
@keyframes lg-fade-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.cm-radio-row label { min-height: 44px; }
.cm-radio-row label:has(input:checked) { border-color: #B8956B; background: rgba(184, 149, 107, 0.12); }
.cm-radio-row input[type="radio"] { accent-color: #B8956B; }

/* --- Touch targets (the 28px chip hit-area rule is unchanged; these lift
       the remaining funnel controls to a 44px minimum) --- */
.cm-add-btn { min-height: 44px; }
#cm-save-search .lg-button { min-height: 44px; }
.cm-add-row select, .cm-add-row input { min-height: 44px; }
.cm-field input, .cm-field select { min-height: 44px; }
.lg-inspiration-trigger { min-height: 44px; align-items: center; }
label:has(> #f_terms) { min-height: 44px; }

/* --- Results: the resolve moment (space reserved; the count lands on the
       TRUE match total, and the block hides entirely on zero matches) --- */
.cm-resolve { margin-top: 20px; padding: 24px 20px; text-align: center; }
.cm-resolve-count { font-family: 'Montserrat', Arial, sans-serif; font-weight: 800; font-size: clamp(2.4rem, 9vw, 3.2rem); line-height: 1; color: #B8956B; font-variant-numeric: tabular-nums; min-height: 1em; }
.cm-resolve-label { margin-top: 6px; font-size: 14px; color: #374151; min-height: 1.45em; }
.cm-resolve-scan { height: 3px; border-radius: 2px; background: rgba(184, 149, 107, 0.22); overflow: hidden; margin-top: 14px; }
.cm-resolve-scan i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #B8956B, #CBAE8A); transform-origin: left center; transform: scaleX(0); transition: transform var(--lg-dur-cine) var(--lg-ease-out); }

/* --- Results: tier-1 match-score ring (the score the engine already
       returns; the number stays visible inside the ring) --- */
.tier1-ring { position: absolute; top: 12px; right: 12px; z-index: 3; width: 48px; height: 48px; display: block; }
.tier1-ring svg { transform: rotate(-90deg); display: block; }
.tier1-ring .tier1-score { position: absolute; inset: 0; display: grid; place-items: center; font-family: 'Montserrat', Arial, sans-serif; font-size: 14px; font-weight: 700; color: #F5EFE6; line-height: 1; }

/* --- Results: staggered card entry (JS-gated by .lg-anim so a failed
       script can never leave cards hidden; reduced motion never hides) --- */
.cm-cards.lg-anim > * { opacity: 0; transform: translateY(14px); }
.cm-cards.lg-anim > .lg-in { opacity: 1; transform: none; transition: opacity var(--lg-dur-slow) var(--lg-ease-out), transform var(--lg-dur-slow) var(--lg-ease-enter); }

/* --- Results tier 2: real gallery thumb strip --- */
.cm-thumbs { display: flex; gap: 6px; margin-top: 10px; }
.cm-thumbs img { width: 52px; height: 36px; border-radius: 6px; object-fit: cover; border: 1px solid rgba(184, 149, 107, 0.35); }
.cm-thumbs img:first-child { border-color: #B8956B; }

/* --- The tier-2 reveal (decoration on an already-authorized render; the
       overlay never intercepts a click and the server still decides tier) --- */
.cm-tier2-photo { position: relative; }
.lg-reveal { position: relative; }
.lg-reveal .cm-tier2-photo img { filter: blur(26px) saturate(1.1); transform: scale(1.12); transition: filter var(--lg-dur-cine) var(--lg-ease-out), transform var(--lg-dur-cine) var(--lg-ease-out); }
.lg-reveal .cm-thumbs { opacity: 0; transition: opacity var(--lg-dur-slow) var(--lg-ease-out) var(--lg-dur-slow); }
.lg-keyov { position: absolute; inset: 0; display: grid; place-items: center; z-index: 4; pointer-events: none; transition: opacity var(--lg-dur-slow) var(--lg-ease-out); }
.lg-keyring { width: 68px; height: 68px; border-radius: 50%; background: rgba(30, 41, 59, 0.85); border: 2px solid #B8956B; display: grid; place-items: center; }
.lg-keyring svg { width: 30px; height: 30px; color: #B8956B; transition: transform var(--lg-dur-slow) cubic-bezier(0.5, 0, 0.2, 1); display: block; }
.lg-reveal.lg-turn .lg-keyring svg { transform: rotate(96deg); }
.lg-glow { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; background: radial-gradient(60% 50% at 50% 30%, rgba(184, 149, 107, 0.35), transparent 70%); }
.lg-reveal.lg-open .cm-tier2-photo img { filter: none; transform: none; }
.lg-reveal.lg-open .lg-keyov { opacity: 0; }
.lg-reveal.lg-open .cm-thumbs { opacity: 1; }
.lg-reveal.lg-open .lg-glow { animation: lg-glow-pulse var(--lg-dur-cine) var(--lg-ease-out) 1; }
@keyframes lg-glow-pulse { 0% { opacity: 0; } 35% { opacity: 1; } 100% { opacity: 0; } }
.cm-tier2-address, .cm-tier2-price { font-variant-numeric: tabular-nums; }
.cm-tier2-price { min-height: 1.4em; }

/* --- dev-0.32.0: reveal choreography. The address resolves WITH the photo
       clear: veiled while .lg-reveal holds, then opacity plus a soft settle
       on the same cine token when .lg-open lands. The masked line reserves
       the box (nowrap, one line), so nothing shifts. --- */
.lg-reveal .cm-tier2-address { opacity: 0.45; transform: translateY(4px); }
.lg-reveal.lg-open .cm-tier2-address { opacity: 1; transform: none; transition: opacity var(--lg-dur-cine) var(--lg-ease-out), transform var(--lg-dur-cine) var(--lg-ease-out); }

/* --- dev-0.32.0: reveal-window chrome dim. Class-driven, filter-based so it
       multiplies with the card-entry opacity instead of overriding it; no
       layout change, pointer events untouched. The revealing card is exempt
       via .lg-reveal-focus on its link wrapper. .lg-reveal-dimming carries
       the transition both ways, so the restore glides over the base token
       when .lg-reveal-dim comes off. --- */
body.lg-reveal-dimming .site-header,
body.lg-reveal-dimming .site-footer,
body.lg-reveal-dimming .cm-wrap-wide > :not(#cm-cards),
body.lg-reveal-dimming #cm-cards > :not(.lg-reveal-focus) { transition: filter var(--lg-dur-base) var(--lg-ease-out); }
body.lg-reveal-dim .site-header,
body.lg-reveal-dim .site-footer,
body.lg-reveal-dim .cm-wrap-wide > :not(#cm-cards),
body.lg-reveal-dim #cm-cards > :not(.lg-reveal-focus) { filter: opacity(0.55); }

/* --- Dark mode for every new component (theme-aware, per Section 16.4) --- */
@media (prefers-color-scheme: dark) {
  .lg-ta-card { background: rgba(21, 29, 43, 0.55); border-color: rgba(61, 74, 92, 0.65); }
  .ta-foot { border-top-color: rgba(61, 74, 92, 0.6); }
  .lg-meter-bow { background-image: url('/images/NAH_key_gold_transparent.svg'); }
  .lg-ghost { color: #B0B7C3; }
  .lg-got { color: var(--color-champagne); background: rgba(184, 149, 107, 0.2); }
  .lg-meter-label { color: var(--text-muted-readable); }
  .lg-meter-label.lg-hot { color: #D4B88C; }
  .cm-group-title { color: #D4B88C; }
  .cm-acc-title { color: var(--text-primary); }
  .lg-signed-line { background: rgba(21, 29, 43, 0.5); border-color: rgba(61, 74, 92, 0.6); }
  .cm-resolve-label { color: var(--text-secondary); }
  .lg-sig-pos { border-left-color: #4ADE80; }
  .lg-sig-neg { border-left-color: #F87171; }
  .cm-radio-row label:has(input:checked) { background: rgba(184, 149, 107, 0.18); border-color: #B8956B; }
  .cm-thumbs img { border-color: rgba(61, 74, 92, 0.7); }
}

/* --- dev-0.32.0: material bow, dark scheme only. The brushed plate rides ON
       TOP of the flat gold key in the background stack (the pinned dark swap
       above stays byte-intact as the mask-unsupported fallback and keeps the
       real vector in the computed value), and the same key vector clips the
       element as a mask; the path is never redrawn. Travel transition and the
       34x20 geometry are untouched. No sweep on the bow. The plate URL lives
       only inside dark media blocks, so light scheme never fetches it. --- */
@media (prefers-color-scheme: dark) {
  @supports ((-webkit-mask-repeat: no-repeat) or (mask-repeat: no-repeat)) {
    .lg-meter-bow {
      background-image: url('/images/NAH_key_material_brushed.webp'), url('/images/NAH_key_gold_transparent.svg');
      background-size: cover, contain;
      background-position: center, center;
      background-repeat: no-repeat, no-repeat;
      -webkit-mask-image: url('/images/NAH_key_gold_transparent.svg');
      -webkit-mask-repeat: no-repeat;
      -webkit-mask-position: center;
      -webkit-mask-size: contain;
      mask-image: url('/images/NAH_key_gold_transparent.svg');
      mask-repeat: no-repeat;
      mask-position: center;
      mask-size: contain;
    }
  }
}

/* --- Reduced motion: full coverage. The three pre-existing guards
       (styles.css sidebar/gallery, styles.css auth dropdown, and the
       background blobs above) stay; this block covers every legacy
       funnel animation that had no guard plus everything new in this
       pass. Every surface renders its complete final state instantly;
       nothing is gated behind an animation. --- */
@media (prefers-reduced-motion: reduce) {
  /* legacy, previously uncovered */
  .lg-button.lg-listening { animation: none; }
  .lg-spinner { animation: none; }
  .lg-missing { animation: none; }
  .lg-button, .lg-example { transition: none; }
  .lg-button:hover, .lg-button:active, .lg-example:hover { transform: none; }
  .cm-accordion-icon, .lg-inspiration-trigger .lg-icon { transition: none; }
  .tier1-photo { transition: none; }
  /* new in dev-0.28.0: final states render instantly */
  .lg-ta-card { transition: none; }
  .lg-ghost-cursor { animation: none; display: none; }
  .lg-got { animation: none; opacity: 1; transform: none; }
  .lg-meter-fill, .lg-meter-bow { transition: none; }
  .cm-accordion.open .cm-accordion-body { animation: none; }
  .cm-resolve-scan i { transition: none; transform: scaleX(1); }
  .cm-cards.lg-anim > * { opacity: 1; transform: none; transition: none; }
  .lg-reveal .cm-tier2-photo img { filter: none; transform: none; transition: none; }
  .lg-reveal .cm-thumbs { opacity: 1; transition: none; }
  .lg-keyov { display: none; }
  .lg-keyring svg { transition: none; }
  .lg-reveal.lg-open .lg-glow, .lg-glow { animation: none; }
  /* dev-0.32.0: choreography final states render instantly (the cascade
     itself never runs under reduced motion; these guards keep the CSS layer
     complete on its own). */
  .lg-reveal .cm-tier2-address { opacity: 1; transform: none; transition: none; }
  body.lg-reveal-dimming .site-header, body.lg-reveal-dimming .site-footer,
  body.lg-reveal-dimming .cm-wrap-wide > :not(#cm-cards),
  body.lg-reveal-dimming #cm-cards > :not(.lg-reveal-focus) { transition: none; }
  body.lg-reveal-dim .site-header, body.lg-reveal-dim .site-footer,
  body.lg-reveal-dim .cm-wrap-wide > :not(#cm-cards),
  body.lg-reveal-dim #cm-cards > :not(.lg-reveal-focus) { filter: none; }
}
