/* ===========================================================================
 * Desktop UX/UI parity layer — First Access Signals web build
 *
 * This file is loaded ONLY in the web build via a <link> tag injected by
 * scripts/inject-head-tags.mjs. It deliberately lives outside global.css
 * because NativeWind / react-native-css-interop processes global.css for
 * the iOS native bundle too, and chokes on `@media (hover: hover)` and
 * other web-only media features. Kept here, the iOS bundler never sees
 * these rules and the web build serves them statically from /desktop-ux.css.
 *
 * Background: react-native-web's StyleSheet has no @media queries, so
 * components using `useBreakpoint()` SSR with the wrong viewport (no
 * `window` during static export = falls back to the smallest breakpoint
 * = mobile-shaped first paint). That's the "looks cheap" first impression
 * on a 4K monitor — small H1, mobile padding, single column, no hero image.
 *
 * Fix: this file. Plain CSS targeting `data-*` attributes that components
 * set via RN-Web's `dataSet` prop. CSS @media queries fire at first paint
 * (no JS, no hydration delay), so the page is already desktop-shaped when
 * the browser renders. !important is required because RN-Web emits atomic
 * classes (`r-XXX`) that have higher specificity than plain selectors.
 * =========================================================================== */

/* --- 0. Smooth-scroll on anchor navigation ------------------------------ */
/* Apple-parity: clicking an anchor link or programmatic scrollTo glides
 * smoothly instead of teleporting. Native scroll behavior on pages with
 * a fixed nav also benefits — when the URL hash changes, scroll glides
 * to the target. `scroll-padding-top` accounts for the 76px fixed nav
 * so the anchor target isn't hidden behind it. Reduced-motion users
 * get instant scroll (browser handles this automatically). */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 76px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* --- 0a. Fixed-nav body padding ------------------------------------------ */
/* SiteNav is `position: fixed` on web (Apple pattern: transparent overlay
 * on the home hero, scroll-triggered solid + frosted-glass everywhere
 * else). Fixed nav is out of flow, so non-home routes need top padding
 * equal to nav height (76px) or content sits behind the nav. Home route
 * has a [data-fas-hero-shell]; we let the hero start at scroll y=0
 * (full-bleed) and overlay it via the nav's z-index. The :has() selector
 * is supported in Chrome 105+, Safari 15.4+, Firefox 121+ — covers
 * 95%+ of our target audience; the fallback (no padding-top on home,
 * 76px overlap on other routes) is acceptable noise on the long tail. */
body {
  padding-top: 76px;
}
body:has([data-fas-hero-shell]) {
  padding-top: 0;
}

/* --- 0. Mobile-overflow guards ------------------------------------------ */
/* RN-Web's atomic CSS doesn't set overflow-x on the root, so any child
 * with a fixed pixel width > viewport (e.g. a 560px Signal card on a
 * 390px iPhone) makes the body scrollable horizontally. Lock the root
 * to viewport width and let `[data-fas-hero-shell]`'s `overflow:hidden`
 * be the visible-clip backstop. */
html,
body {
  max-width: 100vw !important;
  overflow-x: hidden !important;
}

/* --- 1. Fluid container padding ------------------------------------------ */
[data-fas-section] {
  padding-left: clamp(24px, 6vw, 128px) !important;
  padding-right: clamp(24px, 6vw, 128px) !important;
  width: 100% !important;
  max-width: 100vw !important;
  box-sizing: border-box !important;
}

/* --- 2. Fluid hero typography -------------------------------------------- */
[data-fas-hero-h1] {
  font-size: clamp(36px, 7vw, 96px) !important;
  line-height: 0.95 !important;
  letter-spacing: -0.01em !important;
  display: block !important;
}

/* RN-Web's <Text> renders as <div> with `display: inline` by default;
 * sibling eyebrow lines collapse onto one line ("FIRST ACCESS SIGNALSTIMING
 * TOOL FOR THE GTA"). Force block so each line stacks vertically. */
[data-fas-hero-eyebrow] {
  font-size: clamp(11px, 0.85vw, 14px) !important;
  letter-spacing: 0.18em !important;
  display: block !important;
}

