/* ai-search.css
 * ---------------------------------------------------------------------------
 * Index page: replaces the top search bar with a central AI chat box. The
 * notifications bell now lives in the RIGHT slot of the shared
 * `.create-listing-topbar` component (create-listing-topbar.css), so the
 * options arrow (`.home-map-mobile-controls`) and the notification dropdown
 * are anchored to `var(--topbar-top)` — they stay perfectly centred under the
 * bell on every viewport. Loaded LAST so it wins the cascade against the
 * minified home-map.css bundle. Everything is scoped to `body.index-page`.
 * ------------------------------------------------------------------------- */

/* ===== 1. Retire the old location search bar ==============================
 * The DOM nodes stay in place (index-map.js binds its geocoder to them and the
 * AI flow reuses that engine), but they are never shown. */
body.index-page .home-map-search,
body.index-page #homeMapSearch,
body.index-page .home-map-search-suggestions,
body.index-page #homeMapSearchSuggestions {
  display: none !important;
}

/* ===== 2. Options arrow: reuse the mobile controls on desktop too ==========
 * The element is always in the DOM (br() runs on every viewport); the mobile
 * bundle only reveals it under a media query. Re-assert it for every viewport,
 * stacked directly under the bell: the bell button is 48px tall inside the
 * topbar, so the arrow's centre must follow --topbar-top + 58px (button 48px
 * + 10px gap). Horizontally, the controls column is pinned to 48px wide, so
 * right:16px (the topbar side padding) centres it — and the 38px arrow toggle —
 * exactly under the 48px bell button on every viewport. */
body.index-page .home-map-mobile-controls {
  display: flex !important;
  position: absolute !important;
  top: calc(var(--topbar-top, 20px) + 58px) !important;
  right: 16px !important;
  bottom: auto !important;
  left: auto !important;
  z-index: 7 !important;
  width: 48px !important;
  flex-direction: column-reverse !important;
  align-items: center !important;
  gap: 8px !important;
  pointer-events: none !important;
}

body.index-page .home-map-mobile-controls__panel {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  width: 42px !important;
  gap: 8px !important;
  pointer-events: auto !important;
}

body.index-page .home-map-mobile-controls__panel[hidden] {
  display: none !important;
}

/* The mobile bundle keeps the arrow/button visuals inside a max-width media
 * query, so on wider desktops they'd be unstyled (0px, invisible). Re-declare
 * them here, viewport-agnostic, mirroring the mobile look exactly. */
body.index-page .home-map-mobile-controls__toggle {
  position: relative;
  width: 38px;
  height: 38px;
  border: 0;
  background: transparent;
  color: #172230e0;
  cursor: pointer;
  pointer-events: auto;
  outline: none;
  box-shadow: none;
  -webkit-tap-highlight-color: transparent;
  filter: drop-shadow(0 6px 16px rgba(18, 27, 40, .26)) drop-shadow(0 0 10px rgba(255, 255, 255, .18));
}
:root[data-theme=night] body.index-page .home-map-mobile-controls__toggle {
  color: #eef4fb;
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, .34)) drop-shadow(0 0 10px rgba(238, 244, 251, .14));
}
body.index-page .home-map-mobile-controls__toggle-icon {
  position: absolute;
  inset: 0;
  display: block;
}
body.index-page .home-map-mobile-controls__toggle-icon:before,
body.index-page .home-map-mobile-controls__toggle-icon:after {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 2.5px;
  border-radius: 999px;
  background: currentColor;
  content: "";
  transform-origin: center;
  transition: transform .24s ease, opacity .24s ease;
}
body.index-page .home-map-mobile-controls__toggle-icon:before {
  transform: translate(calc(-50% - 4px), -50%) rotate(45deg);
}
body.index-page .home-map-mobile-controls__toggle-icon:after {
  transform: translate(calc(-50% + 4px), -50%) rotate(-45deg);
}
body.index-page .home-map-mobile-controls__toggle.is-open .home-map-mobile-controls__toggle-icon:before {
  transform: translate(-50%, -50%) rotate(45deg);
}
body.index-page .home-map-mobile-controls__toggle.is-open .home-map-mobile-controls__toggle-icon:after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

