/* ==========================================================================
   TenantMatch v2 visual layer (dev-TMV2-1). NAH Rental Homes.

   Ported by hand from docs/design/tmv2/tenantmatch-designed.html. Vanilla CSS,
   no framework, no build step, no new dependency.

   LOADED BY: index.html (the hero question), tenantmatch-v2.html (the picker,
   served only when TMV2=true) and, from dev-TMV2-2, conciergematch-results.html
   (the dossier card and the sealed match report at the foot of this file). All
   three also load css/styles.css. The two funnel pages additionally load
   css/liquid-glass.css; index.html deliberately does NOT, and must not
   (tests/dev0330-tutorial-harness.js A8 encodes that decision: the marketing
   pages do not carry the funnel stylesheet). That asymmetry is the whole reason
   for the same-value fallbacks in section 1.

   1. TOKENS: ALIASED, NOT ADOPTED
   -------------------------------
   The design authored 64 --tm-* tokens and 40 of them duplicate a value this
   codebase already owns. Adopting those values wholesale would mean every
   future brand edit had to be made twice, and the two copies would drift,
   which is the exact failure --cm-gold-text was created to end. So every
   duplicate is an ALIAS: one owner, the design's authored names preserved so
   this file stays diffable against docs/design/tmv2/tenantmatch-design-spec.md
   section by section.

   --tm-gold-ink is the one that mattered. The design gave it #7F6139/#CBA87C;
   dev-UX-1 created --cm-gold-text (#7A5F3E/#D4B88C) days earlier as the SINGLE
   owner of gold-as-text, precisely so the next gold label could not be authored
   against a fresh hex. Two owners of one job cannot coexist, so --tm-gold-ink
   aliases --cm-gold-text and the design's values are dropped. #7A5F3E is DARKER
   than #7F6139, so every light surface the spec measured (5.00 to 5.72:1) only
   improves; the dark pair is re-measured by tests/devTMV2-1-harness.js.

   THE ONE WRINKLE, AND WHY THE FALLBACKS BELOW ARE NOT A SECOND OWNER.
   --cm-gold-text and the --lg-dur and --lg-ease motion scale are declared in
   css/liquid-glass.css, which index.html does not load and must not. On that
   one page those var() calls would have no owner to resolve, so each carries a
   CSS-level fallback holding the SAME value the owner holds. A fallback is
   unreachable on every page that loads the owner, so it can never be the
   value in use where the owner exists, and it cannot drift silently:
   tests/devTMV2-1-harness.js reads both files and asserts every fallback
   equals its owner's declaration. Moving the owners into css/styles.css was
   the alternative and it is worse: dev0320 pins --lg-dur-cine to exactly one
   declaration AND asserts it is absent from css/styles.css, dev0280 pins the
   five durations to liquid-glass, and devUX1 pins both halves of
   --cm-gold-text there.

   2. GENUINELY NEW TOKENS
   -----------------------
   Declared here because nothing in the codebase owns the concept: the plate
   and lit-plate gradients, the sunk surface, the strong edge, the inner
   highlight, the caption ink, the two gold washes, the on-gold ink, the plinth
   triplet, the two scrims, the four shadows, the two extra golds, --tm-pct,
   and the --tm-s and --tm-r scales (the same concepts as --space and --radius
   but a different px-based scale, so aliasing them would silently restyle the
   design). They take the --tm- prefix because that is this repo's convention
   for a scoped visual layer: --lg-* is the liquid-glass layer, --cm-* is the
   funnel layer, --tm-* is this one.

   3. CLASS NAMES ARE NAMESPACED
   -----------------------------
   The design's class names are short and generic (.tile, .card, .btn, .badge,
   .search, .nav, .step, .help), and css/styles.css already owns .btn, .card
   and .nav. Every ported component is prefixed .tm-* on the way in. NOT scoped
   under a wrapper selector, because that raises specificity on every rule and
   makes the dark overrides harder to reason about, which is the shape of the
   dev-UX-1 A defect.

   4. POLARITY
   -----------
   Light-first with a prefers-color-scheme dark override, which is what BOTH
   css/styles.css and css/liquid-glass.css already do and what the design does.
   Nothing is inverted. The design's html[data-tm-scheme] forced-scheme blocks
   are review-dock machinery and are NOT ported: they would be a third copy of
   every token declaration.
   ========================================================================== */