[data-fas-hero-subhead] {
  font-size: clamp(16px, 1.5vw, 24px) !important;
  line-height: 1.4 !important;
  max-width: 36em !important;
  display: block !important;
}

/* --- 3. Full-bleed hero shell -------------------------------------------- */
[data-fas-hero-shell] {
  position: relative !important;
  min-height: clamp(560px, 78vh, 880px) !important;
  width: 100% !important;
  max-width: 100vw !important;
  overflow: hidden !important;
  background-color: #000 !important;
  box-sizing: border-box !important;
  /* Nav clearance (fixed SiteNav, ~76px) + breathing room before next
   * section. With SmartAppBanner now hidden, the nav alone owns the top
   * inset. clamp() scales padding with viewport width. */
  padding-top: clamp(96px, 12vw, 132px) !important;
  padding-bottom: clamp(48px, 6vw, 96px) !important;
}

/* Score-circle count-up — kill web user-agent input quirks so the
 * AnimatedTextInput's text centers cleanly inside the ring.
 * RN-Web maps <TextInput> to <input>, which has caret-color reservation,
 * focus outline, and inconsistent box-sizing defaults across browsers. */
[data-fas-score-input] {
  caret-color: transparent !important;
  outline: 0 !important;
  outline-width: 0 !important;
  text-indent: 0 !important;
  box-sizing: border-box !important;
  padding: 0 !important;
  -webkit-appearance: none !important;
  appearance: none !important;
  background: transparent !important;
}
[data-fas-score-input]:focus,
[data-fas-score-input]:focus-visible {
  outline: 0 !important;
  box-shadow: none !important;
}

[data-fas-hero-video] {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  z-index: 0 !important;
  pointer-events: none !important;
  filter: brightness(0.85) saturate(1.05) !important;
}

/* Static poster image — hidden by default; revealed only on
 * prefers-reduced-motion (see §7 below). Same absolute-cover layout as
 * the video so reduced-motion users get the same cinematic still
 * Apple shows on its hero pages. */
[data-fas-hero-poster] {
  display: none !important;
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  z-index: 0 !important;
  pointer-events: none !important;
  filter: brightness(0.85) saturate(1.05) !important;
}

[data-fas-hero-overlay] {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.45) 0%,
    rgba(0, 0, 0, 0.25) 35%,
    rgba(0, 0, 0, 0.55) 100%
  ) !important;
  z-index: 1 !important;
  pointer-events: none !important;
}

[data-fas-hero-content] {
  position: relative !important;
  z-index: 2 !important;
  min-height: clamp(560px, 78vh, 880px) !important;
  width: 100% !important;
  max-width: 100vw !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  box-sizing: border-box !important;
  min-width: 0 !important;
}

/* Direct children of hero-content (the split, attribution lines, etc.)
 * must allow shrinking — RN-Web flex children default to flex-shrink: 0
 * on iOS Safari, which lets them blow out the parent's width on narrow
 * viewports. */
[data-fas-hero-content] > * {
  min-width: 0 !important;
  max-width: 100% !important;
}

/* --- 4. Hero split (CSS-grid responsive, no JS breakpoint) --------------- */
/* Mobile: single column with `minmax(0, 1fr)` so the cell can SHRINK
 * below its content's intrinsic width. Without `minmax(0, ...)`, an
 * RN-Web Signal card with `width: 560px` blows the cell out and the
 * page horizontally overflows on a 390px iPhone. */
[data-fas-hero-split] {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) !important;
  gap: 32px !important;
  width: 100% !important;
  max-width: 1440px !important;
  margin-left: auto !important;
  margin-right: auto !important;
  align-items: center !important;
  box-sizing: border-box !important;
}

[data-fas-hero-split] > * {
  min-width: 0 !important;
  max-width: 100% !important;
}

@media (min-width: 1024px) {
  [data-fas-hero-split] {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr) !important;
    gap: 64px !important;
  }
}

@media (min-width: 1536px) {
  [data-fas-hero-split] {
    gap: 96px !important;
  }
}