body.index-page .home-map-mobile-controls__button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 44px;
  min-height: 44px;
  padding: 2px 0;
  border: 1px solid var(--liquid-glass-border);
  border-radius: 999px;
  background: var(--liquid-glass-surface-strong);
  box-shadow: var(--liquid-glass-shadow);
  backdrop-filter: blur(18px) saturate(145%);
  -webkit-backdrop-filter: blur(18px) saturate(145%);
  color: #172230;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  pointer-events: auto;
  overflow: hidden;
}
body.index-page .home-map-mobile-controls__button:before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--liquid-glass-top-sheen);
  pointer-events: none;
}
body.index-page .home-map-mobile-controls__button.is-active {
  box-shadow: var(--liquid-glass-shadow-reactive);
}
body.index-page .home-map-mobile-controls__button > * {
  position: relative;
  z-index: 1;
}
body.index-page .home-map-mobile-controls__button--mode {
  width: 44px;
  color: #172230;
  font-size: 12px;
  letter-spacing: .01em;
}
body.index-page .home-map-mobile-controls__button--mode .home-map-mobile-controls__label {
  display: inline;
  color: currentColor;
}
body.index-page .home-map-mobile-controls__label {
  display: none;
}
:root[data-theme=night] body.index-page .home-map-mobile-controls__button,
:root[data-theme=night] body.index-page .home-map-mobile-controls__button--mode {
  color: #eef4fb;
}

/* ===== 3. Hide the old desktop controls cluster (bottom-right) =============
 * The arrow panel now provides the same tools (ruler, building, compass,
 * locate, 3D) in one place, matching mobile. */
body.index-page .home-map-desktop-controls {
  display: none !important;
}

/* ===== 3b. Notification panel: anchor below the bell (desktop only) ========
 * On desktop the panel opens right underneath the bell, aligned to the right
 * edge. z-index must clear the nav pill (185) and the chat dock (200) — the
 * panel is the frontmost *page* surface while it is open.
 *
 * On phones it is NOT a dropdown: it is the Instagram-style bottom sheet that
 * notification-panel.css builds (handle, ~74dvh, drag to dismiss). Everything
 * geometric here therefore lives inside the desktop media query — otherwise
 * these !important declarations would flatten the sheet back into a dropdown
 * hanging off a bell the phone layout does not even anchor the same way.
 *
 * --mc-notification-anchor-drop is the distance from the top of the bell to the
 * top of the panel. The button is 48px tall and the panel slides in from -8px,
 * so the old 52px left only 4px of air — and none at all mid-animation, which
 * is what had the panel's rounded corner biting into the × the bell turns into.
 * 68px keeps a clean 12px gap at rest and still 4px at the start of the slide.
 * (Lifting the topbar above the panel instead is NOT an option: it drags its
 * ::before backdrop scrim over the panel and washes the first rows out.)
 *
 * --mc-notification-bottom-clear is the room the panel must leave free at the
 * bottom so it stops ABOVE the floating chat box (and, on mobile, the nav pill
 * under it) instead of running behind them: the dock's resting offset + its own
 * height + a 12px breathing gap. Desktop: 26px + 74px + 12px. */
body.index-page {
  --mc-notification-anchor-drop: 68px;
  --mc-notification-bottom-clear: 112px;
}
/* Open state: the bell has already swapped its icon for the × (home-map.css) —
 * fill the button too, so it reads as a lit-up "close" control rather than a
 * bare × floating over the map. */
body.index-page .home-map-notifications[aria-expanded="true"] {
  background: var(--liquid-glass-item-active-bg, rgba(255, 255, 255, .18));
  border-color: var(--liquid-glass-inner-border);
}
/* Column layout so the scrolling body simply takes whatever height is left
   under the header — no second max-height to keep in sync. Shared by the
   dropdown and the sheet, so it stays outside the media query. */
body.index-page .notification-panel {
  display: flex;
  flex-direction: column;
}
/* The panel is mounted with the `hidden` attribute and its own stylesheet
   (notification-panel.css) is lazy-loaded. Until that stylesheet arrives, the
   display:flex above would override [hidden] and paint the whole panel under
   the bell on every refresh. This guard makes [hidden] win from first paint. */
body.index-page .notification-panel[hidden] {
  display: none !important;
}
body.index-page .notification-panel__body {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none !important;
}

