/* GENERATED by wb-listora/bin/build-layered-css.mjs from style.css — do NOT edit. */
@layer listora {
/**
 * Listing Detail — Premium single listing page styles.
 */

.listora-detail {
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
}

/* ─── Breadcrumb ─── */

.listora-detail__breadcrumb ol {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3em;
	list-style: none;
	padding: 0;
	margin: 0 0 var(--listora-space-4);
	font-size: var(--listora-card-meta-size);
	color: var(--listora-fg-faint);
}

.listora-detail__breadcrumb li + li::before {
	content: '›';
	margin-inline-end: 0.3em;
}

.listora-detail__breadcrumb a {
	color: var(--listora-fg-muted);
	text-decoration: none;
}

.listora-detail__breadcrumb a:hover {
	text-decoration: underline;
}

.listora-detail__breadcrumb [aria-current] {
	color: var(--listora-fg-default);
	font-weight: var(--listora-weight-medium);
}

/* ─── Gallery Mosaic (Airbnb-style) ─── */

.listora-detail__gallery {
	margin-block-end: var(--listora-space-6);
	border-radius: var(--listora-radius-xl);
	overflow: hidden;
	position: relative;
}

.listora-detail__gallery-mosaic {
	display: grid;
	grid-template-columns: 2fr minmax(0, 1fr) minmax(0, 1fr);
	grid-template-rows: 1fr 1fr;
	height: 420px;
	gap: 4px;
}

.listora-detail__gallery-mosaic-item {
	overflow: hidden;
	cursor: pointer;
}

.listora-detail__gallery-mosaic-item:first-child {
	grid-row: 1 / 3;
}

.listora-detail__gallery-mosaic-item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--listora-transition-slow);
}

.listora-detail__gallery-mosaic-item:hover img {
	transform: scale(1.03);
}

.listora-detail__gallery-show-all {
	position: absolute;
	bottom: var(--listora-space-4);
	inset-inline-end: var(--listora-space-4);
	backdrop-filter: blur(8px);
	background: rgba(255, 255, 255, 0.85);
	border-radius: var(--listora-radius-md);
	padding: 0.4rem 0.8rem;
	font-size: var(--listora-text-size-sm);
	font-weight: var(--listora-weight-semibold);
	border: 1px solid rgba(0, 0, 0, 0.1);
	cursor: pointer;
	z-index: 5;
	transition: background var(--listora-transition-fast);
}

.listora-detail__gallery-show-all:hover {
	background: var(--listora-fg-inverse, var(--listora-bg-elevated));
}

/* Legacy gallery layout (fallback) */
.listora-detail__gallery-main {
	aspect-ratio: 16/9;
	overflow: hidden;
	background: var(--listora-bg-muted);
}

.listora-detail__gallery-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	cursor: zoom-in;
}

/* "View all photos (N)" over the hero, opposite the arrows' centre line. */
.listora-detail .listora-detail__gallery-viewall {
	all: unset;
	box-sizing: border-box;
	position: absolute;
	bottom: var(--listora-space-3);
	inset-inline-end: var(--listora-space-3);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	min-height: var(--listora-tap-target, 40px);
	padding: 0.45em 0.9em;
	font-family: inherit;
	font-size: var(--listora-text-size-sm);
	font-weight: var(--listora-weight-semibold);
	color: var(--listora-fg-default);
	background-color: color-mix(in srgb, var(--listora-bg-elevated) 92%, transparent);
	border: 1px solid var(--listora-border-default);
	border-radius: var(--listora-radius-full);
	box-shadow: var(--listora-shadow-sm);
	cursor: pointer;
}

.listora-detail .listora-detail__gallery-viewall:hover {
	background-color: var(--listora-bg-elevated);
}

.listora-detail .listora-detail__gallery-viewall:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
}

/* Gallery thumb strip — image-only buttons. Specificity-boosted via
 * `.listora-detail__gallery-thumbs .listora-detail__gallery-thumb`
 * (0,2,0) so the background-color: transparent + padding-zero rules
 * win against theme.json's .wp-element-button compilation that
 * otherwise paints these buttons brand-blue with coral borders
 * around each image. */
.listora-detail__gallery-thumbs {
	display: flex;
	gap: 0.4rem;
	margin-block-start: 0.4rem;
	/* Scroll a large gallery horizontally so every photo is reachable while
	   the strip stays one compact row. */
	flex-wrap: nowrap;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scrollbar-width: thin;
	padding-block-end: 0.2rem;
}

.listora-detail__gallery-thumbs::-webkit-scrollbar {
	height: 6px;
}

.listora-detail__gallery-thumbs::-webkit-scrollbar-thumb {
	background: var(--listora-border-default, rgba(0, 0, 0, 0.2));
	border-radius: var(--listora-radius-full);
}

.listora-detail__gallery-thumbs .listora-detail__gallery-thumb {
	all: unset;
	box-sizing: border-box;
	cursor: pointer;
	width: 80px;
	height: 60px;
	/* Never shrink inside the scrolling strip. */
	flex: 0 0 auto;
	scroll-snap-align: start;
	padding: 0;
	background-color: transparent;
	border-radius: var(--listora-radius-sm);
	overflow: hidden;
	border: 2px solid transparent;
	transition:
		border-color var(--listora-transition-fast),
		transform var(--listora-transition-fast);
	flex-shrink: 0;
	display: inline-block;
}

.listora-detail__gallery-thumbs .listora-detail__gallery-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.listora-detail__gallery-thumbs .listora-detail__gallery-thumb:hover,
.listora-detail__gallery-thumbs .listora-detail__gallery-thumb.is-active {
	border-color: var(--listora-primary);
}

.listora-detail__gallery-thumbs .listora-detail__gallery-thumb:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
}

/* ─── Lightbox (native dialog) ─── */

.listora-detail__lightbox {
	border: none;
	background: rgba(0, 0, 0, 0.92);
	width: 100vw;
	height: 100vh;
	max-width: 100vw;
	max-height: 100vh;
	padding: 0;
	position: relative;
}

/* Scoped to [open]: an unconditional display:flex overrides the UA's
   display:none for a closed dialog and paints it over the page. */
.listora-detail__lightbox[open] {
	display: flex;
	align-items: center;
	justify-content: center;
}

.listora-detail__lightbox::backdrop {
	background: rgba(0, 0, 0, 0.92);
}

.listora-detail__lightbox-img {
	max-width: 90vw;
	max-height: 85vh;
	object-fit: contain;
	animation: listora-fadeInScale 0.3s ease;
}

.listora-detail__lightbox-close {
	position: absolute;
	top: var(--listora-space-4);
	inset-inline-end: var(--listora-space-4);
	background: rgba(255, 255, 255, 0.15);
	color: var(--listora-on-media);
	border: none;
	border-radius: 50%;
	width: 2.5rem;
	height: 2.5rem;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background var(--listora-transition-fast);
}

.listora-detail__lightbox-close:hover {
	background: rgba(255, 255, 255, 0.25);
}