/* --- 4b. Footer columns reflow ------------------------------------------ */
/* SiteFooter renders columns in `flexDirection: row` by default. Below
 * 1024px we flip to `column` via CSS. JS-driven branching previously had
 * SSR/hydration timing issues — SSR fires with useWindowDimensions returning
 * {width:0} → JS resolves to mobile → column layout SSR'd. Post-hydration on
 * desktop the JS re-rendered as row, but on mobile post-hydration may not
 * commit before paint, leaving a row layout briefly mounted on 390px
 * viewport where 3 columns can't fit and visibly overlap. CSS @media fires
 * at first paint with the actual viewport, no hydration race. */
@media (max-width: 1023px) {
  [data-fas-footer-columns] {
    flex-direction: column !important;
    gap: 32px !important;
    width: 100% !important;
  }
  [data-fas-footer-columns] > * {
    width: 100% !important;
    flex: 0 1 auto !important;
    min-width: 0 !important;
    max-width: 100% !important;
  }
}

/* --- 4b2. SiteNav: fixed positioning + transparent-over-hero ------------ */
/* The nav floats fixed at the top of the viewport. Default state is
 * solid plaster + frosted-glass blur (Apple's signature backdrop-filter
 * effect). When the home route is at scroll top 0, the nav is over the
 * dark hero video — JS sets data-fas-nav-transparent="true" so we strip
 * the bg/blur/border and switch text + logo color to white. After the
 * user scrolls 80px past the top, the JS toggles the attr off and the
 * nav fades back to solid. 300ms apple-bezier transition makes the
 * fade feel cinematic, not jumpy. */
[data-fas-nav-bar] {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 1100 !important;
  background-color: rgba(248, 247, 245, 0.92) !important;
  -webkit-backdrop-filter: saturate(180%) blur(20px) !important;
  backdrop-filter: saturate(180%) blur(20px) !important;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08) !important;
  transition:
    background-color 300ms cubic-bezier(0.16, 1, 0.3, 1),
    border-bottom-color 300ms cubic-bezier(0.16, 1, 0.3, 1) !important;
}

/* Transparent state — over the hero video on home route, scroll < 80px */
[data-fas-nav-transparent="true"] {
  background-color: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border-bottom-color: transparent !important;
}

/* When transparent, every text/icon swaps to white for legibility on
 * the dark hero video. text-shadow gives a subtle drop so light text on
 * mid-tone areas of the video stays readable. */
[data-fas-nav-transparent="true"] [data-fas-nav-link-text],
[data-fas-nav-transparent="true"] [data-fas-nav-signin-text] {
  color: #ffffff !important;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4) !important;
  transition: color 300ms cubic-bezier(0.16, 1, 0.3, 1) !important;
}
[data-fas-nav-transparent="true"] [data-fas-nav-signin-button] {
  border-color: rgba(255, 255, 255, 0.5) !important;
}
[data-fas-nav-transparent="true"] [data-fas-nav-hamburger-bar] {
  background-color: #ffffff !important;
}

/* When the hero video is hidden (prefers-reduced-motion), the page
 * shows the static poster image; text overlay still needs to be light
 * so the transparent-nav rules above still apply. No change needed. */

/* --- 4c. SiteNav: compact ↔ expanded layout swap ------------------------- */
/* SiteNav renders BOTH layouts in the DOM. CSS toggles which is visible.
 * Compact (hamburger + sign-in) shows on <1024px; expanded (links row +
 * sign-in) shows on >=1024px. Replaces useBreakpoint() JS branching that
 * had the same SSR/hydration mismatch as the footer. */
[data-fas-nav-compact] {
  display: flex !important;
}
[data-fas-nav-expanded] {
  display: none !important;
}
@media (min-width: 1024px) {
  [data-fas-nav-compact] {
    display: none !important;
  }
  [data-fas-nav-expanded] {
    display: flex !important;
  }
}

/* --- 4d. TrustStrip row reflow ------------------------------------------- */
/* Row direction is desktop default; mobile flips to column. Item dividers
 * also swap: vertical right-border between row items on desktop, horizontal
 * bottom-border between stacked items on mobile. */
