/* =====================================================================
   UNIT3D Property Partners — shared site stylesheet (apex site)

   Rebuilt 2026-07-25 from lp.html's inline design system.

   ⚠ lp.html keeps its OWN inline copy of these styles and must never be
   switched to link this file. That isolation is deliberate: it means an
   edit here can never break the live, pixel-tracked ad funnel at
   lp.unit3dpropertypartners.com.
   ===================================================================== */

/* =====================================================================
   Section 1: lp.html's design system, extracted verbatim from its
   <style> block (lp.html:30-512). This is the base — tokens, buttons,
   badges, logo, forms, marquee, carousel, reveal motion. --container
   is 1600px here (was 1120px in the pre-rebuild site.css); that is
   where the sitewide widening comes from.
   ===================================================================== */

  /* ---- UNIT3D Property Partners — Design tokens ---- */
  :root {
    --navy:        #16263D;
    --ink-navy:    #0E1A2B;
    --navy-700:    #1B2C45;
    --navy-600:    #233649;
    --slate:       #5A6675;
    --slate-light: #8A96A4;
    --cream:       #F2EDE2;
    --cream-50:    #FAF8F3;
    --white:       #FFFFFF;

    --brass:       #B08D4C;
    --brass-dark:  #8E6F37;
    --brass-light: #C9A86A;
    --brass-tint:  #EFE6D4;

    --harbour:       #5E7C9E;
    --harbour-deep:  #43617F;
    --harbour-light: #98AEC4;
    --harbour-tint:  #E7ECF2;

    --success: #4E7C5A;
    --warning: #B0833C;
    --danger:  #A14B43;
    --info:    #5E7C9E;

    --surface-page:    var(--cream-50);
    --surface-card:    var(--white);
    --surface-sunken:  var(--cream);
    --surface-inverse: var(--navy);
    --border-subtle:   #E4DECF;
    --border-strong:   #D6CDB7;

    --text-strong:  var(--navy);
    --text-body:    var(--slate);
    /* Muted text on LIGHT surfaces only. Deliberately not var(--slate-light):
       #8A96A4 measures 2.83:1 on cream-50 and 2.58:1 on cream, both well under
       AA 4.5:1. #5E6873 gives 5.34:1 / 4.86:1. --slate-light itself is left
       alone because it is also used on the dark surfaces, where darkening it
       would DROP contrast from 5.81:1 to 3.08:1 — i.e. break what works. */
    --text-muted:   #5E6873;
    --text-on-dark: var(--cream);
    /* Secondary body text on the dark surfaces. Tokenises the #C7CDD4 that
       was hardcoded in .page-hero__sub (and appears inline in several pages,
       copied from lp). Kept at its original value rather than pointed at
       --slate-light, which would be tokenised but visibly dimmer.
       11.11:1 on --ink-navy, so comfortably AA. */
    --text-on-dark-muted: #C7CDD4;
    --text-accent:  var(--brass);

    --accent:        var(--brass);
    --accent-strong: var(--brass-dark);
    --accent-soft:   var(--brass-light);
    --accent-tint:   var(--brass-tint);
    /* Brass for SMALL TEXT (eyebrows, current-page nav) on light surfaces.
       Separate from --accent-strong because that doubles as the primary
       button's hover background, where darkening would worsen the navy text
       on it. --brass-dark #8E6F37 measures 4.42 / 4.02 / 3.78:1 on
       cream-50 / cream / brass-tint — all under AA. This gives 5.59 / 5.09 / 4.79. */
    --accent-text:   #7D5F26;

    --font-display: 'Montserrat', system-ui, sans-serif;
    --font-serif:   'Lora', Georgia, serif;
    --font-body:    'Inter', system-ui, sans-serif;

    --fs-display-xl: 3.5rem;
    --fs-display-lg: 2.75rem;
    --fs-display-md: 2rem;
    --fs-h1: 1.75rem;
    --fs-h2: 1.375rem;
    --fs-h3: 1rem;
    --fs-body-lg: 1.0625rem;
    --fs-body: 0.875rem;
    --fs-sm: 0.8125rem;
    --fs-label: 0.6875rem;
    --fs-micro: 0.625rem;
    --fs-display-serif: 2.4rem;

    --ls-tight: 0.02em;
    --ls-display: 0.04em;
    --ls-label: 0.12em;
    --ls-eyebrow: 0.2em;
    --ls-wordmark: 0.34em;

    --space-6: 24px;

    --radius-xs: 2px;
    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-lg: 10px;

    --container: 1600px;
    --rule-w: 44px;
    --rule-h: 3px;

    --shadow-card: 0 1px 3px rgba(14, 26, 43, 0.06), 0 8px 24px rgba(14, 26, 43, 0.06);
    --shadow-lg: 0 18px 48px rgba(14, 26, 43, 0.16);
    --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);

    --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
    --dur-fast: 120ms;
    --dur: 200ms;
  }

  html, body { margin: 0; padding: 0; }
  body { background: var(--ink-navy); font-family: var(--font-body); }
  * { box-sizing: border-box; }
  ::selection { background: var(--brass); color: var(--navy); }
  img { max-width: 100%; }

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

  /* ---- Eyebrow ---- */
  .u3d-eyebrow__label {
    font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600;
    letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--accent-text);
  }
  .u3d-eyebrow--on-dark .u3d-eyebrow__label { color: var(--accent-soft); }
  .u3d-eyebrow__rule { width: var(--rule-w); height: var(--rule-h); background: var(--accent); margin-top: 14px; }

  /* ---- Button ---- */
  .u3d-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-family: var(--font-display); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    border-radius: var(--radius-xs); border: 1px solid transparent; cursor: pointer;
    transition: background var(--dur) var(--ease-out), color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
    text-decoration: none; line-height: 1; white-space: nowrap;
  }
  .u3d-btn:hover { transform: translateY(-1px); }
  .u3d-btn:active { transform: translateY(0) scale(0.98); }
  .u3d-btn { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
  .u3d-btn:focus-visible, a:focus-visible, button:focus-visible, .u3d-input:focus-visible, .u3d-select:focus-visible, .u3d-textarea:focus-visible {
    outline: 2px solid var(--brass-light); outline-offset: 2px;
  }
  .u3d-btn--sm { padding: 8px 16px; font-size: 11px; }
  .u3d-btn--md { padding: 12px 24px; font-size: 11px; }
  .u3d-btn--lg { padding: 15px 32px; font-size: 12px; }
  .u3d-btn--xl { padding: 22px 52px; font-size: 14px; letter-spacing: 0.1em; }
  .u3d-btn--primary { background: var(--accent); color: var(--navy); }
  .u3d-btn--primary:hover { background: var(--accent-strong); }
  .u3d-btn--ghost-on-dark { background: transparent; color: var(--cream); border-color: color-mix(in srgb, var(--cream) 28%, transparent); }
  .u3d-btn--ghost-on-dark:hover { background: color-mix(in srgb, var(--cream) 8%, transparent); }
  .u3d-btn--block { width: 100%; }

  /* ---- Badge ---- */
  .u3d-badge {
    display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-body);
    font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
    padding: 4px 9px; border-radius: var(--radius-xs); line-height: 1.2;
  }
  .u3d-badge--brass-solid { color: var(--white); background: var(--brass); }
  .u3d-badge--available-solid { color: var(--white); background: var(--success); }

  /* ---- Logo ---- */
  .u3d-logo { display: inline-flex; align-items: center; text-decoration: none; }
  .u3d-logo__word { display: flex; flex-direction: column; align-items: flex-start; text-align: left; line-height: 1; }
  .u3d-logo__unit { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--cream); }
  .u3d-logo__unit span { color: var(--brass); }
  .u3d-logo__sub { font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: 0.34em; color: #94A0B0; }

  .u3d-logo--dark .u3d-logo__unit { color: var(--navy); }
  .u3d-logo--dark .u3d-logo__sub  { color: var(--slate); }
  .site-nav a.nav-item {
    font-size: var(--fs-label); font-weight: 600; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--navy); opacity: 0.65;
    text-decoration: none; transition: opacity var(--dur) var(--ease-out);
  }
  .site-nav a.nav-item:hover { opacity: 1; }
  .site-nav a.nav-item[aria-current="page"] { opacity: 1; color: var(--accent-text); }

  /* ---- Input ---- */
  .u3d-field { display: flex; flex-direction: column; gap: 6px; width: 100%; }
  .u3d-field label {
    font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600;
    letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-body);
  }
  .u3d-input, .u3d-select, .u3d-textarea {
    width: 100%; font-family: var(--font-body); font-size: var(--fs-body); color: var(--text-strong);
    background: var(--surface-card); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    padding: 11px 14px; outline: none;
    transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
  }
  .u3d-textarea { resize: vertical; min-height: 78px; line-height: 1.5; }
  .u3d-input:focus, .u3d-select:focus, .u3d-textarea:focus { border-color: var(--accent); box-shadow: var(--ring); }
  .u3d-form-section { display: flex; flex-direction: column; gap: 16px; }
  .u3d-form-section + .u3d-form-section { margin-top: 4px; padding-top: 22px; border-top: 1px solid var(--navy-600); }
  .u3d-form-section__title {
    font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600;
    letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--brass-light);
  }

  /* ---- Multi-step contact form ---- */
  .u3d-form-intro { text-align: center; padding: 8px 4px 4px; display: flex; flex-direction: column; align-items: center; gap: 16px; }
  .u3d-form-intro__heading {
    font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h2); text-transform: uppercase;
    letter-spacing: 0.02em; color: var(--cream); margin: 0;
  }
  .u3d-form-intro__sub { font-size: var(--fs-sm); color: var(--slate-light); line-height: 1.6; margin: -8px 0 0; max-width: 280px; }
  .u3d-form-intro__caption { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--slate-light); }
  .u3d-form-step { display: flex; flex-direction: column; gap: 22px; }
  .u3d-form-step__meta {
    font-family: var(--font-body); font-size: var(--fs-micro); font-weight: 700;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--brass-light); margin-bottom: -8px;
  }
  .u3d-form-nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
  .u3d-form-nav--end { justify-content: flex-end; }
  .u3d-form-back {
    background: none; border: none; padding: 0; cursor: pointer; font-family: var(--font-body);
    font-size: var(--fs-label); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--slate-light); transition: color var(--dur) var(--ease-out);
  }
  .u3d-form-back:hover { color: var(--cream); }
  .u3d-field-row { display: flex; gap: 14px; }

  /* ---- Wizard card on light hero ---- */
  .u3d-form-card--light {
    background: var(--surface-card); border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 28px;
  }
  .u3d-form-card--light .u3d-form-intro__heading { color: var(--navy); }
  .u3d-form-card--light .u3d-form-intro__sub,
  .u3d-form-card--light .u3d-form-intro__caption { color: var(--slate); }
  .u3d-form-card--light .u3d-form-back:hover { color: var(--navy); }
  .u3d-form-card--light .u3d-form-section + .u3d-form-section { border-top-color: var(--border-subtle); }
  .u3d-form-card--light .u3d-form-step__meta,
  .u3d-form-card--light .u3d-form-section__title { color: var(--brass-dark); }
  .u3d-form-card--light .u3d-form-intro__caption svg { stroke: var(--brass-dark); }

  a { color: inherit; }

  /* ---- Responsive ---- */
  @media (max-width: 1400px) {
    .u3d-carousel__card { width: calc((100% - 40px) / 3) !important; }
  }
  @media (max-width: 980px) {
    .hero-inner { grid-template-columns: 1fr !important; }
    .hero-media { min-height: 300px !important; }
    .pricing-grid { grid-template-columns: repeat(2, 1fr) !important; }
    .u3d-carousel__card { width: calc((100% - 20px) / 2) !important; }
    .comparison-grid { grid-template-columns: 1fr !important; }
    .comparison-photo { min-height: 260px !important; }
    /* Below this width five columns stop fitting, so the timeline turns
       90 degrees: one column, the line runs down through the badge
       centres instead of across them, and each step becomes a row
       (badge left, copy right) instead of a centred stack. */
    .process-grid { display: flex !important; flex-direction: column !important; gap: 36px !important; }
    .process-line { top: 20px !important; bottom: 20px !important; left: 19px !important; right: auto !important; width: 2px !important; height: auto !important; }
    /* Vertical orientation needs the draw to grow downward instead of
       rightward; the extra .process-grid qualifier outranks the desktop
       rule's specificity so this wins regardless of source order. Keeps
       the original snappier ~1.4s pace rather than the slow desktop draw
       (!important since this ties on specificity with the base rule and
       sits earlier in the file). */
    .js .process-grid #process-line { transform-origin: left top; transform: scaleY(0); transition-duration: 1400ms !important; }
    .js .process-grid #process-line.is-visible { transform: scaleY(1); }
    .process-grid .process-step:nth-child(2) { --step-delay: 0ms !important; }
    .process-grid .process-step:nth-child(3) { --step-delay: 360ms !important; }
    .process-grid .process-step:nth-child(4) { --step-delay: 700ms !important; }
    .process-grid .process-step:nth-child(5) { --step-delay: 1040ms !important; }
    .process-grid .process-step:nth-child(6) { --step-delay: 1370ms !important; }
    .process-step { display: flex !important; align-items: flex-start !important; text-align: left !important; gap: 20px !important; }
    .process-step__badge { margin: 0 !important; }
    .process-step__title { margin-top: 2px !important; }
    .guarantee-grid, .contact-grid { grid-template-columns: 1fr !important; }
  }
  @media (max-width: 640px) {
    .hero .hero-inner { padding: 40px 24px 56px !important; gap: 32px !important; }
    .site-nav { padding: 14px 20px !important; }
    .site-nav__inner { grid-template-columns: auto 1fr !important; gap: 12px !important; }
    .site-nav .u3d-btn { padding: 8px 12px !important; font-size: 9.5px !important; white-space: nowrap !important; }
    section { padding: 64px 24px !important; }
    footer { padding: 32px 24px !important; }
    /* The homepage's split-audience hero h1 carries no .hero-title class
       (it's a one-off inline-styled heading), so it never picked up this
       clamp. At the desktop --fs-display-xl (3.5rem) size, "PROPERTIES"
       doesn't fit the 327px mobile content column and, since browsers
       don't break inside a word by default, the h1 poked past its own
       box and inflated document.scrollWidth — the actual cause of the
       mobile horizontal-scroll bug on index.html. */
    .hero-title, .hero--split-audience h1 { font-size: 2.4rem !important; }
    /* minmax(0,1fr) lets grid tracks shrink below their content's
       min-width, so cards can never spill past the viewport */
    .pricing-grid, .process-grid, .why-us-grid { grid-template-columns: minmax(0, 1fr) !important; }
    /* Below this width the row-of-cards layout stops making sense — back to
       one focused card, centred, with peeking neighbours either side. */
    .u3d-carousel__card { width: 84vw !important; scroll-snap-align: center !important; }
    .u3d-carousel__viewport { margin: 0 -24px !important; }
    .u3d-carousel__spacer { display: block !important; flex: 0 0 auto !important; width: 8vw !important; }
    .comparison-grid > * { min-width: 0; }
    /* Buttons wrap instead of clipping off-screen */
    .u3d-btn { white-space: normal; line-height: 1.35; }
    .u3d-btn--xl { display: flex; width: 100%; padding: 18px 20px; font-size: 12.5px; }
    .pricing-highlight { padding: 28px 22px !important; }
    /* 16px inputs stop iOS Safari auto-zooming the page on focus */
    .u3d-input, .u3d-select, .u3d-textarea { font-size: 16px; }
    .u3d-field-row { flex-direction: column; gap: 16px; }
  }
  section[id] { scroll-margin-top: calc(var(--header-h, 124px) + 16px); }

  /* ---- Fixed header (announcement + nav) ----
     The .site-header rule itself lives in Section 3 below, where the two
     competing header definitions were merged. Declaring it here as well was
     a verbatim-extraction artifact: identical values, so harmless, but it
     made the "merge" look like it had not happened. */

  /* ---- Marquee strips ---- */
  .u3d-marquee { overflow: hidden; background: var(--ink-navy); border-top: 1px solid var(--navy-600); border-bottom: 1px solid var(--navy-600); padding: 10px 0; }
  .u3d-marquee__track { display: flex; width: max-content; animation: u3d-marquee 36s linear infinite; }
  .u3d-marquee__item {
    font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm);
    letter-spacing: 0.18em; text-transform: uppercase; color: var(--brass-light);
    white-space: nowrap; padding-right: 28px;
    display: inline-flex; align-items: center; gap: 8px;
  }
  .u3d-marquee__item::after { content: "·"; color: var(--brass); padding-left: 28px; }
  /* Icon-led marquees replace the bullet with a standalone icon separator
     between phrases (not a prefix glued to the text), so the icon gets
     equal space on both sides. */
  .u3d-marquee--icon .u3d-marquee__item { padding-right: 0; }
  .u3d-marquee--icon .u3d-marquee__item::after { content: none; }
  .u3d-marquee__icon-sep { display: inline-flex; align-items: center; justify-content: center; margin: 0 28px; color: var(--brass); flex-shrink: 0; }
  @keyframes u3d-marquee { to { transform: translateX(-50%); } }
  @media (prefers-reduced-motion: reduce) { .u3d-marquee__track { animation: none; } }


  /* ---- Offer carousel ---- */
  .u3d-carousel { position: relative; margin-top: 8px; }
  .u3d-carousel__viewport {
    overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .u3d-carousel__viewport::-webkit-scrollbar { display: none; }
  .u3d-carousel__viewport:focus-visible { outline: 2px solid var(--brass-light); outline-offset: 4px; }
  .u3d-carousel__track { display: flex; gap: 20px; padding: 4px 0; }
  /* Desktop/tablet default: a full row of whole cards, sized as a share of
     the row so N of them exactly fill it with no partial card at the edge.
     Card 5 onward simply starts past the right edge, revealed by scrolling —
     that's what makes the row's own width the relevant "100%" here (not the
     window), since it's a percentage of the track's own box, which in normal
     flow always matches its containing block regardless of overflow. */
  .u3d-carousel__card {
    flex: 0 0 auto; width: calc((100% - 60px) / 4); scroll-snap-align: start;
    background: var(--surface-card); border: 1px solid var(--border-subtle); border-top: 3px solid var(--brass);
    border-radius: var(--radius-md); box-shadow: var(--shadow-card); overflow: hidden;
    display: flex; flex-direction: column;
  }
  /* Mobile-only: a single focused card, centred, peeking neighbours either
     side. Needs real spacer elements (not padding) for the same reason noted
     on the mobile breakpoint below — hidden here since rows-of-cards mode
     doesn't use them. */
  .u3d-carousel__spacer { display: none; }
  /* flex: 0 0 auto locks this to its aspect-ratio-derived size regardless of
     the body's content length. min-height: 0 is the real fix, though: flex
     items default to min-height:auto, which floors at the item's min-content
     size — for a box whose only content is a replaced element (the img),
     that floor is the IMAGE's own intrinsic aspect ratio at its resolved
     width, not the box's declared aspect-ratio. A tall source photo (e.g.
     923×1000) then overrides the 1:1 box despite aspect-ratio being set,
     exactly reproducing the source photo's own ratio instead of cropping to
     square. min-height: 0 removes that floor so aspect-ratio actually wins. */
  .u3d-carousel__photo { flex: 0 0 auto; min-height: 0; aspect-ratio: 1 / 1; background: var(--cream); position: relative; }
  .u3d-carousel__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .u3d-carousel__fallback {
    display: none; position: absolute; inset: 0; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px; text-align: center; padding: 16px; font-size: var(--fs-sm); color: var(--slate-light); line-height: 1.5;
  }
  .u3d-carousel__fallback span { font-size: 11px; }
  .u3d-carousel__body { padding: 24px 26px 28px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
  .u3d-carousel__body h3 {
    font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h2); text-transform: uppercase;
    letter-spacing: 0.02em; color: var(--text-strong); margin: 0; line-height: 1.25; min-height: 2.5em;
  }
  .u3d-carousel__body p { font-size: var(--fs-body); color: var(--text-body); margin: 0; line-height: 1.65; }
  .u3d-carousel__btn {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    width: 44px; height: 44px; border-radius: 50%; background: var(--surface-card); border: 1px solid var(--border-strong);
    box-shadow: var(--shadow-card); color: var(--navy); font-size: 20px; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur) var(--ease-out), background var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  }
  /* Arrows are a desktop mouse affordance: hidden until the pointer is
     actually over the carousel (i.e. near one side or the other), and
     reachable by keyboard focus regardless of hover state. */
  .u3d-carousel:hover .u3d-carousel__btn, .u3d-carousel__btn:focus-visible {
    opacity: 1; pointer-events: auto;
  }
  .u3d-carousel__btn:hover { background: var(--brass-tint); }
  .u3d-carousel__btn:active { transform: translateY(-50%) scale(0.94); }
  .u3d-carousel__btn--prev { left: -22px; }
  .u3d-carousel__btn--next { right: -22px; }
  .u3d-carousel__dots { display: flex; justify-content: center; gap: 10px; margin-top: 24px; }
  .u3d-carousel__dot {
    width: 7px; height: 7px; border-radius: 50%; border: none; padding: 0; cursor: pointer;
    background: var(--border-strong); transition: background var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  }
  /* One dot per card, but the highlighted set is a whole window matching
     however many cards actually fit the viewport at once (1 on mobile, up
     to 4 on wide desktop), so it reads as "these are the visible cards"
     rather than a single-position marker. */
  .u3d-carousel__dot--inview { background: var(--brass); transform: scale(1.55); }
  @media (max-width: 640px) {
    .u3d-carousel__btn { display: none; }
  }

  /* ---- Scroll progress (brass hairline, top of page) ---- */
  #scroll-progress {
    position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 200;
    background: linear-gradient(90deg, var(--brass-dark), var(--brass-light));
    transform: scaleX(0); transform-origin: 0 0; pointer-events: none;
  }

  /* ---- Motion: calm, architectural entrance reveals ---- */
  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }


  .js .reveal,
  .js .reveal-stagger > * {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
  }
  .js .reveal.is-visible,
  .js .reveal-stagger > *.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
  .reveal-stagger > *:nth-child(1) { transition-delay: 0ms; }
  .reveal-stagger > *:nth-child(2) { transition-delay: 70ms; }
  .reveal-stagger > *:nth-child(3) { transition-delay: 140ms; }
  .reveal-stagger > *:nth-child(4) { transition-delay: 210ms; }
  .reveal-stagger > *:nth-child(5) { transition-delay: 280ms; }
  .reveal-stagger > *:nth-child(6) { transition-delay: 350ms; }

  /* ---- Directional reveal variants: same fade/timing as the default
     float-up, but sliding in from a side instead, or not sliding at all.
     Standalone .reveal--left/right (for one-off elements like the hero
     photo) tie on specificity with the base .reveal rule, so they must
     stay below it in source order to win. The per-section grid overrides
     outrank the base rule on specificity alone (order-independent), which
     is exactly why they need :not(.is-visible): without it they'd also
     outrank the base .is-visible reset and hold the card offset forever,
     overlapping its neighbours instead of settling into place. */
  .js .reveal--right { transform: translateX(48px); }

  .js .comparison-grid.reveal-stagger > *:nth-child(1):not(.is-visible) { transform: translateX(-48px); }
  .js .comparison-grid.reveal-stagger > *:nth-child(2):not(.is-visible) { transform: none; }
  .js .comparison-grid.reveal-stagger > *:nth-child(3):not(.is-visible) { transform: translateX(48px); }


  .js .pricing-grid.reveal-stagger > *:nth-child(1):not(.is-visible) { transform: translateX(-48px); }
  .js .pricing-grid.reveal-stagger > *:nth-child(2):not(.is-visible) { transform: none; }
  .js .pricing-grid.reveal-stagger > *:nth-child(3):not(.is-visible) { transform: translateX(48px); }

  .js .guarantee-grid.reveal-stagger > *:nth-child(odd):not(.is-visible) { transform: translateX(-48px); }
  .js .guarantee-grid.reveal-stagger > *:nth-child(even):not(.is-visible) { transform: translateX(48px); }

  .js .contact-grid.reveal-stagger > *:nth-child(2):not(.is-visible) { transform: translateX(48px); }

  /* ---- Contain pre-reveal transform overflow.
     Every translateX(±48px) above (and .reveal--right's) is a real layout
     transform: until its IntersectionObserver fires, the shifted box still
     contributes to the *document's* scrollable overflow even though it
     isn't visible yet (that region is below the fold on first paint), which
     is exactly what produces the mobile horizontal-scroll bug — not stacked
     padding. #income and #contact already carry their own inline
     `overflow:hidden` for this reason (comparison-grid's and contact-grid's
     nth-child offsets); #why-switch (the offer carousel's .reveal--right),
     #pricing (pricing-highlight, pricing-grid's nth-child(3)) and
     #guarantee (its nth-child(even)) were missing the same containment.
     overflow-x only, so none of these sections' own vertical shadows/edges
     get clipped, and none of it touches body — sticky/scroll-anchoring are
     unaffected since nothing in this codebase uses position:sticky. */
  #why-switch, #pricing, #guarantee { overflow-x: hidden; }

  /* ---- Process timeline: the line "draws" itself, and each step's badge
     + copy lands as the growing line reaches that step's position along it
     (roughly quarter-fractions of the draw, since the five steps sit at
     ~0/25/50/75/100% of the line's span). Overrides the generic
     reveal-stagger fade timing, which is far too fast (70ms apart) to read
     as synced with a line draw. Desktop (horizontal) runs slow and
     deliberate, ~1.5s between each step, over a 6s draw; the ≤980px
     vertical layout keeps a snappier pace, restored in that media query. */
  .js #process-line { transform-origin: left center; transform: scaleX(0); transition: transform 6000ms linear; }
  .js #process-line.is-visible { transform: scaleX(1); }
  .process-grid .process-step:nth-child(2) { --step-delay: 0ms; }
  .process-grid .process-step:nth-child(3) { --step-delay: 1500ms; }
  .process-grid .process-step:nth-child(4) { --step-delay: 3000ms; }
  .process-grid .process-step:nth-child(5) { --step-delay: 4500ms; }
  .process-grid .process-step:nth-child(6) { --step-delay: 6000ms; }
  /* The badge appears (fade only, no motion); the copy still slides up.
     Both read --step-delay from their .process-step ancestor above so the
     one set of nth-child rules still drives the whole synced sequence. */
  .js .process-step { opacity: 1; transform: none; }
  .js .process-step__badge { opacity: 0; transition: opacity 420ms var(--ease-out); transition-delay: var(--step-delay, 0ms); }
  .js .process-step.is-visible .process-step__badge { opacity: 1; }
  .js .process-step__body { opacity: 0; transform: translateY(14px); transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out); transition-delay: var(--step-delay, 0ms); }
  .js .process-step.is-visible .process-step__body { opacity: 1; transform: translateY(0); }

  @media (prefers-reduced-motion: reduce) {
    .js .reveal,
    .js .reveal-stagger > * {
      transition: none !important;
      opacity: 1 !important;
      transform: none !important;
    }
  }

  /* ---- Footer social links ---- */
  .u3d-social { display: flex; gap: 12px; }
  .u3d-social__link {
    width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--navy-600);
    display: flex; align-items: center; justify-content: center; color: var(--slate-light);
    transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
  }
  .u3d-social__link:hover { color: var(--brass); border-color: var(--brass); }