.listora-detail__lightbox-nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	background: rgba(255, 255, 255, 0.15);
	color: var(--listora-on-media);
	border: none;
	border-radius: 50%;
	width: 3rem;
	height: 3rem;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background var(--listora-transition-fast);
}

.listora-detail__lightbox-nav:hover {
	background: rgba(255, 255, 255, 0.25);
}

.listora-detail__lightbox-nav--prev {
	inset-inline-start: var(--listora-space-4);
}

.listora-detail__lightbox-nav--next {
	inset-inline-end: var(--listora-space-4);
}

.listora-detail__lightbox-counter {
	position: absolute;
	bottom: var(--listora-space-4);
	left: 50%;
	transform: translateX(-50%);
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--listora-text-size-sm);
}

/* ─── Sticky Compact Header ─── */

.listora-detail__sticky-header {
	position: sticky;
	top: 0;
	z-index: 100;
	backdrop-filter: blur(12px);
	background: color-mix(in srgb, var(--listora-bg-base) 85%, transparent);
	border-block-end: 1px solid var(--listora-border);
	padding: 0.5rem var(--listora-space-4);
	display: flex;
	align-items: center;
	gap: var(--listora-space-4);
	height: 56px;
	transform: translateY(-100%);
	opacity: 0;
	transition: transform var(--listora-transition-base), opacity var(--listora-transition-base);
	pointer-events: none;
}

.listora-detail__sticky-header.is-visible {
	transform: translateY(0);
	opacity: 1;
	pointer-events: auto;
}