:root {
  /* --- Aliases onto css/styles.css (loaded by every page) --- */
  --tm-gold: var(--color-gold);
  --tm-gold-hover: var(--color-gold-hover);
  --tm-slate: var(--color-slate);
  --tm-champagne: var(--color-champagne);
  --tm-charcoal: var(--color-charcoal);
  /* dev-TMV4-6: --tm-warm-gray is deleted. It aliased the token that is now
     gone, and nothing in this sheet or any page ever used it. */
  --tm-font: var(--font-primary);
  --tm-w-regular: var(--weight-regular);
  --tm-w-medium: var(--weight-medium);
  --tm-w-semibold: var(--weight-semibold);
  --tm-w-bold: var(--weight-bold);
  --tm-w-extrabold: var(--weight-extrabold);
  --tm-bg: var(--bg-primary);
  --tm-text: var(--text-primary);
  --tm-text-2: var(--text-secondary);
  --tm-muted: var(--text-muted-readable);
  --tm-edge: var(--border-color);

  /* --- Aliases onto css/liquid-glass.css, with same-value fallbacks --- */
  --tm-fast: var(--lg-dur-fast, 160ms);
  --tm-base: var(--lg-dur-base, 280ms);
  --tm-slow: var(--lg-dur-slow, 550ms);
  --tm-beat: var(--lg-dur-beat, 700ms);
  --tm-ease-out: var(--lg-ease-out, cubic-bezier(0.22, 0.61, 0.36, 1));
  --tm-ease-enter: var(--lg-ease-enter, cubic-bezier(0.2, 0.8, 0.3, 1.18));
  --tm-gold-ink: var(--cm-gold-text, #554129);

  /* --- Genuinely new: no existing owner --- */
  --tm-gold-lift: #CBA87C;
  --tm-gold-deep: #8E6F49;
  --tm-surface: #FFFFFF;
  --tm-surface-2: #FBF8F3;
  --tm-surface-sunk: #F1EADE;
  --tm-edge-strong: #D6CCBC;
  --tm-hi: rgba(255, 255, 255, .9);
  --tm-caption: #564F44;
  --tm-gold-wash: rgba(184, 149, 107, .12);
  --tm-gold-wash-2: rgba(184, 149, 107, .06);
  /* The OPAQUE selected-chip surface. A translucent wash composites onto
     whatever is behind it, and on the funnel's gradient page that measured
     4.40:1 for --tm-gold-ink, under the 4.5 AA floor. Opaque, so the rule
     owns its own contrast: 6.5:1 light, 6.7:1 dark. */
  --tm-gold-chip: #F6EEE3;
  --tm-on-gold: #20170C;
  --tm-plate: linear-gradient(150deg, #C2B49B, #A89878);
  --tm-plate-lit: linear-gradient(150deg, #D9B98C, #B8956B 55%, #8E6F49);
  --tm-shadow-sm: 0 1px 2px rgba(30, 41, 59, .06);
  --tm-shadow-md: 0 6px 16px -8px rgba(30, 41, 59, .18);
  --tm-shadow-lg: 0 18px 44px -22px rgba(30, 41, 59, .28);
  --tm-shadow-gold: 0 10px 30px -14px rgba(184, 149, 107, .55);
  --tm-plinth: 245, 239, 230;
  --tm-pct: 0%;

  --tm-s1: 4px; --tm-s2: 8px; --tm-s3: 12px; --tm-s4: 16px; --tm-s5: 20px;
  --tm-s6: 24px; --tm-s7: 32px; --tm-s8: 40px; --tm-s9: 56px; --tm-s10: 72px;
  --tm-r-sm: 8px; --tm-r-md: 12px; --tm-r-lg: 16px; --tm-r-xl: 20px;
  --tm-r-2xl: 24px; --tm-r-full: 999px;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* The aliases above already follow their owners into dark, because both
       css/styles.css and css/liquid-glass.css override the owner inside their
       own dark blocks. Only the tokens declared here need a dark half, plus
       the --cm-gold-text fallback, which has to carry that file's dark value
       for the one page (index.html) that does not load it. */
    --tm-gold-ink: var(--cm-gold-text, #E8D4B5);
    --tm-surface: #1B2536;
    --tm-surface-2: #222E42;
    --tm-surface-sunk: #111925;
    --tm-edge-strong: rgba(245, 239, 230, .20);
    --tm-hi: rgba(245, 239, 230, .07);
    --tm-caption: #B0B7C3;
    --tm-gold-wash: rgba(184, 149, 107, .14);
    --tm-gold-wash-2: rgba(184, 149, 107, .04);
    --tm-gold-chip: #2A3145;
    --tm-plate: linear-gradient(150deg, #707E99, #606E88);
    --tm-shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    --tm-shadow-md: 0 8px 22px -12px rgba(0, 0, 0, .7);
    --tm-shadow-lg: 0 26px 60px -28px rgba(0, 0, 0, .85);
    --tm-shadow-gold: 0 12px 34px -14px rgba(184, 149, 107, .5);
    --tm-plinth: 20, 28, 41;
  }
}

/* ==========================================================================
   TILES. The die-cut plate.
   Each tile is a metal plate with the answer punched out of it. The knockout
   is one even-odd SVG path filled with the tile surface colour, so the hole
   shows whatever is behind: cold metal at rest, brushed gold when chosen.
   ========================================================================== */
.tm-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tm-tiles.tm-three { grid-template-columns: repeat(3, 1fr); }
.tm-tile {
  position: relative; isolation: isolate; overflow: hidden;
  background: var(--tm-surface); border: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-xl); padding: 0; color: var(--tm-text);
  min-height: 118px; display: flex; flex-direction: column;
  box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-md);
  transition: transform var(--tm-fast) var(--tm-ease-out),
              border-color var(--tm-fast) var(--tm-ease-out),
              box-shadow var(--tm-base) var(--tm-ease-out);
}
.tm-tiles.tm-three .tm-tile { min-height: 112px; }
.tm-tile > span.tm-tile-plate {
  position: relative; display: block; height: 72px; flex: 0 0 auto; overflow: hidden;
  background: var(--tm-plate); background-size: cover; background-position: center;
  transition: background-color var(--tm-base) var(--tm-ease-out);
}
.tm-tiles.tm-three .tm-tile > span.tm-tile-plate { height: 66px; }
.tm-tile.tm-on .tm-tile-plate {
  background-color: var(--tm-gold); background-image: var(--tm-plate-lit);
  background-size: cover; background-position: center;
}
@media (prefers-color-scheme: dark) {
  /* The design inlined images/NAH_key_material_brushed.webp here as base64 so
     the mock opened from disk. In production it is an ordinary path. */
  .tm-tile.tm-on .tm-tile-plate {
    background-color: var(--tm-gold);
    background-image: url('/images/NAH_key_material_brushed.webp');
    background-size: cover; background-position: center;
  }
}
/* The knockout. currentColor is the tile surface, so the hole is the card. */
.tm-tile svg.tm-ic {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  color: var(--tm-surface);
}
/* One raking light pass across the plate on selection. */
.tm-tile-plate::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  transform: translateX(-101%);
  background: linear-gradient(105deg, transparent 32%, rgba(245, 239, 230, .42) 50%, transparent 68%);
}
.tm-tile.tm-on .tm-tile-plate::after { animation: tmSweep var(--tm-beat) var(--tm-ease-out) 1; }
@keyframes tmSweep { from { transform: translateX(-101%); } to { transform: translateX(101%); } }
.tm-tile > span:not(.tm-tile-plate) {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 0 var(--tm-s2); font-size: 13.5px; font-weight: var(--tm-w-extrabold);
  line-height: 1.15; letter-spacing: -.012em; text-align: center; color: var(--tm-text);
  transition: color var(--tm-base) var(--tm-ease-out);
}
.tm-tile:hover { transform: translateY(-3px); border-color: rgba(184, 149, 107, .5); }
.tm-tile:active { transform: scale(.975); }
.tm-tile.tm-on { border-color: var(--tm-gold); box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-gold); }
.tm-tile.tm-on span { color: var(--tm-gold-ink); }

/* ==========================================================================
   HERO QUESTION (index.html). The photo layer, its markup, its ids, its
   script and the "Listed by" attribution are UNTOUCHABLE (CLAUDE.md Section
   17, dev-TMV2-1). Everything here composites OVER it and nothing below
   selects .hero-bg, .hero-slides, .hero-overlay or .hero-slide-caption.
   ========================================================================== */
.tm-hero-eyebrow {
  display: block; font-size: 10.5px; font-weight: var(--tm-w-bold);
  /* dev-TMV5-1: --tm-gold-lift is a GRADIENT stop and was never a text colour;
     as text on the slate hero it measured 6.57:1. The hero ground is fixed dark
     in BOTH schemes, so this takes the FIXED dark half of the gold-text value
     rather than the token, which flips and would paint brown on slate. */
  letter-spacing: .22em; text-transform: uppercase; color: #E8D4B5;
  margin-bottom: var(--tm-s4);
}
/* dev-TMV2-2: the horizontal margin was 0, so the 640px tile block pinned LEFT
   inside .hero-content, which is max-width 800px and text-align center
   (css/styles.css:1073). Above 640px viewport the headline was centred and the
   tiles were not. `auto` is the same treatment .tm-picker below already
   carries; the harness measures the two gutters equal within 1px at 390, 768,
   1280 and 1920. */
