body:is(.create-listing-page, .index-page) {
  --topbar-top: calc(20px + env(safe-area-inset-top));
  --topbar-button-size: 48px;
}

body:is(.create-listing-page, .index-page) .create-listing-topbar {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 150;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: var(--topbar-top) 16px 24px;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transform: none;
  pointer-events: none;
  transition: opacity .18s ease;
}

body:is(.create-listing-page, .index-page) .create-listing-topbar::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(100% + 120px);
  z-index: -1;
  background: var(--liquid-glass-surface);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  -webkit-mask-image: 
    linear-gradient(to bottom, black 10%, rgba(0, 0, 0, 0.92) 25%, rgba(0, 0, 0, 0.72) 45%, rgba(0, 0, 0, 0.4) 65%, rgba(0, 0, 0, 0.12) 85%, transparent 100%);
  mask-image: 
    linear-gradient(to bottom, black 10%, rgba(0, 0, 0, 0.92) 25%, rgba(0, 0, 0, 0.72) 45%, rgba(0, 0, 0, 0.4) 65%, rgba(0, 0, 0, 0.12) 85%, transparent 100%);
  pointer-events: none;
}

body.create-listing-page .create-listing-topbar::after {
  display: none;
}

body.create-listing-page .create-listing-topbar__title {
  position: absolute;
  left: 50%;
  top: var(--topbar-top);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--topbar-button-size);
  max-width: min(58%, 340px);
  min-width: 0;
  margin: 0;
  overflow: hidden;
  transform: translateX(-50%);
  color: var(--theme-text);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
}

body:is(.create-listing-page, .index-page) .create-listing-topbar__button {
  pointer-events: auto;
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--topbar-button-size);
  height: var(--topbar-button-size);
  min-width: var(--topbar-button-size);
  min-height: var(--topbar-button-size);
  border: 0;
  border-radius: 999px;
  color: var(--theme-text);
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform .16s ease, opacity .16s ease, background .16s ease, box-shadow .16s ease, color .16s ease;
}

/* Reuse the sidebar rail's liquid glass on the standalone close, any --glass
   button (the index page reuses this same chrome for "+" and the bell) and the
   action pill. The 1px edge is an inset ring (not a border) so it never grows
   the layout box, keeping every circle and the pill the same height. */
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--close,
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--glass,
body.create-listing-page .create-listing-topbar__actions {
  border: 0;
  border-radius: 999px;
  background: var(--liquid-glass-surface);
  box-shadow: var(--liquid-glass-shadow), inset 0 0 0 1px var(--liquid-glass-border);
  backdrop-filter: blur(26px) saturate(1.28);
  -webkit-backdrop-filter: blur(26px) saturate(1.28);
  isolation: isolate;
}
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--close::before,
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--glass::before,
body.create-listing-page .create-listing-topbar__actions::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--liquid-glass-top-sheen);
  pointer-events: none;
}
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--close::after,
body:is(.create-listing-page, .index-page) .create-listing-topbar__button--glass::after,
body.create-listing-page .create-listing-topbar__actions::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  border: 1px solid var(--liquid-glass-inner-border);
  pointer-events: none;
}

body:is(.create-listing-page, .index-page) .create-listing-topbar__button:focus-visible {
  outline: 2px solid rgba(255, 255, 255, .42);
  outline-offset: 3px;
}

body:is(.create-listing-page, .index-page) .create-listing-topbar__button:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px rgba(255, 255, 255, .34),
    inset 0 -1px rgba(0, 0, 0, .18),
    0 14px 30px rgba(0, 0, 0, .28);
}

body:is(.create-listing-page, .index-page) .create-listing-topbar__button:active {
  transform: scale(.95);
}
body.create-listing-page .create-listing-topbar__button--close span,
body.create-listing-page .create-listing-topbar__button--close span::before,
body.create-listing-page .create-listing-topbar__button--close span::after {
  display: block;
  content: "";
}

body.create-listing-page .create-listing-topbar__button--close span,
body.create-listing-page .create-listing-topbar__button--close span::before {
  width: 22px;
  height: 2.5px;
  border-radius: 999px;
  background: currentColor;
}

body.create-listing-page .create-listing-topbar__button--close span {
  position: relative;
  transform: rotate(45deg);
}

body.create-listing-page .create-listing-topbar__button--close span::before {
  position: absolute;
  top: 0;
  left: 0;
  transform: rotate(90deg);
}


/* Grouped action pill (Apple-style) holding the hamburger */
body.create-listing-page .create-listing-topbar__actions {
  pointer-events: none;
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
}