/* =====================================================================
   Section 2: Apex-only classes carried forward from the pre-rebuild
   assets/site.css. lp.html is a single page with no interior pages, no
   stay cards, and no mobile hamburger, so it has no equivalent for any
   of these — they do not collide with anything above.

   The old .site-footer 4-column grid is deliberately NOT carried
   forward here: lp.html's centred single-column footer wins that
   collision (see file header note on lp winning collisions). Footer
   markup on interior pages renders unstyled until each page's own
   rebuild task adopts lp's centred footer pattern.
   ===================================================================== */

/* ---- Section heading/lede (apex-only: not in lp.html) ---- */
.section-lede { font-size: var(--fs-body-lg); color: var(--text-body); max-width: 560px; margin: 0 0 44px; line-height: 1.7; }

/* ---- Button modifiers (apex-only: not in lp.html) ---- */
.u3d-btn--ghost { background: transparent; color: var(--navy); border-color: var(--border-strong); }
.u3d-btn--ghost:hover { background: var(--cream); }

/* ---- Page hero (interior pages) ---- */
.page-hero { background: var(--ink-navy); padding: 76px 48px 84px; position: relative; overflow: hidden; }
.page-hero__title {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-display-lg);
  line-height: 1.06; text-transform: uppercase; letter-spacing: var(--ls-display);
  color: var(--cream); margin: 22px 0 0;
}
.page-hero__title span { color: var(--brass); }
.page-hero__sub { font-size: var(--fs-body-lg); color: var(--text-on-dark-muted); line-height: 1.7; margin: 20px 0 0; max-width: 560px; }