.tm-hero-tiles { max-width: 640px; margin: var(--tm-s6) auto var(--tm-s5); }
.tm-hero-note {
  display: block; font-size: 13px; font-weight: var(--tm-w-medium);
  color: rgba(245, 239, 230, .82); letter-spacing: .005em; margin: 0;
}
.tm-hero-note b { color: #FFFFFF; font-weight: var(--tm-w-bold); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   PICKER (tenantmatch-v2.html)
   ========================================================================== */
.tm-picker { max-width: 600px; margin: 0 auto; padding: var(--tm-s6) 22px var(--tm-s9); }
.tm-step { display: none; }
.tm-step.tm-on { display: block; animation: tmStep var(--tm-slow) var(--tm-ease-out); }
@keyframes tmStep { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.tm-qn {
  display: block; font-size: 10.5px; font-weight: var(--tm-w-bold);
  letter-spacing: .22em; text-transform: uppercase; color: var(--tm-gold-ink);
  margin-bottom: var(--tm-s3);
}
.tm-picker h2 {
  font-size: clamp(1.8rem, 7.6vw, 2.4rem); font-weight: var(--tm-w-extrabold);
  letter-spacing: -.028em; line-height: 1.05; margin: 0 0 var(--tm-s3); color: var(--tm-text);
}
.tm-help {
  font-size: 15.5px; font-weight: var(--tm-w-regular); line-height: 1.6;
  color: var(--tm-muted); margin: 0 0 var(--tm-s7);
}

/* Progress: option A, Segments. Options B (Dial) and C (Tumblers) are
   dropped, markup and CSS. The segment count is NOT hardcoded: the page sets
   --tm-seg from the step count so the grid, the markup and aria-valuemax
   cannot drift apart (recon F4 note 2). */
.tm-rail { position: relative; display: flex; align-items: center; gap: var(--tm-s4); margin: 0 0 var(--tm-s7); min-height: 26px; }
.tm-prog { display: flex; flex: 1; align-items: center; gap: var(--tm-s4); }
.tm-prog-segments { position: relative; height: 6px; }
.tm-seg-row { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(var(--tm-seg, 7), 1fr); gap: 5px; }
.tm-seg-row i { display: block; border-radius: var(--tm-r-full); background: var(--tm-edge-strong); }
.tm-seg-row.tm-is-fill {
  clip-path: inset(0 calc(100% - var(--tm-pct)) 0 0);
  transition: clip-path var(--tm-slow) var(--tm-ease-out);
}
.tm-seg-row.tm-is-fill i {
  background: linear-gradient(90deg, var(--tm-gold-deep), var(--tm-gold), var(--tm-gold-lift));
  box-shadow: 0 0 12px -2px rgba(184, 149, 107, .6);
}

/* Budget step */
.tm-amt { text-align: center; margin-bottom: var(--tm-s1); }
.tm-amt-val {
  font-size: clamp(3rem, 15vw, 4.4rem); font-weight: var(--tm-w-extrabold);
  color: var(--tm-gold-ink); letter-spacing: -.05em; line-height: 1; background: none;
  border: none; text-align: center; width: 100%; padding: 0; font-variant-numeric: tabular-nums;
}
.tm-amt-val:focus { outline: none; color: var(--tm-gold); }
.tm-amt-unit {
  font-size: 11px; font-weight: var(--tm-w-bold); letter-spacing: .18em;
  text-transform: uppercase; color: var(--tm-caption); margin-top: var(--tm-s2);
}
.tm-count {
  text-align: center; font-size: 14px; font-weight: var(--tm-w-regular);
  color: var(--tm-muted); margin: var(--tm-s4) 0 var(--tm-s6); min-height: 22px;
}
.tm-count b { color: var(--tm-text); font-weight: var(--tm-w-bold); }
.tm-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 44px; background: transparent; margin: 0; }
.tm-slider::-webkit-slider-runnable-track {
  height: 6px; border-radius: var(--tm-r-full);
  background: linear-gradient(90deg, var(--tm-gold) 0%, var(--tm-gold) var(--tm-thumb-pct, 50%),
    var(--tm-edge-strong) var(--tm-thumb-pct, 50%), var(--tm-edge-strong) 100%);
}
.tm-slider::-moz-range-track { height: 6px; border-radius: var(--tm-r-full); background: var(--tm-edge-strong); }
.tm-slider::-moz-range-progress { height: 6px; border-radius: var(--tm-r-full); background: var(--tm-gold); }
.tm-slider::-webkit-slider-thumb {
  -webkit-appearance: none; width: 32px; height: 32px; border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #fff, var(--tm-champagne) 62%, #E3D9C9);
  border: 3px solid var(--tm-gold); margin-top: -13px; cursor: grab;
  box-shadow: 0 4px 14px -3px rgba(0, 0, 0, .45);
}
.tm-slider::-moz-range-thumb {
  width: 32px; height: 32px; border-radius: 50%; background: var(--tm-champagne);
  border: 3px solid var(--tm-gold); cursor: grab;
}
.tm-slider:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.06); }
.tm-ticks {
  display: flex; justify-content: space-between; font-size: 11px; font-weight: var(--tm-w-semibold);
  letter-spacing: .02em; color: var(--tm-caption); margin-bottom: var(--tm-s6);
}
.tm-buckets { display: flex; gap: var(--tm-s2); flex-wrap: wrap; justify-content: center; margin-bottom: var(--tm-s6); }
.tm-bkt {
  background: var(--tm-surface); border: 1px solid var(--tm-edge); border-radius: var(--tm-r-full);
  padding: 10px 16px; font-size: 13px; font-weight: var(--tm-w-semibold); color: var(--tm-muted);
  min-height: 44px; box-shadow: var(--tm-shadow-sm); cursor: pointer;
  transition: border-color var(--tm-fast) var(--tm-ease-out),
              color var(--tm-fast) var(--tm-ease-out),
              background-color var(--tm-fast) var(--tm-ease-out);
}
.tm-bkt:hover { border-color: rgba(184, 149, 107, .5); color: var(--tm-text); }
.tm-bkt.tm-on { border-color: var(--tm-gold); color: var(--tm-gold-ink); background: var(--tm-gold-chip); }