.listora-detail__sticky-title {
	flex: 1;
	font-size: var(--listora-text-size-base);
	font-weight: var(--listora-weight-semibold);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.listora-detail__sticky-actions {
	display: flex;
	gap: var(--listora-space-1);
}

/* ─── Owner toolbar (visible only to the listing's author) ───
 * Sits above the breadcrumb so vendors see a clear "this is your
 * listing, here are your actions" affordance the moment they land on
 * their own page. Subtle accent background distinguishes it from the
 * public content below without competing with the listing title.
 */
.listora-detail__owner-bar {
	/* No decorative left-stripe — the green Published pill already
	 * carries the state signal. The stripe read as an "AI tool"
	 * status indicator out of place for a listing dashboard. */
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1rem;
	align-items: center;
	justify-content: space-between;
	margin: 0 0 1rem;
	padding: 0.65rem 0.95rem;
	background: var(--listora-bg-muted, #f3f4f6);
	border: 1px solid var(--listora-border-subtle, #e2e8f0);
	border-radius: var(--listora-radius-md, 8px);
	font-size: 0.875rem;
	color: var(--listora-fg-default, #1a1a1a);
}

.listora-detail__owner-bar-left {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	flex-wrap: wrap;
}

.listora-detail__owner-bar-label {
	font-weight: var(--listora-weight-medium, 500);
	color: var(--listora-fg-default, #1a1a1a);
}

.listora-detail__owner-bar-status {
	display: inline-flex;
	align-items: center;
	padding: 0.15rem 0.55rem;
	border-radius: 9999px;
	font-size: 0.75rem;
	font-weight: var(--listora-weight-medium, 500);
	background: var(--listora-bg-elevated, #fff);
	border: 1px solid var(--listora-border-subtle, #e2e8f0);
	color: var(--listora-fg-muted, #555);
}

.listora-detail__owner-bar-status.is-publish {
	color: var(--listora-success-fg, #047857);
	border-color: var(--listora-success-fg, #047857);
}

.listora-detail__owner-bar-status.is-pending,
.listora-detail__owner-bar-status.is-pending-verification {
	color: var(--listora-warning-fg, #b45309);
	border-color: var(--listora-warning-fg, #b45309);
}

.listora-detail__owner-bar-status.is-paused {
	color: var(--listora-fg-default, #1a1a1a);
	background: var(--listora-warning-bg, #fef3c7);
	border-color: var(--listora-warning-bg, #fef3c7);
}

.listora-detail__owner-bar-status.is-expired,
.listora-detail__owner-bar-status.is-rejected,
.listora-detail__owner-bar-status.is-deactivated {
	color: var(--listora-danger-fg, #b91c1c);
	border-color: var(--listora-danger-fg, #b91c1c);
}

.listora-detail__owner-bar-actions {
	display: inline-flex;
	gap: 0.4rem;
	flex-wrap: wrap;
}

/* ─── Header ─── */

.listora-detail__header {
	margin-block-end: var(--listora-space-6);
}

.listora-detail__header-top {
	display: flex;
	align-items: center;
	gap: 0.5em;
	flex-wrap: wrap;
	margin-block-end: 0.5rem;
}

.listora-detail__title {
	font-family: var(--listora-card-title-font);
	font-size: var(--wp--preset--font-size--x-large, 2rem);
	font-weight: var(--listora-weight-bold);
	line-height: 1.2;
	letter-spacing: -0.02em;
	margin: 0 0 0.3rem;
	color: var(--listora-fg-default);
}

.listora-detail__address {
	display: flex;
	align-items: center;
	gap: 0.35em;
	font-style: normal;
	font-size: 1rem;
	color: var(--listora-fg-muted);
	margin-block-end: var(--listora-space-4);
}

.listora-detail__address svg {
	flex-shrink: 0;
	color: var(--listora-fg-faint);
}

/* Actions */
.listora-detail__actions {
	display: flex;
	gap: 0.5rem;
	flex-wrap: wrap;
}

.listora-detail__actions .listora-btn {
	font-size: var(--listora-card-meta-size);
	/* Quieter than the pill some themes promote globally - matches the v2
	 * radius-sm token so the action chrome reads premium, not loud. */
	border-radius: var(--listora-radius-sm, 6px);
}

/* The plugin owns its look (card 10347037187): Reign's own a:hover rule set
 * font-size larger on hover, so Save/Share/Directions/Report visibly grew
 * on mouseover. Pin hover/focus to the same size instead of chasing the
 * theme's exact selector - same defensive pattern as 10340592969. */
.listora-detail__actions .listora-btn:hover,
.listora-detail__actions .listora-btn:focus {
	font-size: var(--listora-card-meta-size);
}

.listora-detail__actions .is-favorited {
	color: var(--listora-favorite);
	border-color: var(--listora-favorite);
}

.listora-detail__actions .is-favorited svg {
	fill: currentColor;
}

/* Feature This Listing — owner CTA */
.listora-detail__feature-btn svg {
	color: var(--listora-premium, var(--listora-warning));
}

.listora-detail__feature-btn.is-loading {
	opacity: 0.7;
	cursor: progress;
}

.listora-detail__feature-status {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.4em 0.8em;
	border-radius: var(--listora-radius-full);
	font-size: var(--listora-card-meta-size);
	font-weight: var(--listora-weight-medium);
	background: color-mix(in srgb, var(--listora-premium, var(--listora-warning)) 12%, transparent);
	color: var(--listora-premium, var(--listora-warning));
	white-space: nowrap;
}

.listora-detail__feature-status svg {
	flex-shrink: 0;
}

@media (max-width: 640px) {
	.listora-detail__feature-status {
		width: 100%;
		justify-content: center;
	}
}

/* ─── Content Layout ─── */

.listora-detail__content {
	display: grid;
	/* `minmax(0, 1fr)` (not `1fr`) so the main column doesn't grow to fit
	 * intrinsic content like a long tab strip — without it, the tabs at
	 * mobile widths would push the main column beyond the available
	 * width and visibly cut off the content (Basecamp 9842624047). */
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: var(--listora-space-6);
}

/* 900px, not 768: an iPad held upright (820) and BuddyX at 1024 both squeezed
   the tab strip under the fixed sidebar (card 10337187661). */
@media (max-width: 900px) {
	.listora-detail__content {
		grid-template-columns: minmax(0, 1fr);
	}
}

.listora-detail__main {
	/* Defense-in-depth: even with minmax(0, 1fr) on the parent, an inner
	 * flex/scroll context (the tab strip uses `display: inline-flex`)
	 * can sometimes resist clamping. `min-width: 0` lets the column
	 * truly collapse and the tab strip's `overflow-x: auto` then takes
	 * over to scroll horizontally instead of overflowing the page. */
	min-width: 0;
}

/* ─── Tabs (Pill Style) ─── */

.listora-detail__tabs {
	/* Shrink to the pills, never wider than the column: the strip scrolls
	   inside its own column instead of running under the sidebar. */
	display: flex;
	/* Wrap at every width: the column narrows at several breakpoints (two
	   columns from 901px), and a strip with no scrollbar hides its last tab. */
	flex-wrap: wrap;
	width: max-content;
	max-width: 100%;
	gap: 0.25rem;
	/* Derived from the active pill's surface, so the two always differ -
	   a theme that sets surface and elevated to the same colour (BuddyX)
	   otherwise leaves the active tab invisible. */
	background: color-mix(in srgb, var(--listora-fg-default) 7%, var(--listora-bg-elevated));
	/* Half a pill's height: a full pill on one row, rounded corners on two. */
	border-radius: calc( var(--listora-tap-target, 44px) / 2 + 0.3rem );
	padding: 0.3rem;
	overflow-x: auto;
	scrollbar-width: none;
	margin-block-end: var(--listora-space-4);
}

.listora-detail__tabs::-webkit-scrollbar {
	display: none;
}

/* Specificity-boosted via descendant chain `.listora-detail__tabs
 * .listora-detail__tab` (0,2,0) so the tab pill styling wins against
 * any theme's compiled `.wp-element-button` rule (0,1,0). Explicit
 * background-color set (not just background) to overwrite any theme
 * rule that landed later in the cascade. */
.listora-detail__tabs .listora-detail__tab {
	all: unset;
	box-sizing: border-box;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	min-height: var(--listora-tap-target, 44px);
	padding: 0.5rem 1rem;
	font-family: inherit;
	font-size: var(--listora-text-size-sm);
	font-weight: var(--listora-weight-medium);
	color: var(--listora-fg-muted);
	background-color: transparent;
	white-space: nowrap;
	border: 0;
	border-radius: var(--listora-radius-full);
	transition:
		background-color var(--listora-transition-fast),
		color var(--listora-transition-fast),
		box-shadow var(--listora-transition-fast);
	display: inline-flex;
	align-items: center;
	gap: 0.3em;
}

.listora-detail__tabs .listora-detail__tab:hover {
	color: var(--listora-fg-default);
	background-color: color-mix(in srgb, var(--listora-fg-default) 6%, transparent);
}

.listora-detail__tabs .listora-detail__tab:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
}

.listora-detail__tabs .listora-detail__tab.is-active {
	background-color: var(--listora-bg-elevated);
	color: var(--listora-primary-text);
	box-shadow: var(--listora-shadow-sm);
	font-weight: var(--listora-weight-semibold);
}

.listora-detail__tab-count {
	font-size: 0.75em;
	font-weight: var(--listora-weight-semibold);
	background: var(--listora-primary-fill, var(--listora-primary));
	color: var(--listora-primary-fg);
	padding: 0.1em 0.5em;
	min-width: 1.3em;
	text-align: center;
	border-radius: var(--listora-radius-full);
}

/* On the active tab, swap the badge to inverse colours so it stays
 * legible against the elevated pill bg. */
.listora-detail__tab.is-active .listora-detail__tab-count {
	background: var(--listora-primary-fill, var(--listora-primary));
	color: var(--listora-primary-fg);
}

/* Panels */
.listora-detail__panel {
	animation: listora-fadeIn 0.2s ease;
}

.listora-detail__description {
	line-height: 1.7;
	color: var(--listora-fg-default);
	margin-block-end: var(--listora-space-4);
}

/* Quick Info */
.listora-detail__quick-info {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 1rem;
	padding: var(--listora-space-4);
	background: var(--listora-bg-surface);
	border-radius: var(--listora-radius-lg);
	margin-block-end: var(--listora-space-4);
}

.listora-detail__info-item dt {
	font-size: var(--listora-text-size-xs);
	color: var(--listora-fg-faint);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	margin-block-end: 0.2rem;
}

.listora-detail__info-item dd {
	margin: 0;
	font-weight: var(--listora-weight-medium);
	color: var(--listora-fg-default);
}

/* Features */
.listora-detail__features {
	margin-block-end: var(--listora-space-4);
}

.listora-detail__features h3 {
	font-size: 1rem;
	margin: 0 0 0.5rem;
}

.listora-detail__features-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.listora-detail__features-list .listora-feature-badge {
	font-size: var(--listora-text-size-sm);
	padding: 0.3em 0.7em;
}

/* Field List */
.listora-detail__field-list {
	margin: 0;
}

.listora-detail__field-item {
	display: flex;
	gap: 1rem;
	padding: 0.6rem 0;
	border-block-end: 1px solid var(--listora-border);
}

.listora-detail__field-item:last-child {
	border: none;
}

.listora-detail__field-item dt {
	flex: 0 0 140px;
	font-size: var(--listora-card-meta-size);
	color: var(--listora-fg-faint);
	font-weight: var(--listora-weight-medium);
}

.listora-detail__field-item dd {
	margin: 0;
	flex: 1;
	color: var(--listora-fg-default);
}

.listora-detail__field-item dd a {
	color: var(--listora-primary-text);
}

/* ─── Sidebar (Sticky) ─── */

.listora-detail__sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-4);
	position: sticky;
	top: var(--listora-space-6);
	align-self: start;
}

/* After the base rule, or source order makes sticky win at every width. */
@media (max-width: 900px) {
	.listora-detail__sidebar {
		position: static;
	}
}

/* Contact Card */
.listora-detail__contact-card,
.listora-detail__hours-card,
.listora-detail__owner-card,
.listora-detail__social-card,
.listora-detail__map-card {
	background: var(--listora-bg-elevated);
	border: var(--listora-card-border);
	border-radius: var(--listora-radius-lg);
	padding: var(--listora-space-4);
	box-shadow: var(--listora-shadow-sm);
}

.listora-detail__contact-card h3,
.listora-detail__hours-card h3,
.listora-detail__owner-card h3,
.listora-detail__social-card h3,
.listora-detail__map-card h3 {
	font-size: 1rem;
	font-weight: var(--listora-weight-semibold);
	margin: 0 0 0.75rem;
	color: var(--listora-fg-default);
}

/* One heading scale for the page (card 10337187661): every section title in
   the main column and the sidebar is an h3 at the base size, and Related
   Listings is the only h2. Specificity (0,3,1) outranks the per-section
   rules elsewhere in this sheet and Pro's sidebar card titles. */
.listora-detail .listora-detail__main h3,
.listora-detail .listora-detail__sidebar h3 {
	font-size: var(--listora-text-size-base, 1rem);
	font-weight: var(--listora-weight-semibold);
	line-height: 1.3;
	margin: 0 0 var(--listora-space-3);
}

.listora-detail__contact-name {
	margin: 0 0 var(--listora-space-2);
	font-weight: var(--listora-weight-medium);
}

/* Location card: one marker, the address, directions. */
.listora-detail__map-card .listora-detail__map-embed {
	height: 200px;
	border-radius: var(--listora-radius-md);
	overflow: hidden;
	border: 1px solid var(--listora-border-default);
	margin-block-end: var(--listora-space-3);
}

.listora-detail__map-address {
	margin: 0 0 var(--listora-space-3);
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
}

.listora-detail__map-plus-code {
	margin: 0 0 var(--listora-space-3);
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
	overflow-wrap: anywhere;
}

.listora-detail__map-plus-code code {
	font-size: inherit;
	color: var(--listora-fg-default);
	user-select: all;
}

.listora-detail__map-card .listora-detail__map-directions {
	width: 100%;
	justify-content: center;
}

/* Listed by - the owner card carries no icons, so it only needs the name. */
.listora-detail__owner-name {
	margin: 0;
	font-size: 0.95rem;
	font-weight: var(--listora-weight-medium);
	color: var(--listora-fg-default);
}

.listora-detail__owner-name a {
	color: var(--listora-fg-default);
	text-decoration: none;
}

.listora-detail__owner-name a:hover,
.listora-detail__owner-name a:focus-visible {
	text-decoration: underline;
}

.listora-detail__contact-item {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0;
	color: var(--listora-fg-default);
	text-decoration: none;
	font-size: 0.95rem;
	border-block-end: 1px solid var(--listora-border);
	transition: color var(--listora-transition-fast);
}

.listora-detail__contact-item:last-child {
	border: none;
}

.listora-detail__contact-item:hover {
	color: var(--listora-primary-text);
}

/* Social Links Card */
.listora-detail__social-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0;
}

.listora-detail__social-link {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0;
	color: var(--listora-fg-default);
	text-decoration: none;
	font-size: 0.95rem;
	border-block-end: 1px solid var(--listora-border);
	transition: color var(--listora-transition-fast);
}

.listora-detail__social-list li:last-child .listora-detail__social-link {
	border: none;
}

.listora-detail__social-link:hover,
.listora-detail__social-link:focus-visible {
	color: var(--listora-primary-text);
}

.listora-detail__social-label {
	flex: 1;
}

/* Colored icon circles */
.listora-detail__contact-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	border-radius: var(--listora-radius-md);
	flex-shrink: 0;
}

.listora-detail__contact-icon--phone {
	background: color-mix(in srgb, var(--listora-success) 12%, transparent);
	color: var(--listora-success);
}

.listora-detail__contact-icon--email {
	background: color-mix(in srgb, var(--listora-primary) 12%, transparent);
	color: var(--listora-primary-text);
}

.listora-detail__contact-icon--web {
	background: color-mix(in srgb, var(--listora-premium) 12%, transparent);
	color: var(--listora-premium);
}

/* CTA */
.listora-detail__cta-btn {
	width: 100%;
	justify-content: center;
	margin-block-start: var(--listora-space-2);
}

/* Claimed Badge */
.listora-detail__claimed-badge {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.75rem;
	background: color-mix(in srgb, var(--listora-success) 8%, transparent);
	color: var(--listora-success);
	border-radius: var(--listora-radius-md);
	font-size: var(--listora-card-meta-size);
	font-weight: var(--listora-weight-medium);
}

/* ─── Hours Table ─── */

.listora-hours-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--listora-card-meta-size);
}

.listora-hours-table tr {
	border-block-end: 1px solid var(--listora-border);
}

.listora-hours-table tr:last-child {
	border: none;
}

.listora-hours-table td {
	padding: 0.4rem 0;
}

.listora-hours-table__day {
	font-weight: var(--listora-weight-medium);
	color: var(--listora-fg-default);
	width: 100px;
}

.listora-hours-table__time {
	color: var(--listora-fg-muted);
}

.listora-hours-table__time--closed {
	color: var(--listora-danger);
}

/* Today row highlight with animated dot */
.listora-hours-table .is-today .listora-hours-table__day {
	color: var(--listora-primary-text);
}

.listora-hours-table .is-today .listora-hours-table__day::before {
	content: '';
	display: inline-block;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--listora-success);
	margin-inline-end: 0.4rem;
	animation: listora-pulse 2s infinite;
}

/* ─── Mobile Sticky Bar ─── */

.listora-detail__mobile-bar {
	display: none;
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 1000;
	backdrop-filter: blur(12px);
	background: color-mix(in srgb, var(--listora-bg-base) 85%, transparent);
	border-block-start: 1px solid var(--listora-border);
	padding: 0.5rem;
	/* env()'s second value only applies where env() is unsupported; on a phone
	   without a home bar the inset is a real 0, so the base is added to it. */
	padding-block-end: calc(0.5rem + env(safe-area-inset-bottom, 0px));
	gap: 0.5rem;
	box-shadow: var(--listora-shadow-lg);
}

.listora-detail__mobile-bar .listora-btn {
	flex: 1;
	justify-content: center;
	font-size: var(--listora-text-size-sm);
}

@media (max-width: 768px) {
	.listora-detail__mobile-bar {
		display: flex;
	}

	/* The fixed bar covers the last 4rem of the viewport, so the theme footer
	   could never scroll clear of it. Padding the listing root stops short of
	   the footer, and body padding loses to the theme's own unlayered
	   `body { padding: 0 }` (this sheet sits in @layer listora). A spacer
	   after everything in body reserves the room without touching theme CSS.
	   Applied only while the bar is on the page and shown. */
	body:has(.listora-detail__mobile-bar)::after {
		content: "";
		display: block;
		height: calc(4.5rem + env(safe-area-inset-bottom, 0px));
	}

	.listora-detail__gallery-mosaic {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto;
		height: auto;
	}

	.listora-detail__gallery-mosaic-item:first-child {
		grid-row: auto;
	}

	.listora-detail__gallery-mosaic-item:nth-child(n+3) {
		display: none;
	}

	.listora-detail__gallery-thumb {
		width: 60px;
		height: 45px;
	}

	.listora-detail__sticky-header {
		display: none;
	}
}

@media (max-width: 480px) {
	.listora-detail__title {
		font-size: 1.5rem;
	}

	.listora-detail__quick-info {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.listora-detail__tabs {
		width: 100%;
	}

	.listora-detail__address {
		font-size: var(--listora-text-size-sm);
	}
}

/* ─── Reviews Section (within detail) ─── */

.listora-detail__reviews-summary {
	display: flex;
	gap: var(--listora-space-6);
	align-items: flex-start;
	padding: var(--listora-space-4);
	background: var(--listora-bg-surface);
	border-radius: var(--listora-radius-xl);
	margin-block-end: var(--listora-space-6);
}

.listora-detail__reviews-score {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.3rem;
	min-width: 100px;
}

.listora-detail__reviews-avg {
	font-size: var(--listora-text-size-3xl);
	font-weight: var(--listora-weight-bold);
	line-height: 1;
	color: var(--listora-fg-default);
}

.listora-detail__reviews-stars {
	display: flex;
	gap: 2px;
	color: var(--listora-rating);
}

.listora-detail__reviews-total {
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-faint);
}

.listora-detail__reviews-bars {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.listora-detail__reviews-bar-row {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-faint);
}

.listora-detail__reviews-bar-row span:first-child {
	width: 1em;
	text-align: center;
}

.listora-detail__reviews-bar-row span:last-child {
	width: 2em;
	text-align: end;
}

.listora-detail__reviews-bar {
	flex: 1;
	height: 10px;
	background: var(--listora-border);
	border-radius: var(--listora-radius-full);
	overflow: hidden;
}

.listora-detail__reviews-bar div {
	height: 100%;
	background: linear-gradient(90deg, var(--listora-rating), color-mix(in srgb, var(--listora-rating) 80%, var(--listora-warning)));
	border-radius: var(--listora-radius-full);
	transition: width 0.3s;
}

/* Review cards */
.listora-detail__reviews-list {
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-2);
}

/* Write-a-Review CTA breathes from the review list above and the form
   wrapper below. Without margin the button stacks flush against the
   last review card. Basecamp #9927635866. */
.listora-reviews__write-btn {
	margin-block: var(--listora-space-4) var(--listora-space-3);
	align-self: flex-start;
}

/* ─── Write-a-Review form ───
   The review form is rendered inside the listing-detail block (not the
   standalone listing-reviews block), so its styling must live here — the
   listing-reviews/style.css twin is NOT enqueued on the single-listing
   page. Tokens only (no raw hex). Basecamp #9927635866. */
.listora-reviews__form-wrapper {
	margin-block-start: var(--listora-space-4);
	padding: var(--listora-space-5);
	background: var(--listora-bg-elevated);
	border: 1px solid var(--listora-border);
	border-radius: var(--listora-radius-lg);
	box-shadow: var(--listora-shadow-sm);
}

.listora-reviews__form > h3 {
	margin: 0 0 var(--listora-space-4);
	font-size: var(--listora-text-size-lg);
	font-weight: var(--listora-weight-semibold);
	color: var(--listora-fg-default);
}

/* Field rhythm — consistent vertical gap between rating, title, textarea,
   criteria, and actions. */
.listora-reviews__form .listora-submission__field {
	margin-block-end: var(--listora-space-5);
}

.listora-reviews__form .listora-submission__label {
	display: block;
	font-size: var(--listora-text-size-sm);
	font-weight: var(--listora-weight-medium);
	color: var(--listora-fg-default);
	margin-block-end: var(--listora-space-2);
}

.listora-reviews__form .listora-submission__label .required {
	color: var(--listora-danger);
}

.listora-reviews__form .listora-submission__textarea {
	min-height: 110px;
	resize: vertical;
}

/* ─── Star inputs (overall + per-aspect) ───
   Markup renders stars 1→5 in DOM order (left→right). A star is gold when
   it is checked/hovered OR when a LATER sibling is checked/hovered — i.e.
   selecting "4" lights stars 1-4. Done CSS-only via :has(~ … :checked),
   no JS and no row-reverse trickery. */
.listora-reviews__star-input {
	display: inline-flex;
	flex-direction: row;
	align-items: center;
	gap: 0.15rem;
	border: 0;
	padding: 0;
	margin: 0;
}

.listora-reviews__star-label {
	display: inline-flex;
	cursor: pointer;
	line-height: 0;
}

/* Visually-hidden radio — keep it focusable for keyboard + a11y. */
.listora-reviews__star-label input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.listora-reviews__star-svg {
	width: 1.75rem;
	height: 1.75rem;
	color: var(--listora-border);
	transition: color var(--listora-transition-fast), transform var(--listora-transition-fast);
}

.listora-reviews__star-input--small .listora-reviews__star-svg {
	width: 1.35rem;
	height: 1.35rem;
}

/* Highlight the checked star and every star before it (1→N fill). */
.listora-reviews__star-label:has(input:checked) .listora-reviews__star-svg,
.listora-reviews__star-label:has(~ .listora-reviews__star-label input:checked) .listora-reviews__star-svg {
	color: var(--listora-rating);
}

/* Hover preview overrides the checked state: light the hovered star + all
   before it, and dim any to its right that aren't also hovered. */
.listora-reviews__star-input:hover .listora-reviews__star-label:has(input:checked) .listora-reviews__star-svg,
.listora-reviews__star-input:hover .listora-reviews__star-label:has(~ .listora-reviews__star-label input:checked) .listora-reviews__star-svg {
	color: var(--listora-border);
}

.listora-reviews__star-label:hover .listora-reviews__star-svg,
.listora-reviews__star-label:has(~ .listora-reviews__star-label:hover) .listora-reviews__star-svg {
	color: var(--listora-rating);
}

.listora-reviews__star-label:focus-within .listora-reviews__star-svg {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
	border-radius: 2px;
}

.listora-reviews__star-label:active .listora-reviews__star-svg {
	transform: scale(1.1);
}

/* ─── "Rate each aspect" section ─── */
.listora-reviews__criteria {
	margin-block: var(--listora-space-5);
	padding-block-start: var(--listora-space-5);
	border-block-start: 1px solid var(--listora-border);
}

.listora-reviews__criteria > .listora-submission__label {
	margin-block-end: var(--listora-space-3);
}

.listora-reviews__criterion {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	gap: var(--listora-space-3);
	padding-block: var(--listora-space-2);
}

.listora-reviews__criterion + .listora-reviews__criterion {
	border-block-start: 1px solid var(--listora-border-divider, var(--listora-border));
}

.listora-reviews__criterion-label {
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
	min-width: 0;
}

/* ─── Form actions ─── */
.listora-reviews__form-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--listora-space-2);
	margin-block-start: var(--listora-space-5);
}

.listora-reviews__form-actions .listora-btn {
	min-height: var(--listora-tap-target, 44px);
}

.listora-reviews__form-message {
	margin-block-start: var(--listora-space-3);
	font-size: var(--listora-text-size-sm);
}

.listora-reviews__login-notice {
	text-align: center;
	padding: var(--listora-space-4);
}

/* Mobile (≤640px): stack each criterion (label above its stars) so long
   labels like "Ambiance" never wrap awkwardly mid-row, and make the submit
   button full-width for a comfortable touch target. */
@media (max-width: 640px) {
	.listora-reviews__form-wrapper {
		padding: var(--listora-space-4);
	}

	.listora-reviews__criterion {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--listora-space-2);
	}

	.listora-reviews__form-actions {
		flex-direction: column;
		align-items: stretch;
	}

	.listora-reviews__form-actions .listora-btn {
		width: 100%;
		justify-content: center;
	}
}

.listora-detail__review {
	padding: var(--listora-space-4);
	background: var(--listora-bg-elevated);
	border-radius: var(--listora-radius-lg);
	box-shadow: var(--listora-shadow-sm);
}

.listora-detail__review-header {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	margin-block-end: 0.5rem;
}

.listora-detail__review-avatar {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	object-fit: cover;
	border: 2px solid var(--listora-bg-surface);
}

.listora-detail__review-author {
	font-size: 0.95rem;
}

.listora-detail__review-author--link {
	color: var(--listora-fg-default);
	font-weight: var(--listora-weight-semibold);
	text-decoration: none;
	transition: color 0.15s ease;
}

.listora-detail__review-author--link:hover,
.listora-detail__review-author--link:focus-visible {
	color: var(--listora-primary-text);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.listora-detail__review-author--link:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
	border-radius: 2px;
}

@media (max-width: 640px) {
	.listora-detail__review-author--link {
		font-size: 0.95rem;
	}
}

.listora-detail__review-meta {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-faint);
}

.listora-detail__review-meta .listora-rating {
	display: flex;
	gap: 1px;
}

.listora-detail__review-title {
	font-size: 1rem;
	font-weight: var(--listora-weight-semibold);
	margin: 0 0 0.3rem;
}

.listora-detail__review-content {
	margin: 0;
	color: var(--listora-fg-muted);
	line-height: 1.6;
	font-size: 0.95rem;
}

/* Owner reply card */
.listora-detail__review-reply {
	margin-block-start: 0.75rem;
	padding: var(--listora-space-2) var(--listora-space-4);
	background: var(--listora-bg-surface);
	border-radius: var(--listora-radius-md);
	font-size: var(--listora-text-size-base);
}

.listora-detail__review-reply strong {
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-faint);
	display: block;
	margin-block-end: 0.3rem;
}

.listora-detail__review-reply p {
	margin: 0;
	color: var(--listora-fg-muted);
}

.listora-detail__review-helpful {
	font-size: var(--listora-text-size-xs);
	color: var(--listora-fg-faint);
	margin-block-start: 0.5rem;
	display: block;
}

@media (max-width: 768px) {
	.listora-detail__reviews-summary {
		flex-direction: column;
		align-items: stretch;
	}

	.listora-detail__reviews-score {
		flex-direction: row;
		gap: 0.75rem;
		min-width: auto;
	}
}

/* ─── Map Embed ─── */

.listora-detail__claim-message,
.listora-detail__report-message {
	margin-block-start: var(--listora-space-2);
	font-size: var(--listora-text-size-sm);
	padding: var(--listora-space-4);
	border-radius: var(--listora-radius-md);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--listora-space-2);
}

.listora-detail__claim-message p {
	margin: 0;
	line-height: 1.5;
}

.listora-detail__claim-message--success,
.listora-detail__report-message--success {
	background: color-mix(in srgb, var(--listora-success, var(--listora-success)) 10%, transparent);
	color: var(--listora-success-fg);
}

.listora-detail__claim-message--error,
.listora-detail__report-message--error {
	background: color-mix(in srgb, var(--listora-danger, var(--listora-danger)) 10%, transparent);
	color: var(--listora-danger-fg, var(--listora-danger));
}

.listora-detail__map-embed {
	border-radius: var(--listora-radius-xl);
	overflow: hidden;
	height: 300px;
}

.listora-detail__map-actions {
	margin-block-start: 0.75rem;
	display: flex;
	gap: 0.5rem;
}

@media (max-width: 640px) {
	.listora-detail__map-embed {
		height: 240px;
	}

	.listora-detail__map-actions {
		flex-direction: column;
	}
}

/* ─── Review helpful-vote button (Reviews tab) ─── */
.listora-detail__review-actions {
	display: flex;
	align-items: center;
	gap: var(--listora-space-2);
	margin-block-start: var(--listora-space-2);
	flex-wrap: wrap;
}

.listora-detail__review-helpful-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.4rem 0.75rem;
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
	background: var(--listora-bg-surface);
	border: 1px solid var(--listora-border);
	border-radius: var(--listora-radius-full);
	cursor: pointer;
	transition: color var(--listora-transition-fast), background var(--listora-transition-fast), border-color var(--listora-transition-fast);
}

.listora-detail__review-helpful-btn:hover:not(:disabled) {
	color: var(--listora-primary-text);
	border-color: var(--listora-primary);
}

.listora-detail__review-helpful-btn.is-voted {
	color: var(--listora-primary-text);
	border-color: var(--listora-primary);
	background: color-mix(in srgb, var(--listora-primary) 8%, transparent);
}

.listora-detail__review-helpful-btn.is-error {
	opacity: 0.5;
}

.listora-detail__review-helpful-btn:disabled {
	cursor: default;
}

/* Report sits beside Helpful in the review actions row and had NO rules at
 * all here, so it rendered as raw browser chrome - a grey 3D <button> next to
 * a designed pill, on every listing with reviews (card 10304417208). Same
 * shape as Helpful; danger tint only on hover, because a Report control that
 * is red at rest reads as an alarm on a review that has nothing wrong with it.
 */
.listora-detail__review-report-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.4rem 0.75rem;
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
	background: var(--listora-bg-surface);
	border: 1px solid var(--listora-border);
	border-radius: var(--listora-radius-full);
	cursor: pointer;
	transition: color var(--listora-transition-fast), background var(--listora-transition-fast), border-color var(--listora-transition-fast);
}