/* ---- Cards ---- */
.card {
  background: var(--surface-card); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); box-shadow: var(--shadow-card); padding: 26px;
  display: flex; flex-direction: column; gap: 14px;
}
.card--brass-top { border-top: 3px solid var(--brass); }
.card__title {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h2);
  text-transform: uppercase; letter-spacing: 0.02em; color: var(--text-strong); margin: 0;
}
.card__body { font-size: var(--fs-body); color: var(--text-body); margin: 0; line-height: 1.6; }

.dash-list { display: flex; flex-direction: column; gap: 10px; margin: 2px 0 0; padding: 0; list-style: none; }
.dash-list li { display: flex; gap: 10px; font-size: var(--fs-body); color: var(--text-body); line-height: 1.55; }
.dash-list li::before { content: "—"; color: var(--brass); flex-shrink: 0; }
.dash-list--on-dark li { color: #aeb8c4; }

/* ---- Stay (property) cards ---- */
.stay-card {
  background: var(--surface-card); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); box-shadow: var(--shadow-card); overflow: hidden;
  display: flex; flex-direction: column;
}
.stay-card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--navy-700); }
.stay-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 600ms var(--ease-out); }
.stay-card:hover .stay-card__media img { transform: scale(1.035); }
.stay-card__badge { position: absolute; top: 14px; left: 14px; }
.stay-card__body { padding: 22px 24px 24px; display: flex; flex-direction: column; gap: 8px; }
.stay-card__area { font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--brass-dark); font-weight: 600; }
.stay-card__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h2); text-transform: uppercase; letter-spacing: 0.02em; color: var(--text-strong); margin: 0; }
.stay-card__meta { font-size: var(--fs-sm); color: var(--text-muted); }