[data-fas-trust-row] {
  flex-direction: row !important;
}
[data-fas-trust-item-divider] {
  border-right-width: 1px !important;
  border-right-style: solid !important;
  border-right-color: rgba(0, 0, 0, 0.1) !important;
}
@media (max-width: 767px) {
  [data-fas-trust-row] {
    flex-direction: column !important;
  }
  [data-fas-trust-item-divider] {
    border-right-width: 0 !important;
    border-bottom-width: 1px !important;
    border-bottom-style: solid !important;
    border-bottom-color: rgba(0, 0, 0, 0.1) !important;
    padding-bottom: 24px !important;
    margin-bottom: 8px !important;
  }
}

/* --- 4e. Search tab: desktop two-pane vs phone single-column ------------- */
/* app/(tabs)/search.web.tsx renders BOTH the desktop split and the phone
 * single-column layout in the DOM; CSS toggles which is visible. Same
 * render-both + @media pattern as SiteNav (§4c) and the footer (§4b). It
 * replaces the useIsDesktop() JS branch that SSR'd the phone layout
 * (useWindowDimensions = {width:0} in Node during static export) and forced a
 * desktop hydration mismatch (React #418) — the tree was regenerated on the
 * client, a race that intermittently dropped the search box on desktop. CSS
 * @media fires at first paint with the REAL viewport, so the correct layout is
 * rendered with no hydration race. 1024px == breakpoints.lg (the same
 * threshold lib/responsive useIsDesktop / useIsWideViewport use). */
[data-fas-search-desktop] {
  display: none !important;
}
[data-fas-search-mobile] {
  display: flex !important;
}
@media (min-width: 1024px) {
  [data-fas-search-desktop] {
    display: flex !important;
  }
  [data-fas-search-mobile] {
    display: none !important;
  }
}

/* --- 5. Microinteractions ------------------------------------------------ */
@media (hover: hover) and (pointer: fine) {
  [data-fas-hover-lift] {
    transition:
      transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
      box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1) !important;
    will-change: transform !important;
  }
  [data-fas-hover-lift]:hover {
    transform: translateY(-2px) !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18) !important;
  }
  [data-fas-hover-lift]:active {
    transform: translateY(0) !important;
  }

  [data-fas-hover-underline] {
    position: relative !important;
  }
  [data-fas-hover-underline]::after {
    content: "" !important;
    position: absolute !important;
    left: 0 !important;
    right: 0 !important;
    bottom: -2px !important;
    height: 2px !important;
    background-color: currentColor !important;
    transform: scaleX(0) !important;
    transform-origin: left center !important;
    transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1) !important;
  }
  [data-fas-hover-underline]:hover::after {
    transform: scaleX(1) !important;
  }
}

/* --- 5b. Touch active states -------------------------------------------- */
/* `:hover` is unreliable on touch devices (taps can leave hover stuck).
 * `(pointer: coarse)` targets touch-primary devices specifically so we
 * apply press feedback only when a finger is the input. The active state
 * mirrors the desktop hover-lift so iPhone visitors get the same tactile
 * microinteraction Apple users expect — translateY + scale + shadow on
 * tap-down, snaps back on release. Apple-parity. */
@media (pointer: coarse) {
  [data-fas-hover-lift] {
    transition:
      transform 150ms cubic-bezier(0.16, 1, 0.3, 1),
      box-shadow 150ms cubic-bezier(0.16, 1, 0.3, 1) !important;
  }
  [data-fas-hover-lift]:active {
    transform: translateY(-2px) scale(0.98) !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22) !important;
  }
  [data-fas-hover-underline]:active {
    opacity: 0.7 !important;
  }
}

/* --- 6. Focus rings (keyboard a11y) -------------------------------------- */
/* Apple-parity: every interactive element gets a visible focus ring on
 * keyboard navigation. WCAG 2.4.13 minimum is 2px outline at 3:1 contrast;
 * we use 3px Agency Red for stronger visibility. The :focus-visible
 * pseudo-class fires only for keyboard focus, not mouse clicks — so
 * clicking a button doesn't paint an ugly ring around it.
 *
 * Selector targets every ARIA role we use anywhere in the tree, plus
 * native interactive elements (button, a, input, textarea, select).
 * Previously scoped to [data-fas-hero-content] and [data-fas-section];
 * SiteNav, MobileNavDrawer, AddressInput dropdown, AnimatedSignalTicker
 * dots, and SmartAppBanner close button were all uncovered. */