.listora-detail__review-report-btn:hover:not(:disabled) {
	color: var(--listora-danger, #b32d2e);
	border-color: var(--listora-danger, #b32d2e);
}

.listora-detail__review-report-btn:disabled {
	cursor: default;
	opacity: 0.5;
}

/* Location tab - merged address breakdown + map embed.
 * The address dl + map-wrap render side-by-side on >=900px, stacked on
 * smaller viewports. Replaces the previous Location/Map split. */
.listora-detail__field-item--address dd {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.listora-detail__address-line {
	font-size: var(--listora-text-size-base, 1rem);
	color: var(--listora-fg-default);
	line-height: 1.5;
}

.listora-detail__address-line--muted {
	color: var(--listora-fg-muted);
	font-size: var(--listora-text-size-sm);
}

.listora-detail__map-wrap {
	margin-block-start: var(--listora-space-5, 1.25rem);
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-3, 0.75rem);
}

.listora-detail__map-wrap .listora-detail__map-embed {
	width: 100%;
	min-height: 360px;
	height: 360px;
	border-radius: var(--listora-radius-lg, 14px);
	overflow: hidden;
	border: 1px solid var(--listora-border-default);
}

.listora-detail__map-wrap .listora-detail__map-actions {
	display: flex;
	gap: var(--listora-space-2);
}

/* Standalone Map panel (used when there's no map_location field). */
#panel-map .listora-detail__map-embed {
	min-height: 480px;
	height: 480px;
	border-radius: var(--listora-radius-lg, 14px);
	overflow: hidden;
	border: 1px solid var(--listora-border-default);
	margin-block-end: var(--listora-space-3);
}

/* Uniform tab panel shell - applied to every tab so Overview / Location /
 * field-groups / Services / Reviews / Map share the same card-style canvas.
 * Pulls Place Details + Location out of a naked dl into the same elevated
 * card vocabulary the Services grid was already using. */
.listora-detail__panel {
	background: var(--listora-bg-elevated, #fff);
	border: 1px solid var(--listora-border-default);
	border-radius: var(--listora-radius-lg, 14px);
	padding: var(--listora-space-5, 1.25rem) var(--listora-space-6, 1.5rem);
	margin-block-start: var(--listora-space-4, 1rem);
}

/* Services + Reviews panels already render inner cards (service-card,
 * review-card). Drop the outer panel chrome so we never paint a card
 * inside a card. Keep the top margin so the spacing under the tab nav
 * stays consistent with every other tab. */
#panel-services,
#panel-reviews {
	background: transparent;
	border: none;
	border-radius: 0;
	padding: 0;
}

/* SSR reviews deep-link — reveal the Reviews panel without JS.
 *
 * The Interactivity API toggles panel visibility via the [hidden] property at
 * runtime, but an owner landing on #reviews / #review-<id> / #oldest-unanswered
 * (the review_reminder email deep-link) must see the reviews BEFORE hydration —
 * otherwise the panel reads as JS-blank. These rules force the targeted panel
 * open using CSS :target, so the content is server-rendered AND visible on the
 * very first paint. Once the IAPI hydrates, switchTab takes over normally.
 *
 * Two cases:
 *  1. The hash targets the panel itself (#panel-reviews).
 *  2. The hash targets a child anchor inside the panel (a #review-<id> row or
 *     the #oldest-unanswered marker) — :has() lifts the reveal to the panel.
 */
/* Scoped to before the tab script runs: history.replaceState() never
 * recomputes :target, so after a tab switch this rule kept forcing the Reviews
 * panel open beneath the active tab (card 10304369374). */
.listora-detail:not(.is-tabs-ready) #panel-reviews:target,
.listora-detail:not(.is-tabs-ready) #panel-reviews:has(:target) {
	display: block !important;
}