/* City typeahead */
.tm-search { position: relative; margin-bottom: var(--tm-s4); }
.tm-search > svg {
  position: absolute; left: 16px; top: 50%; margin-top: -9px; width: 18px; height: 18px; fill: none;
  stroke: var(--tm-caption); stroke-width: 1.7; stroke-linecap: round; pointer-events: none;
  transition: stroke var(--tm-fast) var(--tm-ease-out);
}
.tm-search input {
  width: 100%; background: var(--tm-surface); border: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-lg); padding: 16px 16px 16px 46px; color: var(--tm-text);
  font-size: 16px; font-weight: var(--tm-w-medium); min-height: 56px;
  box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-sm);
  transition: border-color var(--tm-fast) var(--tm-ease-out), box-shadow var(--tm-fast) var(--tm-ease-out);
}
.tm-search input:focus {
  outline: none; border-color: var(--tm-gold);
  box-shadow: inset 0 1px 0 var(--tm-hi), 0 0 0 4px var(--tm-gold-wash);
}
.tm-search:focus-within > svg { stroke: var(--tm-gold); }
.tm-search input::placeholder { color: var(--tm-caption); font-weight: var(--tm-w-regular); }
.tm-sugg {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; background: var(--tm-surface);
  border: 1px solid var(--tm-edge-strong); border-radius: var(--tm-r-lg); overflow: hidden;
  z-index: 20; max-height: 264px; overflow-y: auto; display: none; box-shadow: var(--tm-shadow-lg);
}
.tm-sugg.tm-on { display: block; animation: tmPop var(--tm-fast) var(--tm-ease-enter); }
@keyframes tmPop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.tm-sugg button {
  display: flex; justify-content: space-between; align-items: center; gap: var(--tm-s3); width: 100%;
  background: none; border: none; color: var(--tm-text); text-align: left; padding: 14px 16px;
  font-size: 15px; font-weight: var(--tm-w-semibold); min-height: 48px; cursor: pointer;
  border-bottom: 1px solid var(--tm-edge);
  transition: background-color var(--tm-fast) var(--tm-ease-out);
}
.tm-sugg button:last-child { border-bottom: none; }
.tm-sugg button:hover, .tm-sugg button.tm-cur { background: var(--tm-gold-wash); }
.tm-sugg small {
  color: var(--tm-caption); font-size: 11px; font-weight: var(--tm-w-bold);
  letter-spacing: .08em; text-transform: uppercase; flex: 0 0 auto;
}
.tm-sugg .tm-none { padding: 16px; font-size: 14px; color: var(--tm-muted); }
.tm-picked { display: flex; flex-wrap: wrap; gap: var(--tm-s2); margin-bottom: var(--tm-s4); min-height: 4px; }
.tm-pchip {
  display: inline-flex; align-items: center; gap: var(--tm-s2); background: var(--tm-gold-chip);
  border: 1px solid var(--tm-gold); border-radius: var(--tm-r-full); padding: 8px 8px 8px 15px;
  font-size: 13.5px; font-weight: var(--tm-w-semibold); color: var(--tm-gold-ink); min-height: 44px;
  animation: tmChip var(--tm-base) var(--tm-ease-enter);
}
@keyframes tmChip { from { opacity: 0; transform: translateY(5px) scale(.94); } to { opacity: 1; transform: none; } }
.tm-pchip button {
  position: relative; background: none; border: none; color: var(--tm-gold-ink);
  width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; padding: 0; cursor: pointer;
  transition: background-color var(--tm-fast) var(--tm-ease-out);
}
.tm-pchip button::after { content: ''; position: absolute; inset: -8px; }
.tm-pchip button:hover { background: rgba(184, 149, 107, .28); }
.tm-pchip svg { width: 11px; height: 11px; stroke: currentColor; stroke-width: 2.6; fill: none; stroke-linecap: round; }
.tm-anywhere {
  width: 100%; background: none; border: 1px dashed var(--tm-edge-strong); border-radius: var(--tm-r-lg);
  padding: 15px; color: var(--tm-muted); font-size: 14px; font-weight: var(--tm-w-semibold);
  min-height: 52px; cursor: pointer;
  transition: border-color var(--tm-fast) var(--tm-ease-out),
              color var(--tm-fast) var(--tm-ease-out),
              background-color var(--tm-fast) var(--tm-ease-out);
}
.tm-anywhere:hover { border-color: rgba(184, 149, 107, .55); color: var(--tm-text); }
.tm-anywhere.tm-on { border-style: solid; border-color: var(--tm-gold); color: var(--tm-gold-ink); background: var(--tm-gold-chip); }

/* Free-text step */
.tm-ta {
  width: 100%; background: var(--tm-surface); border: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-lg); padding: var(--tm-s4); color: var(--tm-text); font-size: 16px;
  font-family: inherit; font-weight: var(--tm-w-regular); line-height: 1.6; min-height: 150px;
  resize: vertical; box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-sm);
  transition: border-color var(--tm-fast) var(--tm-ease-out), box-shadow var(--tm-fast) var(--tm-ease-out);
}
.tm-ta:focus { outline: none; border-color: var(--tm-gold); box-shadow: inset 0 1px 0 var(--tm-hi), 0 0 0 4px var(--tm-gold-wash); }
.tm-ta::placeholder { color: var(--tm-caption); }
.tm-examples { margin: var(--tm-s4) 0 0; padding: 0; list-style: none; }
.tm-examples li {
  font-size: 13.5px; font-weight: var(--tm-w-regular); line-height: 1.55;
  color: var(--tm-caption); padding: 6px 0 6px 16px; position: relative;
}
.tm-examples li::before { content: ''; position: absolute; left: 0; top: 15px; width: 6px; height: 6px; border-radius: 50%; background: var(--tm-gold); opacity: .55; }

/* Buttons */
.tm-nav { display: flex; gap: var(--tm-s3); padding-top: var(--tm-s6); padding-bottom: max(0px, env(safe-area-inset-bottom)); }
.tm-btn {
  flex: 1; position: relative; overflow: hidden; cursor: pointer;
  background: linear-gradient(168deg, var(--tm-gold-lift), var(--tm-gold) 55%, var(--tm-gold-deep));
  color: var(--tm-on-gold); border: none; border-radius: var(--tm-r-md); padding: 17px;
  font-family: inherit; font-size: 16px; font-weight: var(--tm-w-bold); letter-spacing: -.005em;
  min-height: 56px; box-shadow: var(--tm-shadow-gold);
  transition: transform var(--tm-fast) var(--tm-ease-out),
              box-shadow var(--tm-base) var(--tm-ease-out),
              filter var(--tm-fast) var(--tm-ease-out);
}
.tm-btn:hover { filter: brightness(1.06); box-shadow: 0 14px 38px -14px rgba(184, 149, 107, .7); }
.tm-btn:active { transform: scale(.985); }
.tm-btn[disabled] { filter: none; background: var(--tm-edge-strong); color: var(--tm-caption); box-shadow: none; cursor: not-allowed; }
.tm-btn.tm-ghost {
  background: none; color: var(--tm-muted); border: 1px solid var(--tm-edge-strong);
  font-weight: var(--tm-w-semibold); flex: 0 0 auto; padding: 17px 24px; box-shadow: none;
}
.tm-btn.tm-ghost:hover { color: var(--tm-text); border-color: rgba(184, 149, 107, .5); filter: none; }

.tm-error {
  display: none; margin-top: var(--tm-s4); padding: 14px 16px; border-radius: var(--tm-r-md);
  border: 1px solid rgba(185, 28, 28, .35); background: rgba(185, 28, 28, .07);
  color: var(--tm-text); font-size: 14px; line-height: 1.55;
}
.tm-error.tm-on { display: block; }

/* Focus visibility, matching the house ring. */
.tm-tile:focus-visible, .tm-btn:focus-visible, .tm-bkt:focus-visible,
.tm-anywhere:focus-visible, .tm-search input:focus-visible, .tm-ta:focus-visible,
.tm-sugg button:focus-visible, .tm-amt-val:focus-visible {
  outline: 2px solid var(--tm-gold); outline-offset: 3px; border-radius: var(--tm-r-sm);
}