/* ---- Stat block ---- */
.stat__value { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.4rem, 5.4vw, 1.9rem); color: var(--brass); white-space: nowrap; }
.stat__label { font-size: var(--fs-label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); margin-top: 4px; }

/* ---- Grids ---- */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }

/* ---- FAQ / definition rows ---- */
.faq-item { border-bottom: 1px solid var(--border-subtle); padding: 22px 0; }
.faq-item:first-child { border-top: 1px solid var(--border-subtle); }
.faq-item h3 {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3);
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-strong); margin: 0 0 8px;
}
.faq-item p { font-size: var(--fs-body); color: var(--text-body); line-height: 1.65; margin: 0; }


/* ---- Simple eyebrow (p.eyebrow) — a later task (the landlord page
   rebuild) uses a plain <p class="eyebrow"> label rather than the
   composite .u3d-eyebrow/.u3d-eyebrow__label/.u3d-eyebrow__rule markup
   defined above from lp. Both forms coexist deliberately; do not unify
   them. Styling mirrors .u3d-eyebrow__label's tokens exactly. ---- */
.eyebrow {
  font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--accent-text);
  margin: 0;
}
/* .u3d-eyebrow--center completes the composite eyebrow's variant set.
   It existed in the pre-rebuild site.css but has no lp.html equivalent
   (lp is a single page and never centres its eyebrow) — for-landlords.html
   and contact.html already use it and would lose centring without it. */