/* Per-review deep-link affordance — give the targeted review a brief highlight
 * so an owner following an email link sees exactly which review the link meant.
 * The marker span is zero-height; offset its scroll so the row clears the
 * sticky tab nav. */
.listora-detail__review-anchor {
	display: block;
	height: 0;
	scroll-margin-block-start: var(--listora-space-6, 1.5rem);
}

.listora-detail__review {
	scroll-margin-block-start: var(--listora-space-6, 1.5rem);
}

.listora-detail__review:target {
	outline: 2px solid var(--listora-primary);
	outline-offset: var(--listora-space-2, 0.5rem);
	border-radius: var(--listora-radius-md, 8px);
}

@media (prefers-reduced-motion: no-preference) {
	.listora-detail__review:target {
		transition: outline-color var(--listora-transition-base);
	}
}

.listora-detail__field-list {
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-3, 0.75rem);
	margin: 0;
}

.listora-detail__field-item {
	display: grid;
	grid-template-columns: minmax(140px, 200px) 1fr;
	gap: var(--listora-space-4, 1rem);
	padding-block: var(--listora-space-3, 0.75rem);
	border-block-end: 1px solid var(--listora-border-default);
}

.listora-detail__field-item:last-child {
	border-block-end: none;
}

.listora-detail__field-item dt {
	font-size: var(--listora-text-size-sm);
	font-weight: var(--listora-weight-semibold, 600);
	color: var(--listora-fg-muted);
	margin: 0;
}