body.create-listing-page .create-listing-topbar__actions {
  padding: 4px;
  gap: 4px;
}

body.create-listing-page .create-listing-topbar__actions .create-listing-topbar__button {
  width: calc(var(--topbar-button-size) - 8px);
  height: calc(var(--topbar-button-size) - 8px);
  min-width: calc(var(--topbar-button-size) - 8px);
  min-height: calc(var(--topbar-button-size) - 8px);
}

/* Hamburger reuses the sidebar glyph markup + its 3-bars<->X animation */
body.create-listing-page .create-listing-topbar__button--menu[aria-expanded="true"] .desktop-sidebar__menu-glyph span {
  background: transparent;
}
body.create-listing-page .create-listing-topbar__button--menu[aria-expanded="true"] .desktop-sidebar__menu-glyph span::before {
  top: 0;
  transform: rotate(45deg);
}
body.create-listing-page .create-listing-topbar__button--menu[aria-expanded="true"] .desktop-sidebar__menu-glyph span::after {
  top: 0;
  transform: rotate(-45deg);
}
/* Night theme forces every bar to #eef4fb and only clears the middle bar for
   [data-menu-toggle] toggles; ours isn't one, so restate the reset with higher
   specificity to avoid the extra middle stroke in the X. */
:root[data-theme="night"] body.create-listing-page .create-listing-topbar__button--menu[aria-expanded="true"] .desktop-sidebar__menu-glyph span {
  background: transparent;
}

/* Match the bottom nav's icon presence (25px there): widen the hamburger glyph
   from the desktop sidebar's 18px bars to 22px inside this topbar only. */
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph {
  width: 26px;
  height: 20px;
}
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph span,
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph span::before,
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph span::after {
  width: 22px;
  height: 3.4px;
}
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph span::before {
  top: -8px;
}
body.create-listing-page .create-listing-topbar__button--menu .desktop-sidebar__menu-glyph span::after {
  top: 8px;
}

/* Dropdown bubble reuses .mobile-menu-panel; only repositioned below the topbar */
body.create-listing-page #createListingTopbarMenu {
  position: absolute;
  top: calc(100% - 12px);
  right: 12px;
  bottom: auto;
  left: auto;
  z-index: 40;
  width: min(272px, calc(100vw - 24px));
  height: auto;
  max-height: min(60vh, calc(100dvh - 130px));
  overflow-y: auto;
  padding: 10px 0;
  border: 1px solid var(--liquid-glass-border);
  border-radius: var(--mc-radius-popover, 22px);
  box-shadow: var(--liquid-glass-shadow);
  transform: translateY(-8px);
}
/* The panel INHERITS pointer-events: none from its parent <header>
   (.create-listing-topbar, line 26) — not from the sibling __actions rule.
   Normally .mobile-menu-panel.is-open re-enables it, but that rule lives in
   menu-panel.css, which this page never links statically; site-ui.js injects it
   under requestIdleCallback, so the menu would be click-through for the first
   ~1.8s. A direct declaration on the element beats inheritance outright.
   The closed state needs no counterpart: it simply keeps inheriting none. */
body.create-listing-page #createListingTopbarMenu.is-open {
  pointer-events: auto;
  transform: translateY(0);
}

body.create-listing-page .create-listing-page__hero {
  display: none;
}

body.create-listing-page.create-listing-mobile-preview-open .create-listing-topbar {
  opacity: 0;
  pointer-events: none;
  transform: translate3d(-50%, -10px, 0);
}
/* The close + action pill now inherit the sidebar's theme-aware liquid glass
   variables. */

@media (min-width: 901px) {
  /* Desktop now uses the same confirm (checkmark) as mobile to publish, so it
     stays visible here alongside the menu. */
  body.create-listing-page .create-listing-page__main {
    padding-top: calc(96px + env(safe-area-inset-top));
  }
}

@media (max-width: 900px) {
  body:is(.create-listing-page, .index-page) {
    --topbar-button-size: 48px;
    --topbar-top: calc(7px + env(safe-area-inset-top));
  }

  /* Mobile topbar inherits full width and flex layout from global */

  body.create-listing-page .create-listing-page__main,
  body.create-listing-page.has-mobile-tabbar .create-listing-page__main {
    padding-top: calc(84px + env(safe-area-inset-top));
  }
}