.u3d-eyebrow--center { display: flex; flex-direction: column; align-items: center; }

/* ---- Apex-only responsive rules for the classes above. These lived in
   the pre-rebuild site.css's "Responsive" block, outside the sed ranges
   used to salvage the base rules, but are needed for the same preserved
   classes (.grid-2/3/4, .page-hero, .about-photo) to collapse correctly
   on small screens. ---- */
@media (max-width: 980px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .about-photo { height: 320px !important; }
}
@media (max-width: 640px) {
  .page-hero { padding: 56px 24px 64px; }
  .page-hero__title { font-size: 2.1rem; }
  .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr) !important; }
}

/* ---- FAQ accordion variant. The static .faq-item (h3 + p) above is
   still used by contact.html's guest FAQ — both forms coexist. ---- */
details.faq-item { padding: 0; }
details.faq-item > summary {
  list-style: none; cursor: pointer; padding: 22px 0;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3);
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-strong);
}
details.faq-item > summary::-webkit-details-marker { display: none; }
details.faq-item > summary::after {
  content: "+"; font-size: 1.4em; line-height: 1; color: var(--brass); flex-shrink: 0;
}
details.faq-item[open] > summary::after { content: "–"; }
details.faq-item > p {
  font-size: var(--fs-body); color: var(--text-body); line-height: 1.65;
  margin: 0 0 22px; max-width: 70ch;
}
.faq-list { margin-top: 48px; }