.listora-detail__field-item dd {
	font-size: var(--listora-text-size-base);
	color: var(--listora-fg-default);
	margin: 0;
	line-height: 1.55;
}

@media (max-width: 640px) {
	.listora-detail__field-item {
		grid-template-columns: 1fr;
		gap: var(--listora-space-1, 0.25rem);
	}
}

/* Services tab - grid + card layout.
 * Service cards on the Services tab render as a responsive grid of
 * elevated cards with optional image, title, price, duration, and a
 * collapsible description. Previously missing - tab rendered unstyled
 * as a flat text list. */
.listora-detail__services-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: var(--listora-space-4, 1rem);
}

.listora-detail__service-card {
	display: flex;
	flex-direction: column;
	background: var(--listora-bg-elevated, #fff);
	border: 1px solid var(--listora-border-default, #e0e0e0);
	border-radius: var(--listora-radius-lg, 14px);
	overflow: hidden;
	transition: box-shadow var(--listora-transition-fast, 0.15s ease), transform var(--listora-transition-fast, 0.15s ease);
}

.listora-detail__service-card:hover {
	box-shadow: 0 6px 24px rgba(15, 23, 42, 0.08);
	transform: translateY(-1px);
}

.listora-detail__service-image {
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--listora-bg-muted, #f5f5f5);
}

.listora-detail__service-image img {
	width: 100%;
	height: 100%;
	display: block;
	object-fit: cover;
}

.listora-detail__service-body {
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-2, 0.5rem);
	padding: var(--listora-space-4, 1rem);
	flex: 1;
}

.listora-detail__service-title {
	margin: 0;
	font-size: var(--listora-text-size-lg, 1.0625rem);
	font-weight: 700;
	color: var(--listora-fg-default, #1a1a1a);
	line-height: 1.35;
}

.listora-detail__service-meta {
	display: flex;
	align-items: center;
	gap: var(--listora-space-3, 0.75rem);
	flex-wrap: wrap;
}

.listora-detail__service-price {
	font-size: var(--listora-text-size-base, 1rem);
	font-weight: 700;
	color: var(--listora-primary-text);
}

.listora-detail__service-duration {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	font-size: var(--listora-text-size-sm, 0.875rem);
	color: var(--listora-fg-muted, #555555);
}

.listora-detail__service-duration svg {
	color: var(--listora-fg-faint, #999999);
	flex-shrink: 0;
}

.listora-detail__service-desc-wrap {
	display: flex;
	flex-direction: column;
	gap: var(--listora-space-1, 0.25rem);
}

/* Service description toggle - card 9872013428.
 * Template emits `--collapsed` modifier on initial render; JS toggles it
 * via actions.toggleServiceDesc. Default state: 2-line clamp; expanded
 * state: full description height. */
.listora-detail__service-desc {
	margin: 0;
	font-size: var(--listora-text-size-sm);
	color: var(--listora-fg-muted);
	line-height: 1.5;
}

.listora-detail__service-desc--collapsed {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.listora-detail__service-toggle {
	font-size: var(--listora-text-size-xs);
	color: var(--listora-primary-text);
	background: none;
	border: 0;
	padding: var(--listora-space-1, 0.25rem) 0;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
}

.listora-detail__service-toggle svg {
	transition: transform var(--listora-transition-fast, 0.1s ease);
}

/* Rotate the chevron when the description has been expanded
 * (collapsed class removed by the toggle action). */
.listora-detail__service-desc:not(.listora-detail__service-desc--collapsed) ~ .listora-detail__service-toggle svg,
.listora-detail__service-card:has(.listora-detail__service-desc:not(.listora-detail__service-desc--collapsed)) .listora-detail__service-toggle svg {
	transform: rotate(180deg);
}

/* ─── Video (1.6.0) ──────────────────────────────────────────────────────────
   Responsive oEmbed wrapper. Providers return a fixed-width iframe, which
   overflows a card on mobile; the aspect-ratio box makes it fluid without
   depending on the provider's own responsive markup. Direction-neutral, so the
   RTL twin is identical. */

.listora-detail__video {
	margin-block-start: var(--listora-space-6);
}

.listora-detail__video-title {
	margin-block-end: var(--listora-space-3);
	font-size: var(--listora-text-size-lg);
	font-weight: 600;
	color: var(--listora-text);
}

.listora-detail__video-embed {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	border-radius: var(--listora-card-radius);
	background: var(--listora-bg-elevated);
}

.listora-detail__video-embed iframe,
.listora-detail__video-embed video,
.listora-detail__video-embed embed,
.listora-detail__video-embed object {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* ─── Tags (1.6.0) ───────────────────────────────────────────────────────────
   Tag chips under Features & Amenities. Each links into the directory's own
   `?tags=` filter, so a visitor can finally browse by a tag they can see.

   The `.listora-tag-badge` chip itself lives in src/components/badge.css — the
   listing-card block renders it too, and this sheet does not load on a grid.
   Only the section layout is block-specific and stays here. */

.listora-detail__tags {
	margin-block-start: var(--listora-space-6);
}

.listora-detail__tags-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--listora-space-2);
	margin-block-start: var(--listora-space-3);
}

/* ─── Gallery carousel (1.6.0) ───────────────────────────────────────────────
   Arrows + dots over the main image so every photo stays reachable once the
   thumbnail strip has scrolled out of view. Logical properties throughout, so
   the RTL twin is identical and prev/next follow reading direction. */

.listora-detail__gallery-main {
	position: relative;
}

.listora-detail__gallery-nav {
	position: absolute;
	inset-block-start: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--listora-tap-target, 44px);
	block-size: var(--listora-tap-target, 44px);
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: color-mix(in srgb, var(--listora-bg-elevated) 88%, transparent);
	color: var(--listora-text);
	cursor: pointer;
	backdrop-filter: blur(4px);
	transition: background 0.2s, color 0.2s;
}

.listora-detail__gallery-nav--prev {
	inset-inline-start: var(--listora-space-3);
}

.listora-detail__gallery-nav--next {
	inset-inline-end: var(--listora-space-3);
}

/* The next arrow points along the reading direction, so it flips in RTL. */
[dir="rtl"] .listora-detail__gallery-nav svg {
	transform: scaleX(-1);
}

.listora-detail__gallery-nav:hover {
	background: var(--listora-bg-elevated);
	color: var(--listora-primary-text);
}

.listora-detail__gallery-nav:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: 2px;
}

.listora-detail__gallery-dots {
	position: absolute;
	inset-block-end: var(--listora-space-3);
	inset-inline: 0;
	z-index: 2;
	display: flex;
	justify-content: center;
	gap: var(--listora-space-2);
}

/* The dot is 8px of PAINT inside a 40px touch region.
   Sizing the button itself at 8px gave a target a quarter of the WCAG 2.5.8
   minimum, and since the arrows hide on coarse pointers the dots are the only
   control left there — the smallest tappable thing on the page was also the
   only one. The visible dot is drawn by ::after so the target can grow
   without the dot growing with it. */
.listora-detail__gallery-dot {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--listora-tap-target, 40px);
	block-size: var(--listora-tap-target, 40px);
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.listora-detail__gallery-dot::after {
	content: "";
	inline-size: 8px;
	block-size: 8px;
	border-radius: 50%;
	background: color-mix(in srgb, var(--listora-bg-elevated) 60%, transparent);
	transition: background 0.2s, transform 0.2s;
}

.listora-detail__gallery-dot.is-active::after {
	background: var(--listora-bg-elevated);
	transform: scale(1.4);
}

.listora-detail__gallery-dot:focus-visible {
	outline: 2px solid var(--listora-primary);
	outline-offset: -6px;
	border-radius: 50%;
}

/* Touch: swipe carries navigation, so the arrows step aside for the photo.
   The dots stay — they are the only affordance showing HOW MANY photos there
   are, which is what tells a visitor to swipe at all.

   Gated on the POINTER, not the viewport. A width query also hid the arrows
   from anyone with a narrow desktop window, where there is no swipe to replace
   them — mouse and keyboard users lost every control except 8px dots. `hover:
   none` is true exactly when swipe is available. */
@media (hover: none) and (pointer: coarse) {
	.listora-detail__gallery-nav {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.listora-detail__gallery-nav,
	.listora-detail__gallery-dot::after {
		transition: none;
	}
}

/* Small aspect stars keep a thumb-sized tap area. */
.listora-reviews__star-input--small {
	gap: 0;
}

.listora-reviews__star-input--small .listora-reviews__star-label {
	padding: 0.35rem;
}

/* Visitors on an expired listing. */
.listora-detail__expired-notice {
	margin-block: 0 var(--listora-space-4);
	padding: var(--listora-space-3) var(--listora-space-4);
	border-radius: var(--listora-radius-md);
	background: var(--listora-warning-bg, color-mix(in srgb, var(--listora-warning) 12%, transparent));
	color: var(--listora-warning-fg, var(--listora-fg));
	font-size: var(--listora-card-meta-size);
}

/* ─── Phone: actions and tabs ─────────────────────────────────────────────
 *
 * Six full-width buttons stacked above the content pushed the description two
 * screens down, and the sticky bar already carries Save. Under 768px the bar is
 * there, so the inline Save goes; under 640px the rest wrap into full rows,
 * each label on one line (a fixed three-up grid broke "Add to Compare" and
 * Pro's "Feature for 25 credits · 30 days" onto three lines).
 * The tab strip stays one row that scrolls sideways (a fade at its end says
 * there is more) instead of wrapping into a three-row block.
 * ──────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
	.listora-detail__actions .listora-detail__action--save {
		display: none;
	}
}

@media (max-width: 640px) {
	.listora-detail__actions .listora-btn {
		flex: 1 1 auto;
		justify-content: center;
		padding-inline: 0.75rem;
		white-space: nowrap;
	}

	.listora-detail__tabs {
		flex-wrap: nowrap;
		width: 100%;
		scroll-snap-type: x proximity;
		mask-image: linear-gradient(to right, #000 92%, transparent 100%);
	}

	[dir="rtl"] .listora-detail__tabs {
		mask-image: linear-gradient(to left, #000 92%, transparent 100%);
	}

	.listora-detail__tabs .listora-detail__tab {
		flex-shrink: 0;
		scroll-snap-align: start;
	}
}
}