@media (max-width: 420px) {
  .tm-tiles.tm-three { grid-template-columns: repeat(2, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .tm-step.tm-on, .tm-sugg.tm-on, .tm-pchip { animation: none; }
  .tm-tile-plate::after, .tm-tile.tm-on .tm-tile-plate::after { animation: none; display: none; }
  .tm-seg-row.tm-is-fill { transition: none; }
  .tm-tile, .tm-btn, .tm-bkt, .tm-anywhere, .tm-search input, .tm-ta { transition: none; }
  .tm-tile:hover { transform: none; }
}

/* ==========================================================================
   THE DOSSIER CARD AND THE SEALED MATCH REPORT (dev-TMV2-2)
   conciergematch-results.html. Ported from docs/design/tmv2 spec sections 9
   and 10, namespaced .tm-* on the way in because the design's own names
   (.card, .ph, .cb, .addr, .rent, .meta, .why, .report, .badge) collide with
   css/styles.css.

   WHAT DID NOT PORT, and why: the inlined base64 webp brushed plate (the seal
   and the verdict numeral use --tm-plate-lit, the gradient the spec itself
   names as the light-scheme treatment and the dark fallback layer), the
   .tm-review scheme dock, the html[data-tm-scheme] blocks that serve it, and
   the dev-note bar. All four are mock-only by the design's own note.

   The card is a document, not an app card: photo band, address block, a
   perforated tear, then the insert. What is withheld is the SEAL, not the
   words: .tm-locked carries no blur, because a blurred line is a CSS hide and
   this build gates server-side (dev-B2b-2b-b). The five teaser lines are real
   COUNTS of what is inside; not one of the lines themselves is in this DOM.
   ========================================================================== */
:root {
  /* The one colour the ported components need that had no owner. A 2px rule on
     the why-line only; never text, so no contrast floor applies. */
  --tm-open: #7FB08D;
  /* The cinematic beat, aliased onto its existing owner exactly as the other
     four durations above are (dev-0.32.0 owns --lg-dur-cine). */
  --tm-cine: var(--lg-dur-cine, 1300ms);
}

/* The design's payoff numeral (.verdict .big, a 0-to-6 count-up) is NOT ported,
   and its rules are deliberately absent rather than left here unused. This page
   already owns that moment: #cm-resolve / .cm-resolve-count is the same count-up
   on the same cine token, and it is pinned by dev0280, dev0320 and smoke. A
   second numeral would be a second owner of one moment, which is the defect
   --cm-gold-text was created to end. The ruled line below IS ported, because
   nothing here owned it. */
.tm-ruled {
  position: relative; text-align: center; font-size: 14.5px; font-weight: var(--tm-w-regular);
  line-height: 1.6; color: var(--tm-muted); max-width: 44ch; margin: 0 auto var(--tm-s8);
  padding-top: var(--tm-s5);
}
.tm-ruled::before {
  content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 56px; height: 1px; background: linear-gradient(90deg, transparent, var(--tm-gold), transparent);
}
.tm-ruled b { color: var(--tm-text); font-weight: var(--tm-w-bold); font-variant-numeric: tabular-nums; }

.tm-dossier {
  position: relative; background: var(--tm-surface); border: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-2xl); margin-bottom: var(--tm-s5);
  box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-lg);
}
.tm-ph {
  position: relative; height: 196px; overflow: hidden;
  border-bottom: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-2xl) var(--tm-r-2xl) 0 0;
  background: radial-gradient(120% 90% at 50% 0%, var(--tm-gold-wash-2), transparent 70%),
    linear-gradient(158deg, var(--tm-surface-sunk), var(--tm-surface-2));
}
/* NO filter, NO crop treatment, NO colour grade: Stellar MLS prohibits altering
   listing media (CLAUDE.md 16.6). Cover framing only. */
.tm-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tm-badge {
  position: absolute; top: 14px; left: 14px; z-index: 2; text-align: center;
  background: var(--tm-surface); border: 1px solid var(--tm-gold); border-radius: var(--tm-r-md);
  padding: 8px 13px; box-shadow: var(--tm-shadow-md);
}
.tm-badge b {
  display: block; font-size: 23px; font-weight: var(--tm-w-extrabold); color: var(--tm-gold-ink);
  line-height: 1; letter-spacing: -.035em; font-variant-numeric: tabular-nums;
}
.tm-badge span {
  display: block; font-size: 8px; font-weight: var(--tm-w-bold); letter-spacing: .16em;
  text-transform: uppercase; color: var(--tm-caption); margin-top: 3px;
}
.tm-flag {
  position: absolute; top: 14px; right: 14px; z-index: 2; font-size: 9.5px;
  font-weight: var(--tm-w-bold); letter-spacing: .14em; text-transform: uppercase;
  color: var(--tm-on-gold); background: var(--tm-gold); border-radius: var(--tm-r-full);
  padding: 5px 10px;
}
.tm-cb { padding: var(--tm-s5); }
.tm-addr {
  font-size: 21px; font-weight: var(--tm-w-extrabold); line-height: 1.18; letter-spacing: -.025em;
  margin: 0 0 var(--tm-s1); color: var(--tm-text);
}
.tm-rent {
  font-size: 16px; font-weight: var(--tm-w-bold); color: var(--tm-gold-ink);
  letter-spacing: -.01em; margin-bottom: var(--tm-s1); font-variant-numeric: tabular-nums;
}
.tm-meta { font-size: 13px; font-weight: var(--tm-w-medium); color: var(--tm-caption); margin-bottom: var(--tm-s4); }
.tm-why {
  font-size: 14.5px; font-weight: var(--tm-w-regular); line-height: 1.55;
  border-left: 2px solid var(--tm-open); padding-left: var(--tm-s4); margin: 0 0 var(--tm-s5);
  color: var(--tm-text-2);
}

/* The insert. .tm-report must NOT carry overflow:hidden or the tear is clipped. */
.tm-report {
  position: relative; margin: var(--tm-s7) 0 var(--tm-s5);
  padding: var(--tm-s6) var(--tm-s5) var(--tm-s5);
  border: 1px solid rgba(184, 149, 107, .5); border-radius: var(--tm-r-xl);
  background: linear-gradient(165deg, var(--tm-gold-wash), var(--tm-gold-wash-2) 65%), var(--tm-surface-2);
  box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-md);
}
/* The perforation, edge to edge past the card padding. */
.tm-report::before {
  content: ''; position: absolute; left: calc(-1 * var(--tm-s5) - 1px); right: calc(-1 * var(--tm-s5) - 1px);
  top: -25px; height: 2px; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(184, 149, 107, .85) 0 6px, transparent 6px 13px);
}
.tm-report::after {
  content: ''; position: absolute; right: -32px; top: -32px; width: 150px; height: 150px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 36% 32%, rgba(203, 168, 124, .34), rgba(184, 149, 107, .10) 58%, transparent 74%);
}
.tm-seal {
  position: absolute; right: var(--tm-s3); top: var(--tm-s3); z-index: 2; width: 64px; height: 64px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center; pointer-events: none;
  background-color: var(--tm-gold); background-image: var(--tm-plate-lit);
  background-size: cover; background-position: center;
  box-shadow: inset 0 0 0 1px rgba(245, 239, 230, .3), inset 0 -3px 8px rgba(0, 0, 0, .4),
              0 8px 20px -8px rgba(0, 0, 0, .55);
}
.tm-seal svg { width: 46px; height: 27px; display: block; filter: drop-shadow(0 1px 0 rgba(245, 239, 230, .42)); }
.tm-seal svg path { fill: var(--tm-on-gold); }
/* dev-TMV3-1: the seal now carries the REAL NAH key vector rather than a
   hand-drawn generic one. Both brand SVGs bake their fill into the path
   (#B8956B gold, #1E293B slate) instead of using currentColor, so the gold file
   on a gold plate would be invisible. Base layer: the SLATE asset as a flat
   img, which reads correctly on the gold plate on its own and is what a client
   without mask support gets. Enhanced layer: the same geometry as a CSS MASK
   over the knockout colour, which is the treatment the placeholder had, and is
   the standing dev-0.32.0 technique (CLAUDE.md 15). Aspect is 130/76 = 1.714,
   identical to the retired 24/14 viewBox, so nothing re-lays-out. */