[role="button"]:focus-visible,
[role="link"]:focus-visible,
[role="combobox"]:focus-visible,
[role="option"]:focus-visible,
[role="menuitem"]:focus-visible,
[role="tab"]:focus-visible,
[role="checkbox"]:focus-visible,
[role="radio"]:focus-visible,
[role="switch"]:focus-visible,
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid #ed2127 !important;
  outline-offset: 3px !important;
  border-radius: 4px !important;
  /* Defense in depth: some RN-Web atomic classes set outline:none.
   * Box-shadow ring as a backup so the ring is always visible even if
   * outline is suppressed somewhere. */
  box-shadow: 0 0 0 3px rgba(237, 33, 39, 0.15) !important;
}

/* --- 6a. FieldShell inputs draw their own focus border ------------------ */
/* Every text field in the app lives inside a FieldShell (components/ui/inputs/
 * FieldShell.tsx), whose 1px chassis border animates to Agency Red on focus —
 * that color shift IS the focus indicator (the search box uses exactly this).
 * For a text <input>/<textarea>, :focus-visible matches even on tap, so the §6
 * ring above would paint a SECOND red rounded rectangle 3px outside that border
 * (outline-offset), the doubled "secondary border" reported on the form fields.
 * Suppress the global ring + the browser's own focus / tap chrome for inputs
 * that carry FieldShell's border (marked data-fas-field). Inputs without their
 * own border are not matched here, so they keep the §6 ring. */
[data-fas-field] input,
[data-fas-field] textarea {
  -webkit-tap-highlight-color: transparent !important;
  -webkit-appearance: none !important;
  appearance: none !important;
}
[data-fas-field] input:focus,
[data-fas-field] input:focus-visible,
[data-fas-field] textarea:focus,
[data-fas-field] textarea:focus-visible {
  outline: none !important;
  box-shadow: none !important;
}

/* --- 6b. Address autocomplete listbox: active option highlight ---------- */
/* When the user keyboard-navigates suggestions (ArrowUp/Down) or mouse-
 * hovers, AddressInput sets aria-selected="true" on the active option.
 * This rule paints a subtle background so visual users see what the
 * keyboard / screen reader is on. Color is the muted brand background
 * (rgba sampled from colors.muted in design/tokens.ts). */
[data-fas-address-option][aria-selected="true"] {
  background-color: rgba(237, 33, 39, 0.08) !important;
}

/* --- 6c. Listings carousel + cards -------------------------------------- */
/* Web-only polish for the cross-platform ListingsCarousel + ListingCard.
 * RN-Web maps ScrollView horizontal to overflow-x: auto by default, but
 * scroll-snap-type isn't always set — pin it explicitly for crisp snap.
 * The native iOS / Android paths already get this from snapToInterval
 * + decelerationRate="fast" via the native scroll view. */
[data-fas-listings-carousel] > div[role="list"],
[data-fas-listings-carousel] > div > div[role="list"] {
  scroll-snap-type: x mandatory !important;
  scroll-behavior: smooth !important;
  /* Mouse-drag cursor cue. RN-Web doesn't expose pointer events on
   * ScrollView; we get touch + trackpad + wheel for free. Mouse drag
   * uses the standard scrollbar (visually hidden) + click-to-scroll. */
  cursor: grab !important;
}
[data-fas-listings-carousel] > div[role="list"]:active,
[data-fas-listings-carousel] > div > div[role="list"]:active {
  cursor: grabbing !important;
}

/* Card snap target — each card aligns to the start of the scroll
 * container. Belt-and-braces with the JS snapToInterval. */
[data-fas-listing-card] {
  scroll-snap-align: start !important;
  scroll-snap-stop: always !important;
}

/* Photo-gallery prev/next arrows: present in DOM for a11y + keyboard
 * but visually hidden until pointer-fine-hover. On touch devices the
 * swipe gesture is the primary nav so arrows stay hidden. */