@media (max-width: 360px) {
  body.create-listing-page .create-listing-topbar__title {
    font-size: .88rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  body:is(.create-listing-page, .index-page) .create-listing-topbar,
  body:is(.create-listing-page, .index-page) .create-listing-topbar__button {
    transition-duration: .01ms !important;
  }
}

/* Listing import is gated off: importing photos makes the listing UNPUBLISHABLE.
   Contrary to what this comment claimed until 2026-07-20, the path fails CLOSED —
   it does not write bad rows. The real defect is worse to live with than bad data:

   1. Imported photos are never re-hosted. applyImportedListing() pushes them with
      no .file (create-listing.js:5437), so Xr() emits the remote CDN URL as
      existing_url (:4424) and no bytes are ever uploaded. Then:
      - publish mode: parsePhotos() gets allowExistingPhotos=false
        (publish-listing/index.ts:579), so every fileless photo raises an issue at
        :489-495 and the whole publish is rejected with "Não foi possível ler uma
        das fotos selecionadas." The message names neither the photo nor the cause,
        imported photos look identical to uploaded ones in the UI, and the client
        gate Vi() (create-listing.js:4275) only counts r.photos.length — so the UI
        declares the draft ready and invites a submission that cannot succeed.
      - update mode: syncExistingListingImages() has no INSERT path. An unmatched
        photo hits `continue` (publish-listing/index.ts:1643-1645) and the response
        still reports success, so the host sees "Alterações guardadas." and loses
        the photos silently.

   2. The 40-photo cap is bypassed CLIENT-SIDE only. applyImportedListing() pushes
      without consulting `re = 40` (create-listing.js:15), which the manual upload
      path does honour (:4899-4911). Verified live: a 60-image payload is accepted
      and reported as "60 foto(s)". The server does NOT silently truncate — it
      raises an explicit 422 (publish-listing/index.ts:507-509), and the extractor
      already caps at 40 (_shared/listing-extract.ts:358). So this is only
      reachable by mixing manual uploads with an import, and it fails loudly.

   FIXED, do not re-add without re-testing: the imported address once failed to
   reach the location inputs, letting Pe() rebuild from the empty DOM and force
   country back to "Portugal". applyImportedListing() now calls jr() -> Mo() ->
   ht(true), which syncs state into the inputs. Verified live that an imported
   Spanish address survives a Pe() rebuild with country intact.

   NOTE: this gate also hides the .ics calendar-sync panel, which lives inside the
   same dialog (create-listing.html:398). That is the only way for a host to link
   an external calendar, so lifting the gate is also what unblocks calendar sync.

   WHY THIS RULE, AND WHY IT MUST NOT BE REMOVED FIRST:
   The `hidden` attribute on the button (create-listing.html:92) does NOT hold on
   its own at startup. navigation.css sets .mobile-menu-link--button{display:flex}
   in the author origin, which beats the UA-origin [hidden]{display:none}. The
   author-origin guard that honours [hidden] lives in menu-panel.css, which no page
   links statically — site-ui.js injects it under requestIdleCallback. It IS
   injected on this page (an earlier audit claimed otherwise; that was wrong), but
   late: measured at ~1325ms against DOMContentLoaded at ~407ms, i.e. a ~900ms
   window where only the rule below hides the button. Remove this block expecting
   `hidden` to cover you and the button is clickable during that window.

   WHAT THIS GATE DOES NOT DO: it is presentational only.
   window.CribondImportListing.open is still exported (import-listing.js:478)
   and open() performs no gate check, so a console call opens the fully wired
   dialog. The listing-import edge function has no server-side gate either and is
   deployed and live. If you need a real kill switch, put it behind an env flag in
   supabase/functions/listing-import/index.ts, not here.

   TO LIFT: fix the photo strategy first (re-host in the edge function, or stop
   importing photos entirely), then this block AND the `hidden` attribute go. */
body.create-listing-page [data-open-import-listing] {
  /* Import listing is live — button visible */
}

/* The draft entries in the top-bar menu ("Guardar rascunho", "Eliminar
   rascunho") ship `hidden` and are revealed by create-listing-simple.js once it
   knows whether this is a new listing or an open draft. `hidden` alone does not
   hold on them — same trap documented at length above: navigation.css sets
   .mobile-menu-link--button{display:flex} in the author origin, which beats the
   UA-origin [hidden]{display:none}, and the author guard that honours [hidden]
   lives in menu-panel.css, injected late by site-ui.js. Without this rule both
   entries flash visible (and clickable) for that window. */
body.create-listing-page .mobile-menu-link--button[hidden] {
  display: none;
}

/* Destructive entry: same shape as its siblings, read as a warning. */
body.create-listing-page .mobile-menu-link--danger,
body.create-listing-page .mobile-menu-link--danger svg {
  color: #c0392b;
  stroke: currentColor;
}

body.create-listing-page .mobile-menu-link--danger:hover {
  background: rgba(192, 57, 43, 0.1);
}