@media (min-width: 900.99px) {
  body.index-page .notification-panel {
    top: calc(var(--topbar-top, 20px) + var(--mc-notification-anchor-drop)) !important;
    right: 16px !important;
    bottom: auto !important;
    left: auto !important;
    z-index: 210 !important;
    width: min(430px, calc(100vw - 32px)) !important;
    max-height: calc(
      100dvh - var(--topbar-top, 20px) - var(--mc-notification-anchor-drop) -
        var(--mc-notification-bottom-clear)
    ) !important;
    border-radius: var(--mc-radius-panel, 34px) !important;
    transform: translateY(-8px) !important;
  }
  body.index-page .notification-panel.is-open {
    transform: translateY(0) !important;
  }
  /* Hide the bottom-sheet grabber on desktop — there the panel is a dropdown
   * anchored to the bell, not a draggable bottom sheet. */
  body.index-page .notification-panel__grabber {
    display: none !important;
  }
}

/* ===== 3c. Map stage background: match the globe theme =====================
 * In day mode the stage background must be light so it blends with the
 * Liberty map style instead of showing a black void behind the globe. */
:root[data-theme="day"] body.index-page .home-map__stage {
  background: #f2efe9;
}

/* =========================================================================
 * 4. Central AI chat box (Gemini-style)
 * -------------------------------------------------------------------------
 * States are driven by two data-attributes on `.ai-search`:
 *   data-pos   = center | dock     (vertical placement)
 *   data-scrim = on | off          (globe blur + conversation visibility)
 * The whole layer sits BELOW the toolbar/arrow (z-index 5 < 6/7) so the bell
 * and options arrow stay crisp and clickable above the scrim.
 * ===================================================================== */
@property --ai-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }

body.index-page .ai-search {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;               /* only children capture clicks */
}

/* --- scrim: blurs/dims the globe when the box is engaged --------------- */
body.index-page .ai-search__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(circle at 50% 42%, rgba(8,11,16,.20), rgba(8,11,16,.42));
  -webkit-backdrop-filter: blur(11px) saturate(112%);
  backdrop-filter: blur(11px) saturate(112%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .5s ease, visibility .5s ease;
}
body.index-page .ai-search[data-scrim="on"] .ai-search__scrim {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* --- dock: positioned wrapper (thread + input) ------------------------ */
body.index-page .ai-search__dock {
  position: absolute;
  z-index: 2;
  left: 50%;
  width: min(680px, calc(100% - 40px));
  display: flex;
  flex-direction: column;
  gap: 12px;
  pointer-events: none;               /* children re-enable */
  transition: top .55s cubic-bezier(.22,1,.36,1), bottom .55s cubic-bezier(.22,1,.36,1), transform .55s cubic-bezier(.22,1,.36,1);
}
body.index-page .ai-search[data-pos="center"] .ai-search__dock {
  top: 50%;
  transform: translate(-50%, -54%);
}
/* Docked, the wrapper spans from just under the top toolbar down to its resting
 * offset, so its height is DEFINITE. That is what lets the conversation run all
 * the way up the screen instead of stopping at an arbitrary fraction of it: the
 * thread simply takes the room the input pill doesn't need (justify-content
 * keeps the pill glued to the bottom), and shrinks instead of pushing itself off
 * the top when the pill grows to several lines.
 * --ai-dock-clear matches the notification panel's own drop (68px) plus 12px of
 * air, so the chat and the panel stop on the same line. */
body.index-page .ai-search[data-pos="dock"] .ai-search__dock {
  top: var(--ai-dock-clear, 80px);
  bottom: 26px;
  transform: translateX(-50%);
  justify-content: flex-end;
}

/* --- conversation thread --------------------------------------------- */
body.index-page .ai-search__thread {
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 0 1 auto;
  min-height: 0;                      /* required, or a flex item never shrinks */
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height .5s cubic-bezier(.22,1,.36,1), opacity .4s ease;
}
body.index-page .ai-search.is-thread-open .ai-search__thread {
  /* Everything left over: the clearance above, the gap, a typical input pill and
     the dock's resting offset. A taller pill is absorbed by the shrink above. */
  max-height: calc(100dvh - var(--ai-dock-clear, 80px) - 120px);
  overflow-y: auto;
  opacity: 1;
  padding: 2px;
}
/* After a result the globe is revealed (scrim off) and only the LAST reply
 * peeks over it, so the guest sees the map without losing what was said.
 * Uses a fixed max-height (not "none") so the collapse transition animates. */
body.index-page .ai-search.is-thread-peek .ai-search__thread {
  max-height: 120px;
  overflow: hidden;
  opacity: 1;
  padding: 2px;
  pointer-events: none;               /* clicks fall through to the globe/markers */
}
body.index-page .ai-search.is-thread-peek .ai-search__thread > .ai-search__msg {
  display: none;
}
body.index-page .ai-search.is-thread-peek .ai-search__thread > .ai-search__msg:last-child {
  display: -webkit-box;
  -webkit-line-clamp: 3;             /* keep the caption compact over the map */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body.index-page .ai-search.is-thread-peek .ai-search__msg--ai {
  box-shadow: 0 16px 44px rgba(4, 7, 12, .55);
}
/* --- scrollbars: the thumb and nothing else ---------------------------
 * Both scrollers float over the globe, where a native Windows scrollbar cuts a
 * hard white rectangle with two arrow buttons through the glass. Track and
 * buttons go; only a thin rounded thumb stays. The thread sits over the dark
 * scrim (light thumb) and the input inside the pale pill (grey thumb), so they
 * get their own colours.
 *
 * The two syntaxes do NOT stack, and the standard one WINS where it exists — so
 * it is fenced off to the engines that have nothing else (Firefox). Chrome sees
 * `scrollbar-color` and switches to a scrollbar that it draws WITH arrow buttons
 * (tinted from these very colours), ignoring ::-webkit-scrollbar-button
 * altogether: that is where the arrows came from. Behind the @supports, Chrome
 * and Safari take the pseudo-element path below, which has no buttons at all. */
@supports not selector(::-webkit-scrollbar) {
  body.index-page .ai-search__thread,
  body.index-page .ai-search__input {
    scrollbar-width: thin;
  }
  body.index-page .ai-search__thread { scrollbar-color: rgba(255, 255, 255, .42) transparent; }
  body.index-page .ai-search__input  { scrollbar-color: rgba(128, 138, 152, .5) transparent; }
}

body.index-page .ai-search__thread::-webkit-scrollbar,
body.index-page .ai-search__input::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
body.index-page .ai-search__thread::-webkit-scrollbar-track,
body.index-page .ai-search__input::-webkit-scrollbar-track,
body.index-page .ai-search__thread::-webkit-scrollbar-corner,
body.index-page .ai-search__input::-webkit-scrollbar-corner {
  background: transparent;
}
/* The up/down arrows at each end. */
body.index-page .ai-search__thread::-webkit-scrollbar-button,
body.index-page .ai-search__input::-webkit-scrollbar-button {
  display: none;
  width: 0;
  height: 0;
}
body.index-page .ai-search__thread::-webkit-scrollbar-thumb,
body.index-page .ai-search__input::-webkit-scrollbar-thumb {
  border-radius: 999px;
}
body.index-page .ai-search__thread::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .42); }
body.index-page .ai-search__thread::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .62); }
body.index-page .ai-search__input::-webkit-scrollbar-thumb { background: rgba(128, 138, 152, .5); }
body.index-page .ai-search__input::-webkit-scrollbar-thumb:hover { background: rgba(128, 138, 152, .72); }