.tm-seal-flat { width: 46px; height: 27px; display: block; object-fit: contain; filter: drop-shadow(0 1px 0 rgba(245, 239, 230, .42)); }
.tm-seal-key { display: none; }
@supports ((-webkit-mask-repeat: no-repeat) or (mask-repeat: no-repeat)) {
  .tm-seal-flat { display: none; }
  .tm-seal-key {
    display: block; width: 46px; height: 27px;
    background-color: var(--tm-on-gold);
    filter: drop-shadow(0 1px 0 rgba(245, 239, 230, .42));
    -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;
  }
}
.tm-rh { display: flex; align-items: center; gap: var(--tm-s2); margin-bottom: var(--tm-s4); position: relative; z-index: 1; }
.tm-rh svg {
  width: 16px; height: 16px; fill: none; stroke: var(--tm-gold-ink); stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round; flex: 0 0 auto;
}
.tm-rh b { font-size: 10.5px; font-weight: var(--tm-w-bold); letter-spacing: .2em; text-transform: uppercase; color: var(--tm-gold-ink); }
/* Legible, receding into the depth of the insert. Never a blur. */
.tm-locked { position: relative; z-index: 1; opacity: 1; user-select: none; max-width: 80%; padding-bottom: var(--tm-s2); }
.tm-rl { font-size: 13.5px; font-weight: var(--tm-w-medium); line-height: 1.45; padding: 6px 0; color: var(--tm-text-2); }
.tm-rl:nth-child(3) { opacity: .74; }
.tm-rl:nth-child(4) { opacity: .52; }
.tm-rl:nth-child(5) { opacity: .34; }

/* The OPENED report, for a renter with an active term. Same insert, no seal. */
.tm-report.tm-open { background: var(--tm-surface-2); }
.tm-rsec { position: relative; z-index: 1; margin-bottom: var(--tm-s5); }
.tm-rsec:last-child { margin-bottom: 0; }
.tm-rsec h4 {
  font-size: 10.5px; font-weight: var(--tm-w-bold); letter-spacing: .2em; text-transform: uppercase;
  color: var(--tm-gold-ink); margin: 0 0 var(--tm-s3);
}
.tm-rsec ul { list-style: none; margin: 0; padding: 0; }
.tm-rsec li { font-size: 14px; font-weight: var(--tm-w-regular); line-height: 1.5; padding: 5px 0; color: var(--tm-text-2); }
.tm-rsec .tm-num { font-variant-numeric: tabular-nums; font-weight: var(--tm-w-bold); color: var(--tm-text); }
/* dev-TMV5-3: minmax(0, 1fr), AND THIS IS THE HALF THAT ACTUALLY HOLDS THE
   CARD IN. A grid item's `min-width` computes to `auto`, so `.tm-alt` carried
   its own min-content width up the chain and the whole row grew to fit the
   longest street rather than clipping it. Measured on an isolated probe of this
   exact markup with a 33-character street: the card rendered 398px wide inside a
   382px container, spilling 37px, and it did so IDENTICALLY with and without the
   `.tm-alt-t` display fix, because a block that is allowed to be as wide as it
   likes never reaches its ellipsis. This is the same defect conciergematch-
   results.html already documents on `.cm-tier2-content` and fixes the same way. */
.tm-alts { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tm-s3); }
.tm-alt { min-width: 0; }
.tm-alt {
  display: flex; gap: var(--tm-s3); align-items: center; text-decoration: none; color: inherit;
  border: 1px solid var(--tm-edge); border-radius: var(--tm-r-lg); padding: var(--tm-s2); background: var(--tm-surface);
}
.tm-alt img { width: 72px; height: 56px; object-fit: cover; border-radius: var(--tm-r-md); flex: 0 0 auto; }
/* dev-TMV5-3: THE ELLIPSIS NEVER FIRED, AND THE REASON IS THAT IT WAS ON AN
   INLINE BOX. `.tm-alt-t` is a <span>, so it was `display: inline` by default,
   and `overflow`, `text-overflow` and `white-space` have no effect on an inline
   box: the text simply ran on past the card. Making these blocks is what makes
   the truncation the rule already asked for actually happen, and `flex: 1 1 auto`
   with `min-width: 0` is what lets the flex item shrink below its content width
   in the first place (a flex item's default `min-width: auto` is the other half
   of this defect and is why the row pushed wide instead of clipping).

   THE THREE LINES ARE TREATED DIFFERENTLY ON PURPOSE. A street and a stat line
   are identifiers and truncate to one line. The BEAT line is a real statement
   about why this home is here, so it wraps rather than being cut off mid-reason,
   and `overflow-wrap: anywhere` keeps a long unbroken token inside the card. */