[data-fas-gallery-nav] {
  opacity: 0 !important;
  pointer-events: none !important;
  transition: opacity 200ms cubic-bezier(0.16, 1, 0.3, 1) !important;
}
@media (hover: hover) and (pointer: fine) {
  [data-fas-gallery-nav] {
    opacity: 1 !important;
    pointer-events: auto !important;
  }
  /* Subtle entrance: dim until the gallery itself is hovered, then
   * brighten. Keeps the chrome quiet by default. */
  [data-fas-listing-card] [data-fas-gallery-nav] {
    opacity: 0 !important;
  }
  [data-fas-listing-card]:hover [data-fas-gallery-nav] {
    opacity: 1 !important;
  }
}

/* Photo lightbox: prev/next arrows stay visible at all times — this is
 * the dedicated photo-browsing surface, not a card-hover affordance.
 * The selector is more specific than the base [data-fas-gallery-nav]
 * rule above, so it wins. */
[data-fas-photo-lightbox] [data-fas-gallery-nav] {
  opacity: 1 !important;
  pointer-events: auto !important;
}

@media (hover: hover) and (pointer: fine) {
  /* Card hover lift — same Compass-shadow pattern as data-fas-hover-lift
   * but scoped to listing cards so we can layer it over the existing
   * RN getShadow("md") without conflicting with hero CTAs. */
  [data-fas-listing-card] {
    transition:
      transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
      box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1) !important;
    will-change: transform !important;
  }
  [data-fas-listing-card]:hover {
    transform: translateY(-3px) !important;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.14) !important;
  }
  [data-fas-listing-card]:active {
    transform: translateY(-1px) !important;
  }
}

@media (pointer: coarse) {
  [data-fas-listing-card] {
    transition: transform 150ms cubic-bezier(0.16, 1, 0.3, 1) !important;
  }
  [data-fas-listing-card]:active {
    transform: translateY(-2px) scale(0.99) !important;
  }
}

/* --- 7. Reduced-motion accommodations ------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  /* Hide the autoplay video (motion source); reveal the static poster
   * so the hero composition stays visually intact instead of going
   * black. Apple-parity for reduced-motion users. */
  [data-fas-hero-video] {
    display: none !important;
  }
  [data-fas-hero-poster] {
    display: block !important;
  }
  [data-fas-hover-lift],
  [data-fas-hover-lift]:hover,
  [data-fas-hover-underline]::after,
  [data-fas-listing-card],
  [data-fas-listing-card]:hover {
    transition: none !important;
    transform: none !important;
  }
  [data-fas-listings-carousel] > div[role="list"],
  [data-fas-listings-carousel] > div > div[role="list"] {
    scroll-behavior: auto !important;
  }
}

/* --- 8. Print stylesheet (compliance review prints /methodology, /legal/*) */
@media print {
  [data-fas-hero-video],
  [data-fas-hero-overlay] {
    display: none !important;
  }
  [data-fas-hero-shell] {
    background: white !important;
    color: black !important;
  }
  [data-fas-nav-bar] {
    display: none !important;
  }
  /* Footer stays visible in print: it carries the VOW MLS attribution +
   * brokerage credit + REALTOR/MLS trademark notices that compliance
   * reviewers expect on the printed copy. */
}

/* --- 9. Legal/methodology inline links ---------------------------------- */
/* Apple-pattern inline link: subtle default underline in body color, color
 * shift to agencyRed on hover, focus-visible ring for keyboard users.
 * Cubic-bezier 0.16 1 0.3 1 is the locked Apple curve per CLAUDE.md §5.
 * RN-Web's atomic classes have higher CSS specificity than plain selectors
 * so !important is required. */
[data-fas-inline-link] {
  color: #000 !important;
  text-decoration-line: underline !important;
  text-decoration-color: rgba(0, 0, 0, 0.35) !important;
  text-underline-offset: 3px !important;
  text-decoration-thickness: 1px !important;
  cursor: pointer !important;
  transition:
    color 200ms cubic-bezier(0.16, 1, 0.3, 1),
    text-decoration-color 200ms cubic-bezier(0.16, 1, 0.3, 1) !important;
}
@media (hover: hover) and (pointer: fine) {
  [data-fas-inline-link]:hover {
    color: #ed2127 !important;
    text-decoration-color: #ed2127 !important;
  }
}
[data-fas-inline-link]:focus-visible {
  outline: 2px solid #ed2127 !important;
  outline-offset: 3px !important;
  border-radius: 2px !important;
}