body.index-page .ai-search__msg {
  max-width: 86%;
  padding: 10px 14px;
  border-radius: 18px;
  font-size: .92rem;
  line-height: 1.46;
  white-space: pre-wrap;
  word-break: break-word;
  animation: ai-msg-in .32s ease both;
}
body.index-page .ai-search__msg--user {
  align-self: flex-end;
  background: linear-gradient(135deg, #e61e4d, #d70466);
  color: #fff;
  border-bottom-right-radius: 6px;
  box-shadow: 0 10px 24px rgba(214,4,102,.24);
}
body.index-page .ai-search__msg--ai {
  align-self: flex-start;
  background: var(--liquid-glass-surface-strong, rgba(220,229,238,.62));
  color: var(--theme-text, #101722);
  border: 1px solid var(--liquid-glass-border, rgba(255,255,255,.14));
  border-bottom-left-radius: 6px;
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: var(--liquid-glass-shadow, 0 14px 34px rgba(10,15,25,.28));
}
body.index-page .ai-search__msg--typing {
  color: var(--theme-text-muted, #6b7788);
  font-style: italic;
}
@keyframes ai-msg-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* --- description-search results --------------------------------------
 * Shown when the guest described the PROPERTY rather than a place ("uma casa
 * renovada dos anos 1900"): the globe cannot answer that, so the matching
 * listings are surfaced right in the thread, each with the fragment of its
 * description that matched. Same glass as the AI bubble, so the results read
 * as part of the reply rather than as a separate widget. */
body.index-page .ai-search__results {
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  max-width: 100%;
  animation: ai-msg-in .32s ease both;
}
body.index-page .ai-search__result {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  border-radius: 18px;
  background: var(--liquid-glass-surface-strong, rgba(220,229,238,.62));
  border: 1px solid var(--liquid-glass-border, rgba(255,255,255,.14));
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: var(--liquid-glass-shadow, 0 14px 34px rgba(10,15,25,.28));
}
/* The shared preview card brings its own frame; inside this one it is just the
   content, so the double border and double shadow come off.

   It also lies DOWN here. The conversation panel is wide and short, so the
   card's usual photo-on-top shape spent all the width on nothing and all the
   height on one photo. Scoped to this card only — the map popup and the search
   grid keep their upright shape.

   The card itself stays `position: relative` (it is the containing block for
   its own full-surface link, which is absolute with inset:0 — left static, that
   link resolves against the page and covers the viewport). */
body.index-page .ai-search__result .map-preview-card--grid {
  border: 0;
  box-shadow: none;
  background: transparent;
  width: 100%;
  display: flex;
  align-items: stretch;
  gap: 12px;
}
body.index-page .ai-search__result .map-preview-card__gallery {
  flex: 0 0 38%;
  /* Bounded both ways: unbounded it eats a narrow sheet on a phone, and on a
     wide dock it grows into the vertical card this replaced. */
  min-width: 108px;
  max-width: 168px;
  align-self: flex-start;
}
body.index-page .ai-search__result .map-preview-card__body {
  flex: 1 1 auto;
  min-width: 0;
  padding: 2px 2px 0 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* Price sits at the foot of the column, level with the bottom of the photo. */
body.index-page .ai-search__result .map-preview-card__divider {
  margin-top: auto;
}

/* --- host row, the same shape search.html puts above every result ------ */
body.index-page .ai-search__result-host {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 4px;
  text-decoration: none;
  color: var(--theme-text, #101722);
  min-width: 0;
}
body.index-page .ai-search__result-host-avatar {
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(120,132,148,.28);
  font-size: .74rem;
  font-weight: 700;
}
body.index-page .ai-search__result-host-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* display:flex with the name in its own span, or the ellipsis eats the badge. */
body.index-page .ai-search__result-host-name {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  font-size: .8rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.index-page .ai-search__result-host-badge {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
}

/* --- price row handed to the shared card ------------------------------ */
body.index-page .ai-search__result-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  margin: 0;
  font-size: .82rem;
}
body.index-page .ai-search__result-price strong {
  font-weight: 700;
}
body.index-page .ai-search__result-price-note {
  font-size: .72rem;
  font-weight: 500;
  color: var(--theme-text-muted, #6b7788);
}
body.index-page .ai-search__result-price-note em {
  font-style: normal;
}

/* --- "ver no mapa" ----------------------------------------------------- */
body.index-page .ai-search__result-map {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  align-self: stretch;
  padding: 7px 12px;
  border: 1px solid var(--liquid-glass-border, rgba(255,255,255,.22));
  border-radius: 999px;
  background: rgba(255,255,255,.28);
  color: var(--theme-text, #101722);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .18s ease, transform .18s ease;
}
body.index-page .ai-search__result-map:hover,
body.index-page .ai-search__result-map:focus-visible {
  background: rgba(255,255,255,.46);
  transform: translateY(-1px);
}
body.index-page .ai-search__result-map svg {
  width: 14px;
  height: 14px;
}
/* The collapsed peek over a clear globe shows only the last reply — result
 * cards would cover the very markers they point at. */
body.index-page .ai-search.is-thread-peek .ai-search__results { display: none; }

/* --- input box with animated Gemini border --------------------------- */
body.index-page .ai-search__box {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 6px 3px 20px;
  border-radius: 27px;
  background: var(--liquid-glass-surface, rgba(220,229,238,.62));
  border: 1px solid var(--liquid-glass-border, rgba(255,255,255,.14));
  box-shadow: var(--liquid-glass-shadow, 0 18px 44px rgba(10,15,25,.32));
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
  isolation: isolate;
}
body.index-page .ai-search__badge{display:inline-flex;align-items:center;justify-content:center;flex:0 0 22px;width:22px;height:22px;margin-right:2px;color:var(--theme-text-muted,#8e8e93)}body.index-page .ai-search__badge-icon{display:block;width:100%;height:100%}
body.index-page .ai-search[data-pos="center"] .ai-search__box {
  animation: ai-rise .6s cubic-bezier(.22,1,.36,1) both;
}
/* the spinning conic-gradient ring (same technique as checkout step 3) */
body.index-page .ai-search__box::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: 27px;
  padding: 1.7px;
  background: conic-gradient(from var(--ai-angle), #4285f4, #9b72cb, #e61e4d, #ff8fb3, #28c3ff, #4285f4);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: ai-spin 5s linear infinite;
  pointer-events: none;
  opacity: .92;
}
@keyframes ai-spin { to { --ai-angle: 360deg; } }
@keyframes ai-rise { from { opacity: 0; transform: translateY(20px) scale(.96); } to { opacity: 1; transform: none; } }

/* A registered custom property cannot be animated on the compositor, so this
   ring is a style recalc + repaint on every single frame, forever, on top of
   whatever the globe is doing. Anyone who asked for less motion gets the ring
   frozen mid-gradient — same colours, no per-frame cost. */
@media (prefers-reduced-motion: reduce) {
  body.index-page .ai-search__box::after { animation: none; }
}

body.index-page .ai-search__input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  resize: none;
  outline: none;
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
  color: var(--theme-text, #101722);
  max-height: 132px;
  padding: 10px 0 0;
  /* Explicit, so the bar exists only once the text really is taller than the
     field — never as a permanent gutter in an empty pill. */
  overflow-y: auto;
  overflow-x: hidden;
}
body.index-page .ai-search__input::placeholder { color: var(--theme-text-muted, #64707f); opacity: 1; }

body.index-page .ai-search__send {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(135deg, #e61e4d, #d70466);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform .16s ease, box-shadow .16s ease, opacity .16s ease;
  box-shadow: 0 8px 20px rgba(214,4,102,.3);
}
body.index-page .ai-search__send:hover { transform: translateY(-1px); }
body.index-page .ai-search__send:disabled { opacity: .5; cursor: default; box-shadow: none; }
body.index-page .ai-search__send svg { width: 22px; height: 22px; }

/* --- mobile: the input pill docks just above the nav pill; the conversation
 * floats ABOVE it as free bubbles (same as desktop, only bottom-anchored). The
 * pill keeps its own Gemini border — it never wraps the messages. ----------- */
@media (max-width: 900.98px) {
  /* parent must sit above the mobile nav (z-index 185) so the dock is visible */
  body.index-page .ai-search {
    z-index: 200 !important;
  }

  /* The chat pill rests at 84px (just above the nav pill) and is ~93px tall,
     so the notification panel has to stop 12px above that whole stack. */
  body.index-page {
    --mc-notification-bottom-clear: calc(190px + env(safe-area-inset-bottom));
  }

  body.index-page .ai-search__dock {
    /* !important beats the higher-specificity desktop data-pos rules */
    left: 50% !important;
    right: auto !important;
    /* Same span as desktop: pinned top AND bottom, so the conversation reaches
       the top of the screen and the pill stays put at the bottom. */
    top: var(--ai-dock-clear, 80px) !important;
    bottom: calc(84px + env(safe-area-inset-bottom)) !important;  /* rest just above the nav pill */
    z-index: 200 !important;
    transform: translateX(-50%) !important;
    width: min(420px, calc(100vw - 24px)) !important;  /* match the nav pill */
    flex-direction: column;                            /* messages above, input below */
    justify-content: flex-end;
    gap: 8px;
  }

  /* Focus lock: pin the pill to the viewport the instant the field is focused,
     BEFORE iOS scrolls the page up to reveal it (that native scroll is what
     stranded the pill at its nav-bar offset). Keeps the resting bottom, so there
     is no jump — the docked offset only arrives once the keyboard is up. */
  body.index-page .ai-search__dock.is-kb-lock {
    position: fixed !important;
    transition: none !important;
  }

  /* Keyboard open: the JS measures the real gap to the keyboard top and writes
     the exact bottom offset into --kb (self-correcting, so it stays flush even
     when iOS lies about innerHeight or the fixed reference frame). */
  body.index-page .ai-search__dock.is-keyboard {
    position: fixed !important;
    bottom: var(--kb, 0px) !important;
    transition: none !important;
  }

  /* conversation floats above the input pill, filling everything above it */
  body.index-page .ai-search.is-thread-open .ai-search__thread {
    max-height: calc(
      100dvh - var(--ai-dock-clear, 80px) - 84px - env(safe-area-inset-bottom) - 100px
    );
  }
  /* tapping the peeking reply re-opens the full conversation (replaces the grabber) */
  body.index-page .ai-search.is-thread-peek .ai-search__thread {
    pointer-events: auto;
    cursor: pointer;
  }
}