.tm-alt-b { min-width: 0; flex: 1 1 auto; }
.tm-alt-t { display: block; font-size: 14px; font-weight: var(--tm-w-bold); color: var(--tm-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tm-alt-m { display: block; font-size: 12.5px; color: var(--tm-caption); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* dev-TMV5-2: WHY this alternative is here. It is the whole reason the card
   qualified (server.js findAlternatives admits nothing that does not beat the
   one above it on something the renter stated), so it is weighted as a real
   statement rather than as a caption, and it takes --tm-gold-ink, which is the
   readable gold token, never raw Refined Gold (CLAUDE.md 1.5 rule 2). */
.tm-alt-w { display: block; margin-top: 2px; font-size: 12.5px; font-weight: var(--tm-w-bold); color: var(--tm-gold-ink); overflow-wrap: anywhere; }

.tm-terms {
  font-size: 12px; font-weight: var(--tm-w-regular); color: var(--tm-caption); text-align: center;
  margin: var(--tm-s3) 0 0; line-height: 1.6;
}
.tm-detail {
  display: block; text-align: center; margin-top: var(--tm-s3); font-size: 13.5px;
  font-weight: var(--tm-w-semibold); color: var(--tm-gold-ink);
}
.tm-trust {
  text-align: center; font-size: 12.5px; font-weight: var(--tm-w-regular); color: var(--tm-caption);
  line-height: 1.65; max-width: 44ch; margin: var(--tm-s7) auto 0;
}
.tm-save {
  border: 1px solid var(--tm-edge); border-radius: var(--tm-r-xl); background: var(--tm-surface-2);
  padding: var(--tm-s5); margin: var(--tm-s6) 0 0; text-align: center;
}
.tm-save h3 { margin: 0 0 var(--tm-s2); font-size: 18px; font-weight: var(--tm-w-extrabold); letter-spacing: -.02em; color: var(--tm-text); }
.tm-save p { margin: 0 0 var(--tm-s4); font-size: 14px; line-height: 1.6; color: var(--tm-muted); }
.tm-save-row { display: flex; flex-wrap: wrap; gap: var(--tm-s3); justify-content: center; align-items: center; }
.tm-save-row input[type="email"] {
  flex: 1 1 240px; min-height: 48px; padding: 0 14px; font: inherit; font-size: 16px;
  border: 1px solid var(--tm-edge-strong); border-radius: var(--tm-r-md);
  background: var(--tm-surface); color: var(--tm-text);
}
.tm-save-row input[type="email"]:focus-visible { outline: 2px solid var(--tm-gold); outline-offset: 2px; }
.tm-save-terms { display: flex; gap: 10px; align-items: flex-start; text-align: left; margin-top: var(--tm-s4); font-size: 13px; color: var(--tm-muted); line-height: 1.55; }
.tm-save-terms input { margin-top: 3px; width: 20px; height: 20px; flex: 0 0 auto; }
.tm-save-msg { display: block; margin-top: var(--tm-s3); font-size: 14px; font-weight: var(--tm-w-semibold); }

@media (max-width: 520px) {
  .tm-locked { max-width: 100%; }
  .tm-seal { width: 52px; height: 52px; }
  .tm-seal svg { width: 36px; height: 21px; }
  .tm-seal-flat, .tm-seal-key { width: 36px; height: 21px; }
}

/* dev-TMV2-2: the repo had no visually-hidden utility, and the save-my-matches
   field needs a real <label> rather than a bare aria-label. One class, here,
   rather than a bare placeholder standing in for a label. */
.tm-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ==========================================================================
   dev-TMV3-2: THE THREE NEW PICKER SCREENS, and the free-text step's controls.

   Everything below honours the contracts the picker already keeps: a 44px
   minimum target, a 16px minimum font on any real input (iOS zooms a smaller
   one), both colour schemes through the --tm-* tokens rather than a fresh hex,
   and a reduced-motion answer for every animation.
   ========================================================================== */

/* The optional square-footage sub-question. It sits UNDER the baths tiles on
   the same screen and is visually subordinate to them, because it is the half
   of the question most renters will skip. */
.tm-sub {
  margin-top: var(--tm-s7); padding-top: var(--tm-s6);
  border-top: 1px solid var(--tm-edge);
}
.tm-sub-label {
  display: block; font-size: 14.5px; font-weight: var(--tm-w-semibold);
  color: var(--tm-text-2); margin-bottom: var(--tm-s4);
}
.tm-optional {
  display: block; font-size: 12.5px; font-weight: var(--tm-w-regular);
  color: var(--tm-caption); margin: 2px 0 var(--tm-s4);
}
/* dev-TMV4-1: A FIELD THAT LOOKS LIKE A FIELD. This borrowed .tm-amt from the
   rent screen, where a borderless 4.4rem numeral IS the screen and reads as an
   input because nothing else is competing for the eye. Under a row of bathroom
   tiles the same treatment read as a heading, and the operator's tester did not
   find it. A border, a resting surface and a unit suffix inside the control,
   at 17px so iOS never zooms on focus. The rent control is untouched. */
.tm-field {
  display: flex; align-items: center; gap: var(--tm-s3);
  max-width: 320px; padding: 0 var(--tm-s4);
  background: var(--tm-surface); border: 1.5px solid var(--tm-edge-strong);
  border-radius: var(--tm-r-md); min-height: 56px;
  transition: border-color var(--tm-fast) var(--tm-ease-out),
              box-shadow var(--tm-fast) var(--tm-ease-out);
}
.tm-field:focus-within { border-color: var(--tm-gold); box-shadow: 0 0 0 3px var(--tm-gold-wash); }
.tm-field-val {
  flex: 1 1 auto; min-width: 0; width: 100%;
  background: none; border: none; padding: 0; font: inherit;
  font-size: 17px; font-weight: var(--tm-w-bold); color: var(--tm-text);
  font-variant-numeric: tabular-nums;
}
.tm-field-val:focus { outline: none; }
.tm-field-val::placeholder { color: var(--tm-caption); font-weight: var(--tm-w-regular); }
.tm-field-suffix {
  flex: 0 0 auto; font-size: 13px; font-weight: var(--tm-w-semibold);
  color: var(--tm-caption); white-space: nowrap;
}
/* No longer a "skip": it is the OTHER answer to the same question, so it reads
   and behaves as a selectable chip rather than as navigation. */
.tm-skip-inline {
  display: inline-flex; align-items: center; justify-content: center;
  margin: var(--tm-s4) 0 0; min-height: 44px; padding: 0 var(--tm-s5);
  cursor: pointer; font: inherit; font-size: 14px; font-weight: var(--tm-w-semibold);
  color: var(--tm-text-2); background: var(--tm-surface-2);
  border: 1.5px solid var(--tm-edge); border-radius: var(--tm-r-full);
  transition: color var(--tm-fast) var(--tm-ease-out),
              border-color var(--tm-fast) var(--tm-ease-out),
              background-color var(--tm-fast) var(--tm-ease-out);
}
.tm-skip-inline:hover { border-color: var(--tm-gold); color: var(--tm-gold-ink); }
.tm-skip-inline.tm-on { border-color: var(--tm-gold); background: var(--tm-gold-chip); color: var(--tm-gold-ink); }
.tm-skip-inline:focus-visible { outline: 2px solid var(--tm-gold); outline-offset: 2px; }

/* MULTI-SELECT tiles. .tm-mpick is a separate class from .tm-pick on purpose:
   .tm-pick clears its siblings and auto-advances, which is exactly right for a
   single answer and exactly wrong for a set. The selected treatment is the same
   gold plate, so the two read as one system. */
.tm-mpick.tm-on .tm-tile-plate {
  background-color: var(--tm-gold); background-image: var(--tm-plate-lit);
  background-size: cover; background-position: center;
}
.tm-mpick.tm-on { border-color: var(--tm-gold); box-shadow: inset 0 1px 0 var(--tm-hi), var(--tm-shadow-gold); }
.tm-mpick.tm-on span { color: var(--tm-gold-ink); }
/* A checked corner, so "one of several chosen" is legible without relying on
   the plate alone (the single-select tiles look identical when chosen). */
.tm-mpick.tm-on::after {
  content: ""; position: absolute; top: 8px; right: 8px; width: 18px; height: 18px;
  border-radius: var(--tm-r-full); background: var(--tm-gold);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2320170C' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 12px 12px; background-repeat: no-repeat; background-position: center;
}

/* ---- the free-text step (Phase 6) ---- */
/* The examples are CONTROLS now, not decoration: tapping one fills the box. */
.tm-examples { list-style: none; margin: var(--tm-s5) 0 0; padding: 0; display: grid; gap: var(--tm-s3); }
.tm-ex {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--tm-surface-2); border: 1px solid var(--tm-edge);
  border-radius: var(--tm-r-md); padding: 13px 15px; min-height: 44px;
  font: inherit; font-size: 14.5px; line-height: 1.5; color: var(--tm-text-2);
  transition: border-color var(--tm-fast) var(--tm-ease-out),
              background-color var(--tm-fast) var(--tm-ease-out),
              color var(--tm-fast) var(--tm-ease-out);
}
.tm-ex:hover { border-color: var(--tm-gold); background: var(--tm-gold-wash-2); color: var(--tm-text); }
.tm-ex:focus-visible { outline: 2px solid var(--tm-gold); outline-offset: 2px; }
.tm-ex-hd {
  font-size: 12.5px; font-weight: var(--tm-w-bold); letter-spacing: .02em;
  text-transform: none; color: var(--tm-text-2); margin: var(--tm-s6) 0 0;
}
/* dev-TMV5-1: the five categories. Each group states in one line what we do
   with what the renter writes there, which is where the honesty about scoring
   lives (a category we do not match on says so, in four words). */
/* dev-TMV5-2: the disclosure the five categories now sit behind. A real
   <summary>, so the marker, the keyboard behaviour and the announcement are the
   browser's rather than ours. --tm-gold-ink is the readable gold token
   (CLAUDE.md 1.5 rule 2); raw Refined Gold is never text. */
.tm-exwrap { margin-top: var(--tm-s4); }
.tm-exsum {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  min-height: 44px; padding: 4px 2px; list-style: none;
  font-size: 13.5px; font-weight: var(--tm-w-bold); color: var(--tm-gold-ink);
}
.tm-exsum::-webkit-details-marker { display: none; }
.tm-exsum::before {
  content: ''; width: 7px; height: 7px; flex: 0 0 auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform var(--tm-fast) var(--tm-ease-out);
}
.tm-exwrap[open] .tm-exsum::before { transform: rotate(45deg); }
.tm-exsum:focus-visible { outline: 2px solid var(--tm-gold); outline-offset: 2px; border-radius: var(--tm-r-sm); }
/* dev-TMV5-2: A CLOSED <details> LOSES TO AN AUTHOR display RULE, and this is
   the SAME defect CLAUDE.md 16.2 records from dev-TMV4-2: `[hidden]{display:none}`
   is a USER AGENT rule and `.rep-verified{display:flex}` is an AUTHOR rule, so
   the author rule wins and the attribute does nothing. Chrome hides a closed
   details' children with a UA rule too, and `display: grid` here beat it: the
   disclosure read closed and all eleven examples were still painted. Measured by
   this sprint's own harness at both widths before it shipped. The author rule
   below is what actually closes it. */
.tm-exwrap:not([open]) .tm-exgroups { display: none; }
.tm-exgroups { margin-top: var(--tm-s4); display: grid; gap: var(--tm-s5); }
.tm-exg-t {
  margin: 0; font-size: 14.5px; font-weight: var(--tm-w-bold);
  letter-spacing: -0.005em; color: var(--tm-text);
}
.tm-exg-s { margin: 3px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--tm-text-2); }
.tm-exg .tm-examples { margin-top: var(--tm-s3); }

/* The arrival ghost. The intake precedent (js/dictation.js and the
   conciergematch intake) is followed exactly: the ghost is a SIBLING overlay,
   never the textarea's value, so it can never be submitted, and it is removed
   the instant the field has content or the renter touches a key. */
.tm-ta-wrap { position: relative; }
.tm-tghost {
  position: absolute; inset: 0; padding: 16px 18px; pointer-events: none;
  font: inherit; font-size: 16px; line-height: 1.65; color: var(--tm-caption);
  white-space: pre-wrap; overflow: hidden; border-radius: var(--tm-r-lg);
}
.tm-tghost::after {
  content: ""; display: inline-block; width: 2px; height: 1.05em;
  vertical-align: text-bottom; margin-left: 1px; background: var(--tm-gold);
  animation: tmGhostCaret 1s steps(1) infinite;
}
@keyframes tmGhostCaret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.tm-ta-wrap.tm-typed .tm-tghost { display: none; }

/* The loading state on the primary control. It replaces a button that looked
   dead for the whole parse-plus-match round trip. */
.tm-btn[aria-busy="true"] { cursor: progress; }
.tm-spin {
  display: inline-block; width: 15px; height: 15px; margin-right: 9px;
  vertical-align: -2px; border-radius: var(--tm-r-full);
  border: 2px solid currentColor; border-top-color: transparent;
  animation: tmSpin 720ms linear infinite;
}
@keyframes tmSpin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  /* The ghost still renders, as ONE static example with no caret and no
     typing, so the affordance survives without the motion. */
  .tm-tghost::after { animation: none; opacity: 0; }
  .tm-spin { animation-duration: 0s; border-top-color: currentColor; }
  .tm-mpick.tm-on .tm-tile-plate::after { animation: none; }
}