/* =====================================================================
   Section 3: Site header — lp.html's fixed 3-column grid, plus the
   apex's hamburger (lp has no mobile menu — it is a single page with
   anchor links only; the apex has five real page links and needs one).
   Merges the pre-rebuild site.css's sticky-with-hamburger header with
   lp's fixed-with-centred-logo header; lp's positioning and grid win,
   the apex's mobile hamburger behaviour is grafted on.
   ===================================================================== */
.site-header { position: fixed; top: 0; left: 0; right: 0; z-index: 100; }

.site-nav {
  background: var(--surface-page);
  border-bottom: 1px solid var(--border-subtle);
  padding: 18px 48px;
}

.site-nav__inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;  /* centres the logo mathematically,
                                           independent of the side columns'
                                           widths. flex space-between was
                                           tried first and does not centre. */
  align-items: center;
  gap: 32px;
}

.site-nav__links  { justify-self: start; display: flex; gap: 28px; align-items: center; }
.u3d-logo         { justify-self: center; }
.site-nav__actions{ justify-self: end; display: flex; gap: 12px; align-items: center; }

.nav-toggle { display: none; background: none; border: 0; padding: 6px; cursor: pointer; }

@media (max-width: 960px) {
  .nav-toggle { display: inline-flex; }
  .site-nav__inner { grid-template-columns: auto 1fr; }
  .site-nav__links {
    grid-column: 1 / -1;
    display: none;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 12px 0 4px;
  }
  .site-nav__links.is-open { display: flex; }
  .u3d-logo { justify-self: start; }
}