/* --- 10. Legal table horizontal-scroll on narrow viewports -------------- */
/* Privacy §4.2 service-provider table is 3 columns. On a narrow phone
 * viewport (<560px) cells would shrink under flex:1 and string content
 * wraps awkwardly. Container gets overflow-x: auto, table has minWidth
 * via inline style so it overflows below 560px and scrolls. */
[data-fas-table-scroll] {
  overflow-x: auto !important;
  -webkit-overflow-scrolling: touch !important;
}

/* --- 11. Property-page tour layout (two-column, sticky rail, slim bar) --- */
/* The inline tour form sits in a two-column grid on web at >=1024: listing
 * content (including the photo hero) on the left, the tour card in a sticky
 * right rail that persists as the reader scrolls. Below 1024 the rail is
 * hidden and an inline form shows in the content column instead. CSS-grid
 * keyed on data attributes (not JS breakpoints) so first paint is correct,
 * mirroring [data-fas-hero-split] above. */
[data-fas-prop-layout] {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) !important;
  width: 100% !important;
  max-width: 1280px !important;
  margin-left: auto !important;
  margin-right: auto !important;
  /* Clear the fixed section-nav (60px) that sits above the content on web. */
  margin-top: 60px !important;
  box-sizing: border-box !important;
  /* overflow:visible is required for the sticky rail. A clipping ancestor
     (RN-Web Views can clip) would trap the sticky context and the rail
     would not follow the scroll. */
  overflow: visible !important;
}
[data-fas-prop-layout] > * {
  min-width: 0 !important;
  max-width: 100% !important;
  overflow: visible !important;
}
@media (min-width: 1024px) {
  [data-fas-prop-layout] {
    /* No align-items override: the default `stretch` makes the rail cell as
       tall as the content column, which is exactly what gives the sticky rail
       room to travel. align-items:start collapses the cell to the card's own
       height, so the rail cannot follow the scroll (the bug we just fixed). */
    grid-template-columns: minmax(0, 1fr) 380px !important;
    column-gap: 40px !important;
  }
}
/* Tour rail follows the scroll via JS (transform), NOT CSS sticky. RN-Web's
   ScrollView owns the overflow scroll-container, so a `position: sticky` child
   binds to a div that doesn't actually scroll and never sticks (it degrades to
   relative). The page drives translateY on this node on scroll instead, clamped
   to the content column. See the follow effect in app/property/[id].tsx. */
[data-fas-prop-rail-inner] {
  will-change: transform !important;
}

/* Section quick-nav bar (web): fixed to the viewport top so it stays put as the
   reader scrolls (same RN-Web sticky limitation as the rail, so we use fixed +
   a matching top margin on the layout below). */
[data-fas-prop-section-nav] {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 1095 !important;
}
/* Below 1024 there is no room for a rail: hide it, show the inline form. */
@media (max-width: 1023px) {
  [data-fas-prop-rail] {
    display: none !important;
  }
}
/* At 1024+ the sticky rail is the booking surface, so drop the inline form. */
@media (min-width: 1024px) {
  [data-fas-prop-inline-form] {
    display: none !important;
  }
}

/* Slim "Request a tour" bar. Native renders RN position:absolute; on web we
 * pin it to the viewport below the SiteNav with the iOS safe-area inset, and
 * hide it at 1024+ where the sticky rail replaces it. Hidden in print. */
[data-fas-tour-jump] {
  position: fixed !important;
  z-index: 1090 !important;
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 8px) !important;
}
@media (min-width: 1024px) {
  [data-fas-tour-jump] {
    display: none !important;
  }
}
@media print {
  [data-fas-tour-jump] {
    display: none !important;
  }
}

/* Date strip (DateStripInput): hide the scrollbar and show a grab cursor. */
[data-fas-date-strip] {
  scrollbar-width: none !important;
  cursor: grab !important;
}
[data-fas-date-strip]::-webkit-scrollbar {
  display: none !important;
}