@media (max-width: 420px) {
  .tm-amt-sm .tm-amt-val { font-size: 1.7rem; }
  .tm-ex { font-size: 14px; padding: 12px 13px; }
}

/* dev-TMV3-2: the card's factual chip row. Must-haves the home HAS, in the
   renter's own tile words, plus its position against the derived budget range.
   Positive and neutral facts only: a home that misses a must-have carries a
   shorter row, never a "does not have" chip. */
.tm-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--tm-s3); }
.tm-chip {
  display: inline-block; padding: 4px 10px; border-radius: var(--tm-r-full);
  background: var(--tm-gold-chip); color: var(--tm-gold-ink);
  font-size: 12px; font-weight: var(--tm-w-bold); letter-spacing: .01em;
  border: 1px solid var(--tm-gold-wash);
}
.tm-chip-quiet {
  background: var(--tm-surface-sunk); color: var(--tm-caption);
  border-color: var(--tm-edge);
}

/* dev-TMV3-2: the Show more control and its batch. */
#cm-more { margin-top: var(--tm-s6); }
.cm-more-btn { display: block; width: 100%; max-width: 320px; margin: 0 auto var(--tm-s6); min-height: 48px; }
#cm-more-cards[hidden] { display: none; }

/* dev-TMV4-1: HOW WE ARE PAID, once and with weight. The sentence used to ride
   the tail of .tm-terms, 12px centred caption grey, repeated under all six
   buttons. It answers the first question a renter has about signing anything,
   so it gets a real block: the gold edge and wash the funnel already uses for
   reassurance (.rep-reassure on the wizard is the same idiom), body-size type on
   the readable ink rather than the caption ink, and one instance. */
.tm-comp {
  display: flex; gap: var(--tm-s3); align-items: flex-start;
  margin: var(--tm-s6) 0 0; padding: var(--tm-s4) var(--tm-s5);
  border: 1px solid rgba(184, 149, 107, .35); border-left-width: 4px;
  border-radius: var(--tm-r-lg); background: var(--tm-gold-wash-2);
}
.tm-comp-ic { flex: 0 0 auto; width: 22px; height: 22px; margin-top: 1px; color: var(--tm-gold-ink); }
.tm-comp p {
  margin: 0; font-size: 15px; line-height: 1.6;
  font-weight: var(--tm-w-semibold); color: var(--tm-text);
}
@media (max-width: 390px) { .tm-comp { padding: var(--tm-s4); } .tm-comp p { font-size: 14.5px; } }

/* dev-TMV4-2: THE TRUST STRIP AT THE PICKER START. Social proof works at the
   commitment moment, not the arrival moment, so the homepage's stats band moved
   here and to the agreement step. It sits in the picker's chrome rather than in
   any one step, so it holds on every question. Muted on purpose: it reassures,
   it does not compete with the question. */
.tm-trust-start {
  max-width: 620px; margin: var(--tm-s5) auto 0; padding-top: var(--tm-s4);
  border-top: 1px solid var(--tm-edge);
  font-size: 13px; line-height: 1.6; text-align: center;
  color: var(--tm-muted);
}
@media (max-width: 390px) { .tm-trust-start { font-size: 12.5px; } }