/* ---- Homepage audience split ---- */
.audience-card {
  display: flex; flex-direction: column;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-decoration: none;
  transition: transform 240ms ease, box-shadow 240ms ease;
}
.audience-card:hover { transform: translateY(-4px); box-shadow: 0 18px 40px rgba(14,26,43,0.18); }
.audience-card img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; min-height: 0; flex: 0 0 auto; }
.audience-card__body { padding: 32px; display: flex; flex-direction: column; gap: 12px; }
.audience-card__body h2 { font-family: var(--font-display); color: var(--text-strong); margin: 0; }
.audience-card__body p  { color: var(--text-body); margin: 0; }
.audience-card__body .u3d-btn { align-self: flex-start; margin-top: 8px; }
@media (max-width: 860px) { .audience-split { grid-template-columns: minmax(0,1fr) !important; } }

/* ---- Mobile nav sizing (apex-only).
   lp.html has no hamburger and no multi-page nav, so these rules had no
   counterpart when the design system was lifted from it and were dropped.
   Without them the logo keeps its inline 24px, the nav grid's min-content
   width exceeds the viewport, and the fixed header forces ~69px of
   horizontal page scroll on every apex page at 375px. ---- */
@media (max-width: 640px) {
  .site-nav .u3d-logo__unit { font-size: 20px !important; }
  .site-nav .u3d-logo__sub  { font-size: 6.4px !important; }
  .site-nav .u3d-btn--sm    { padding: 9px 12px; font-size: 10px; }
}
@media (max-width: 480px) {
  .site-nav { gap: 8px; }
  .site-nav__actions { gap: 8px; }
  .site-nav .u3d-btn--sm { padding: 8px 9px; font-size: 9px; letter-spacing: 0.06em; }
  .site-nav .u3d-btn--sm span[aria-hidden] { display: none; }
  .site-nav .u3d-logo__unit { font-size: 18px !important; }
  .site-nav .u3d-logo__sub  { font-size: 5.8px !important; }
}

/* ---- Editorial two-column text sections (about, contact).
   These are inline-styled grids with no class of their own, so nothing
   collapsed them on mobile: the tracks default to min-width:auto and long
   paragraphs pushed them past the viewport, which showed up as a 3px
   horizontal scroll on about.html and, more importantly, as a cramped
   side-by-side layout on a phone. minmax(0,1fr) lets the track shrink
   below its content's min-content width. ---- */
@media (max-width: 860px) {
  .editorial-split { grid-template-columns: minmax(0, 1fr) !important; gap: 32px !important; }
}
