/**
 * Plan Heavy search page.
 *
 * Inherits all tokens from listing.css.
 *
 * Mobile: two tab rows (type chips then action row).
 *         Map toggle = pink pill when active.
 *         Open Now / Nearby = underline active.
 * Desktop: type chips in tab bar; Open Now + Nearby in sidebar above Area;
 *          Map toggle stays in... no tab row on desktop sidebar.
 *          Two-column: 280px sidebar + results.
 *         Dietary: 2-col grid with icons.
 *         Inspiration chips row above first card.
 */

/* ══ Page ═══════════════════════════════════════════════════ */
.ph-search { background: var(--ph-color-bg); min-height: 80vh; }

/* ══ The one sticky line ════════════════════════════════════
   From the v2 design (ph-guided.jsx stickyBar): search, Filters with a
   count, Map, Video feed, count. Translucent with a blur, so the list
   reads through it rather than hitting a solid band. */
.ph-search__sticky {
	position: -webkit-sticky; position: sticky; top: 0; z-index: 30;
	background: rgba(255, 255, 255, 0.95);
	-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--line);
}
body.admin-bar .ph-search__sticky { top: 32px; }
@media screen and (max-width: 782px) { body.admin-bar .ph-search__sticky { top: 46px; } }

.ph-search__sticky-inner {
	display: flex; align-items: center; gap: var(--s2);
	padding-top: var(--s2); padding-bottom: var(--s2);
	max-width: 1180px;
}

/* Compact, and no submit button: the search runs as you type, so a Search
   button was a second way to do what the field already does, taking a
   third of the row to say it. */
.ph-search__form {
	display: flex; align-items: center; flex: 0 1 300px; min-width: 0;
	height: 38px; padding-inline: var(--s3);
	border: 1.5px solid var(--line);
	border-radius: var(--r-pill);
	background: var(--white);
	transition: border-color var(--fast);
}
.ph-search__form:focus-within { border-color: var(--pink); }
.ph-search__form-icon {
	color: var(--ink-3); font-size: 17px; width: 17px; height: 17px;
	margin-right: var(--s2); flex-shrink: 0;
}
.ph-search__form-input {
	flex: 1; border: none; background: transparent; padding: 0;
	font-size: var(--t-sm); font-family: inherit; font-weight: var(--w-med);
	outline: none; min-width: 0; color: var(--ink);
}
.ph-search__form-input::placeholder { color: var(--ink-3); }

/* Filters and Map: pills that fill pink when they are doing something. */
.ph-search__pill {
	flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
	min-height: 38px; padding-inline: var(--s3);
	border: 1.5px solid var(--line); border-radius: var(--r-pill);
	background: var(--white); color: var(--ink);
	font-size: var(--t-sm); font-weight: var(--w-heavy); font-family: inherit;
	white-space: nowrap; cursor: pointer;
	transition: background var(--fast), border-color var(--fast), color var(--fast);
}
.ph-search__pill .dashicons { font-size: 16px; width: 16px; height: 16px; color: var(--ink-2); }
.ph-search__pill:hover { border-color: var(--pink); }
.ph-search__pill.is-active {
	background: var(--pink); border-color: var(--pink); color: var(--white);
}
.ph-search__pill.is-active .dashicons { color: var(--white); }
.ph-search__filtercount {
	background: var(--pink); color: var(--white);
	border-radius: var(--r-pill); padding: 0 6px;
	font-size: var(--t-micro); font-weight: var(--w-heavy);
}
.ph-search__pill.is-active .ph-search__filtercount {
	background: rgba(255, 255, 255, 0.28);
}

.ph-search__iconbtn {
	flex: 0 0 auto; display: grid; place-items: center;
	width: 38px; height: 38px; border-radius: var(--r-pill);
	border: 1.5px solid var(--line); background: var(--white);
	color: var(--ink-2); cursor: pointer;
	transition: background var(--fast), border-color var(--fast), color var(--fast);
}
/* display:grid on the class beats the browser's [hidden] rule, so the
   reset button sat there permanently even though the JS had never shown
   it. Anything that sets display has to say what hidden means. */
.ph-search__iconbtn[hidden] { display: none; }
.ph-search__iconbtn .dashicons { font-size: 16px; width: 16px; height: 16px; }
.ph-search__iconbtn:hover { border-color: var(--pink); color: var(--pink-press); }
.ph-search__iconbtn.is-active {
	background: var(--ink); border-color: var(--ink); color: var(--white);
}

/* The count closes the line: what is on the left narrowed it, this is what
   it came to. */
.ph-search__count {
	margin-left: auto; flex: 0 0 auto; white-space: nowrap;
	font-size: var(--t-xs); font-weight: var(--w-heavy); color: var(--ink-2);
}

/* ══ The type row ═══════════════════════════════════════════ */
.ph-search__chiprow {
	background: var(--white);
	border-bottom: 1px solid var(--line);
	padding-block: var(--s3);
}

/* ══ Tab bar - row 1 (type chips) ════════════════════════════ */
.ph-search__tabs {
	position: -webkit-sticky; position: sticky; top: 0; z-index: 10;
	background: var(--ph-color-surface);
	border-top: 1px solid var(--ph-color-line);
	border-bottom: 2px solid var(--ph-color-line);
}
body.admin-bar .ph-search__tabs { top: 32px; }
@media screen and (max-width: 782px) { body.admin-bar .ph-search__tabs { top: 46px; } }

.ph-search__tabs-inner {
	display: flex; align-items: stretch;
	gap: var(--ph-space-3); min-height: 44px;
}
.ph-search__chips {
	display: flex; gap: var(--ph-space-4); flex: 1; min-width: 0;
	align-items: center;
	overflow-x: auto; overflow-y: hidden;
	-ms-overflow-style: none; scrollbar-width: none;
	/* The row scrolls, and on a phone it runs out of width mid-word right
	   where the Video Feed button starts. A hard cut against a black
	   button reads as text hidden behind it rather than as more to
	   scroll, so the last few pixels fade instead. The mask is on the
	   padding box, so it stays at the right edge while the chips move
	   under it. */
	-webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent 100%);
	mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent 100%);
}
.ph-search__chips::-webkit-scrollbar { display: none; }
/* Chip = tab-list link style (identical to ph-lh__tablist a) */
/* The type chip. A pill, as the design has it (Chip in ph-atoms.jsx), not
   an uppercase underline tab: these are things you pick, not sections you
   are inside, and as small caps they read as a navigation bar rather than
   as the filter they are. */
.ph-chip {
	flex-shrink: 0; display: inline-flex; align-items: center; gap: 6px;
	min-height: 38px; padding-inline: var(--s4);
	border: 1px solid var(--line); border-radius: var(--r-pill);
	background: var(--white); color: var(--ink);
	font-size: var(--t-sm); font-weight: var(--w-bold);
	text-transform: none; letter-spacing: normal;
	white-space: nowrap; font-family: inherit; cursor: pointer;
	transition: background var(--fast), border-color var(--fast), color var(--fast);
}
.ph-chip__icon { display: grid; place-items: center; flex: 0 0 auto; }
.ph-chip__icon svg { width: 15px; height: 15px; display: block; }
.ph-chip:hover { border-color: var(--pink); color: var(--pink-press); }
.ph-chip.is-active {
	background: var(--pink); border-color: var(--pink); color: var(--white);
}
.ph-chip.is-active .dashicons { color: var(--white); }

/* Map toggle in tab bar, far left of the type chips. Underline-tab style to
   match the type chips, with a divider after it. Desktop only (mobile uses the
   Map button in the action row instead). */
.ph-chip--map {
	flex-shrink: 0;
	width: 280px; box-sizing: border-box;
	display: inline-flex; align-items: center; justify-content: center; gap: 6px;
	padding: 0;
	border: 0;
	border-right: 1px solid var(--ph-color-line);
	border-bottom: 2px solid transparent;
	/* Loud enough to read as an action. It previously matched the type chips
	   in weight and colour, so the one control that changes the whole view
	   looked like a passive label. */
	background: var(--ph-color-ink);
	font-size: var(--ph-text-small); font-weight: 700; font-family: inherit;
	text-transform: uppercase; letter-spacing: 0.06em;
	color: #fff; cursor: pointer;
	border-radius: 0;
	transition: background 0.15s, color 0.15s;
}
.ph-chip--map:hover { background: var(--ph-color-primary); color: #fff; }
.ph-chip--map .dashicons { color: #fff; }
.ph-chip--map.is-active {
	background: var(--ph-color-primary);
	color: #fff;
	box-shadow: inset 0 -3px 0 0 rgba(0, 0, 0, 0.18);
}
.ph-chip--map.is-active .dashicons { color: #fff; }
.ph-chip--map .dashicons { font-size: 15px; width: 15px; height: 15px; }

/* Video feed button: pinned far right, solid pink backgrounded button so it
   reads as a distinct action, not a tab. It sits in its own fixed space at the
   right of the tab row (outside the scrolling chips), so the type tabs never
   slide underneath it. Visible on both desktop and mobile. */
.ph-search__videobtn {
	flex-shrink: 0; align-self: center;
	display: inline-flex; align-items: center; gap: 6px;
	padding: 9px 16px;
	background: var(--ph-color-ink); color: #fff;
	border: none; border-radius: var(--ph-radius-sm);
	font-size: 11px; font-weight: 700; font-family: inherit;
	text-transform: uppercase; letter-spacing: 0.05em;
	white-space: nowrap; cursor: pointer;
	transition: background 0.15s, transform 0.1s;
}
.ph-search__videobtn:hover { background: var(--ph-color-ink-soft, #5a5f73); }
.ph-search__videobtn:active { transform: scale(0.97); }
.ph-search__videobtn .dashicons { font-size: 15px; width: 15px; height: 15px; color: #fff; }

.ph-search__tabsright {
	display: flex; align-items: center; gap: var(--ph-space-2); flex-shrink: 0;
}
.ph-search__count {
	font-size: var(--ph-text-label); color: var(--ph-color-ink-soft); white-space: nowrap;
}
.ph-search__count strong { color: var(--ph-color-primary); }
.ph-search__reset-btn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 28px; height: 28px; border-radius: 50%;
	border: 1px solid var(--ph-color-line); background: var(--ph-color-surface);
	color: var(--ph-color-ink-soft); cursor: pointer;
	transition: border-color 0.15s;
}
.ph-search__reset-btn:hover { border-color: var(--ph-color-primary); color: var(--ph-color-primary); }
.ph-search__filterbtm {
	display: inline-flex; align-items: center; gap: 4px;
	min-height: 30px; padding: 4px var(--ph-space-3);
	border: 1px solid var(--ph-color-line); border-radius: var(--ph-radius-pill);
	background: var(--ph-color-surface); color: var(--ph-color-ink-soft);
	font-size: var(--ph-text-label); font-weight: 600; font-family: inherit;
	cursor: pointer; white-space: nowrap; transition: border-color 0.15s, color 0.15s;
}
.ph-search__filterbtm:hover { border-color: var(--ph-color-primary); color: var(--ph-color-primary); }
.ph-search__filterbtm .dashicons { font-size: 13px; width: 13px; height: 13px; }

/* ══ Action row - row 2 (Open Now | Nearby | Map + count/filter) ═ */
.ph-search__actionrow {
	background: var(--ph-color-surface);
	border-bottom: 1px solid var(--ph-color-line);
}
.ph-search__actionrow-inner {
	display: flex; align-items: center; justify-content: space-between;
	min-height: 40px; gap: var(--ph-space-2);
	flex-wrap: nowrap;
	overflow-x: auto;
	-ms-overflow-style: none; scrollbar-width: none;
}
.ph-search__actionrow-inner::-webkit-scrollbar { display: none; }
.ph-search__toggles {
	display: flex; align-items: center; gap: 0; flex-shrink: 0;
}
/* Open Now and Nearby: underline-style toggle (same as chips) */
.ph-search__toggle {
	display: inline-flex; align-items: center; gap: 4px;
	padding: 10px var(--ph-space-3) 10px 0;
	margin-right: var(--ph-space-3);
	color: var(--ph-color-ink-soft);
	font-size: 10.5px; font-weight: 600; font-family: inherit;
	text-transform: uppercase; letter-spacing: 0.06em;
	white-space: nowrap; background: none; border: none;
	border-bottom: 2px solid transparent;
	cursor: pointer; transition: color 0.15s, border-color 0.15s;
}
.ph-search__toggle .dashicons { font-size: 13px; width: 13px; height: 13px; }
/* Open Now and Nearby active = underline */
.ph-search__toggle.is-active {
	color: var(--ph-color-primary); border-bottom-color: var(--ph-color-primary);
}
/* Map toggle = pill fill when active */
.ph-search__toggle--map {
	padding: 7px var(--ph-space-3);
	border: 1.5px solid var(--ph-color-line);
	border-bottom: 1.5px solid var(--ph-color-line);
	border-radius: var(--ph-radius-pill);
	margin-right: var(--ph-space-4);
	transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.ph-search__toggle--map.is-active {
	background: var(--ph-color-primary);
	border-color: var(--ph-color-primary);
	color: #fff;
}
.ph-search__toggle--map.is-active .dashicons { color: #fff; }
.ph-search__actionright {
	display: flex; align-items: center; gap: var(--ph-space-2); flex-shrink: 0;
}
.ph-search__count--mob {
	font-size: var(--ph-text-label); color: var(--ph-color-ink-soft); white-space: nowrap;
}
.ph-search__count--mob strong { color: var(--ph-color-primary); }

/* ══ Desktop two-column layout ══════════════════════════════ */
/* Boxed to 1180 with a 290px rail, from the v2 desktop design (build brief
   section 7.2 and DesktopApp in ph-apps.jsx). The results column carries the
   white ground and a hairline down each side, so the page reads as one
   column of content rather than content floating on the page background. */
.ph-search__layout {
	display: grid; grid-template-columns: 290px 1fr;
	gap: var(--s4); align-items: start;
	padding-top: var(--s4);
	max-width: 1180px;
}

.ph-search__layout > .ph-search__results {
	background: var(--white);
	border-left: 1px solid var(--line);
	border-right: 1px solid var(--line);
	padding: var(--s4);
}

/* ══ Sidebar ════════════════════════════════════════════════ */
.ph-search__sidebar {
	position: sticky; top: 54px;
	height: calc(100vh - 54px); overflow-y: auto;
	/* The sidebar is now a transparent column: the Open now / Nearby pill
	   pair floats detached at the top, and the filter sections live in
	   their own card (.ph-sf__panel) below with a gap between the two. */
	background: transparent;
	border: 0;
	box-shadow: none;
	scrollbar-width: none;
}
.ph-search__sidebar::-webkit-scrollbar { display: none; }
.ph-sf__panel {
	background: var(--ph-color-surface);
	border: 1px solid var(--ph-color-line);
	border-radius: var(--ph-radius-md);
	box-shadow: var(--ph-shadow-card);
	overflow: hidden;
}
body.admin-bar .ph-search__sidebar { top: 86px; height: calc(100vh - 86px); }

/* Sidebar Open Now + Nearby toggles (above Area, desktop only) */
.ph-sf__toggles {
	display: flex; gap: 0;
	background: var(--ph-color-surface);
	border: 1px solid var(--ph-color-line);
	border-radius: var(--ph-radius-md);
	box-shadow: var(--ph-shadow-card);
	overflow: hidden;
	margin-bottom: var(--ph-space-4);
}
/* Vertical divider between the two halves of the pill. */
.ph-sf__toggle + .ph-sf__toggle {
	border-left: 1px solid var(--ph-color-line);
}
.ph-sf__toggle {
	flex: 1 1 0;
	display: inline-flex; align-items: center; justify-content: center; gap: 7px;
	padding: 15px var(--ph-space-2);
	border: 0;
	background: transparent; color: var(--ph-color-ink);
	font-size: 13px; font-weight: 700; font-family: inherit;
	cursor: pointer; white-space: nowrap;
	transition: color 0.15s, background 0.15s;
}
.ph-sf__toggle .dashicons { font-size: 15px; width: 15px; height: 15px; color: var(--ph-color-ink-soft); }
.ph-sf__toggle:hover { color: var(--ph-color-primary); }
.ph-sf__toggle.is-active {
	color: var(--ph-color-primary);
	background: rgba(232, 86, 138, 0.06);
}
.ph-sf__toggle.is-active .dashicons { color: var(--ph-color-primary); }

/* Accordion sections */
.ph-sf__section { border-bottom: 1px solid var(--ph-color-line); }
/* Plans mode hides the venue filter groups outright. Stated explicitly so a
   later display rule on a section cannot outrank the hidden attribute. */
.ph-sf__section[hidden],
.ph-sf__toggles[hidden],
.ph-search__toggles[hidden] { display: none !important; }
.ph-sf__section:last-child { border-bottom: none; }
.ph-sf__section--area    .ph-sf__head { background: rgba(232,86,138,0.04); }
.ph-sf__section--dietary .ph-sf__head { background: rgba(76,154,76,0.05); }
.ph-sf__section--cuisine .ph-sf__head { background: rgba(43,182,196,0.05); }
.ph-sf__section--features .ph-sf__head { background: rgba(224,166,56,0.04); }
.ph-sf__head {
	display: flex; align-items: center; justify-content: space-between;
	width: 100%; padding: 11px var(--ph-space-4);
	font-size: 10.5px; font-weight: 700; font-family: inherit;
	text-transform: uppercase; letter-spacing: 0.05em;
	color: var(--ph-color-ink); cursor: pointer; border: none; text-align: left;
}
.ph-sf__head--clickable:hover { background: rgba(0,0,0,0.03) !important; }
.ph-sf__chevron { font-size: 12px; width: 12px; height: 12px; transition: transform 0.2s; flex-shrink: 0; color: var(--ph-color-ink-soft); }
.ph-sf__head[aria-expanded="true"] .ph-sf__chevron { transform: rotate(180deg); }
.ph-sf__body { padding: var(--ph-space-2) var(--ph-space-3) var(--ph-space-3); }
.ph-sf__body--closed { display: none; }
.ph-sf__list { display: flex; flex-direction: column; }
.ph-sf__check {
	display: flex; align-items: center; gap: var(--ph-space-2);
	padding: 7px var(--ph-space-2); border-radius: var(--ph-radius-sm);
	font-size: var(--ph-text-small); color: var(--ph-color-ink);
	cursor: pointer; transition: background 0.1s; user-select: none;
}
.ph-sf__check:hover { background: var(--ph-color-bg); }
.ph-sf__check input { width: 14px; height: 14px; flex-shrink: 0; accent-color: var(--ph-color-primary); cursor: pointer; margin: 0; }

/* Dietary 2-col grid with icons */
.ph-sf__dietary-grid {
	display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
}
.ph-sf__dcheck {
	display: flex; flex-direction: column; align-items: center; gap: 4px;
	padding: var(--ph-space-3) var(--ph-space-2);
	border: 1.5px solid var(--ph-color-line); border-radius: var(--ph-radius-sm);
	cursor: pointer; transition: border-color 0.15s, background 0.1s;
	user-select: none; text-align: center; position: relative;
}
.ph-sf__dcheck:hover { background: var(--ph-color-bg); border-color: var(--ph-color-primary); }
.ph-sf__dcheck.is-checked { border-color: var(--ph-color-primary); background: rgba(232,86,138,0.06); }
.ph-sf__dcheck input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.ph-sf__dcheck-icon { width: 22px; height: 22px; color: var(--ph-color-ink-soft); }
.ph-sf__dcheck.is-checked .ph-sf__dcheck-icon { color: var(--ph-color-primary); }
.ph-sf__dcheck-label { font-size: 10.5px; font-weight: 600; color: var(--ph-color-ink-soft); line-height: 1.2; }
.ph-sf__dcheck.is-checked .ph-sf__dcheck-label { color: var(--ph-color-primary); }

/* Accessibility sub-label inside "Dietary and accessibility". Off by
   default (ph_show_accessibility_filters), see build brief section 5.2. */
.ph-sf__access-label {
	margin: var(--ph-space-3) 0 var(--ph-space-1);
	font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
	color: var(--ph-color-ink-soft);
}

/* Area tree */
.ph-area__group { margin-bottom: 1px; }
.ph-area__parent {
	display: flex; align-items: center; gap: var(--ph-space-2);
	padding: 7px var(--ph-space-2); border-radius: var(--ph-radius-sm);
	font-size: var(--ph-text-small); font-weight: 600; color: var(--ph-color-ink);
	cursor: pointer; user-select: none; transition: background 0.1s;
}
.ph-area__parent:hover { background: var(--ph-color-bg); }
.ph-area__parent input { width: 14px; height: 14px; accent-color: var(--ph-color-primary); flex-shrink: 0; margin: 0; cursor: pointer; }
.ph-area__parent-label { flex: 1; }
.ph-area__toggler { font-size: 12px; width: 12px; height: 12px; color: var(--ph-color-ink-soft); transition: transform 0.18s; flex-shrink: 0; cursor: pointer; }
.ph-area__toggler.is-open { transform: rotate(90deg); }
.ph-area__children { display: none; flex-direction: column; padding-left: var(--ph-space-4); }
.ph-area__children.is-open { display: flex; }
.ph-area__child {
	display: flex; align-items: center; gap: var(--ph-space-2);
	padding: 6px var(--ph-space-2); border-radius: var(--ph-radius-sm);
	font-size: var(--ph-text-small); color: var(--ph-color-ink-soft);
	cursor: pointer; user-select: none; transition: background 0.1s;
}
.ph-area__child:hover { background: var(--ph-color-bg); }
.ph-area__child input { width: 14px; height: 14px; accent-color: var(--ph-color-primary); flex-shrink: 0; margin: 0; cursor: pointer; }

/* ══ Results column ═════════════════════════════════════════ */
.ph-search__results { min-width: 0; }

/* ══ Boxed map ══════════════════════════════════════════════ */
.ph-search__mapbox {
	background: var(--ph-color-surface);
	border: 1px solid var(--ph-color-line);
	border-radius: var(--ph-radius-md);
	box-shadow: var(--ph-shadow-card);
	overflow: hidden; margin-bottom: var(--ph-space-4);
	position: relative;
	opacity: 0; transform: translateY(-6px);
	transition: opacity 0.22s ease, transform 0.22s ease;
}
.ph-search__mapbox.ph-mapbox--visible { opacity: 1; transform: translateY(0); }
.ph-search__mapbox[hidden] { display: none; }
/* Desktop: map stays pinned below the sticky toolbar while results scroll. */
@media (min-width: 1024px) {
	.ph-search__mapbox {
		position: sticky;
		top: 0;
		z-index: 5;
	}
}
/* Top left, not top right: Google puts its own map-type and fullscreen
   controls in the top-right corner, and the close button was sitting on top
   of them. */
.ph-search__map-head {
	position: absolute; top: var(--ph-space-2); left: var(--ph-space-2); z-index: 10;
	display: flex; justify-content: flex-start; padding: 0; background: transparent; border: 0;
}
.ph-search__map-close {
	font-size: var(--ph-text-label);
	background: var(--ph-color-surface);
	border: 1px solid var(--ph-color-line);
	box-shadow: var(--ph-shadow-card);
	border-radius: 999px; padding: 6px 12px;
}
.ph-search__map-canvas { width: 100%; height: 320px; display: block; }

/* Mobile-only video chip in tabs row: hidden at desktop widths. */
.ph-search__video-mobile { display: none; }

/* ══ Inspiration chips ══════════════════════════════════════ */
.ph-search__inspo { display: flex; gap: var(--ph-space-2); }
/* Mobile: single horizontal-scroll line, smaller pills, never wraps.
   Even vertical padding so the gap above the pills matches the gap below
   them (down to the first card). */
.ph-search__inspo.ph-search__inspo--mobile {
	flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
	-ms-overflow-style: none; scrollbar-width: none;
	background: var(--ph-color-bg);
	padding: 20px var(--ph-space-4) 20px;
	margin: 0;
}
.ph-search__inspo--mobile::-webkit-scrollbar { display: none; }
/* Desktop: in results column, wraps, sits above the grid/map */
/* Desktop: single horizontal-scroll line (matches mobile), more pills visible
   given the wider space. Hidden scrollbar. */
.ph-search__inspo--desktop {
	flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
	-ms-overflow-style: none; scrollbar-width: none;
	margin-bottom: var(--ph-space-3);
}
.ph-search__inspo--desktop::-webkit-scrollbar { display: none; }
/* The .ph-inspo-chip component itself now lives in components.css, so the
   occasion block on the front door and the inspiration row here are the same
   component rather than two that drift apart (rule 2.2). Only the mobile
   size override stays here, because it is specific to this row. */
/* Mobile pills: smaller, single line */
.ph-search__inspo--mobile .ph-inspo-chip {
	flex-shrink: 0; padding: 5px 12px; font-size: var(--ph-text-label); box-shadow: none;
}

/* ══ Card grid ══════════════════════════════════════════════ */
.ph-search__grid { display: flex; flex-direction: column; gap: var(--ph-space-3); }
.ph-search__empty { color: var(--ph-color-ink-soft); font-size: var(--ph-text-body); padding: var(--ph-space-6) 0; text-align: center; }

/* ══ Card ═══════════════════════════════════════════════════
   The v2 wide row card, from ListingCard size="w" in ph-atoms.jsx. The
   design uses the wide row on desktop search and the grid card on Explore,
   so this is a restyle of the row rather than a second card (brief section
   2: one card, do not build a third).

   Flat: a hairline and no shadow at rest. The old card carried a drop
   shadow on every row, which stacked into a grey wash down a long list. */
.ph-scard {
	background: var(--white); border: 1px solid var(--line);
	border-radius: var(--r-md); box-shadow: none;
	overflow: hidden; transition: border-color var(--fast), box-shadow var(--fast);
}
.ph-scard:hover { border-color: var(--line-2); box-shadow: var(--e1); }
.ph-scard--featured { outline: 2px solid var(--ph-color-featured); }
.ph-scard--draft { opacity: 0.78; outline: 2px dashed var(--ph-color-ink-soft); }
.ph-scard__inner { display: flex; align-items: stretch; }
.ph-scard__media-wrap { flex-shrink: 0; width: 180px; position: relative; }
.ph-scard__media { display: block; width: 100%; height: 100%; min-height: 160px; background: var(--ph-color-bg); }
.ph-scard__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ph-scard__img--placeholder { display: block; min-height: 160px; background: var(--ph-color-line); }
/* No photo at all: shrink the media column rather than reserving 200px
   for a picture that is not coming. Most listings have none yet, and the
   words are what the reader is actually comparing. */
.ph-scard__media-wrap:has(.ph-scard__img--placeholder) { width: 64px; }
.ph-scard__media-wrap:has(.ph-scard__img--placeholder) .ph-scard__media,
.ph-scard__img--placeholder { min-height: 0; }
@media (max-width: 900px) {
	/* The mobile card keeps its media column at 130px; a placeholder just
	   narrows it. Making it full width here wrapped the row and gave a
	   missing photo the top half of the card, which is the opposite of
	   what a reader wants. */
	.ph-scard__media-wrap:has(.ph-scard__img--placeholder) { width: 48px; }
}
/* The logo sits inside the photo, bottom left, rather than hanging off its
   edge. In the design it overlaps the image it belongs to; hanging it below
   the media box put it half onto the body text on a short card. */
.ph-scard__logo {
	position: absolute; left: var(--s3); bottom: var(--s3);
	width: 52px; height: 52px; border-radius: var(--r-pill);
	border: 2px solid var(--white); background: var(--white);
	object-fit: cover; box-shadow: var(--e1);
}
.ph-scard__status {
	position: absolute; left: 6px; top: 6px;
	background: var(--ph-color-ink); color: #fff;
	font-size: 10px; font-weight: 700; text-transform: uppercase;
	padding: 2px 6px; border-radius: var(--ph-radius-sm);
}
.ph-scard__body { flex: 1; min-width: 0; padding: var(--s4); display: flex; flex-direction: column; gap: 4px; }

/* Fully-vegan / fully-vegetarian bar. Desktop: a slim vertical strip between
   the image and the body, with the label reading bottom to top. Mobile: it
   becomes a full-width banner across the top of the card (see the 900px rule).
   Flex order places the strip between media (0) and body so DOM order is free. */
.ph-scard__dietbar {
	order: 1;
	flex: 0 0 26px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--ph-color-diet-vegetarian);
}
.ph-scard__dietbar--vegan { background: var(--ph-color-diet-vegan); }
.ph-scard__dietbar--vegetarian { background: var(--ph-color-diet-vegetarian); }
.ph-scard__dietbar-text {
	writing-mode: vertical-rl;
	transform: rotate(180deg);
	color: #fff;
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	white-space: nowrap;
}
.ph-scard__body { order: 2; }
.ph-scard__titlerow { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ph-space-2); }
/* 20px heavy with tight tracking, the design's wide-card heading. The name
   is what the reader scans, so it leads the card rather than sitting at
   body size level with the description under it. */
.ph-scard__title {
	font-size: 20px; font-weight: var(--w-heavy); color: var(--ink);
	text-decoration: none; line-height: 1.2; letter-spacing: -0.5px;
}
.ph-scard__title:hover { color: var(--pink-press); }
/* The save button is defined once, further down, next to the heart SVG
   rules that belong with it. It was defined twice, and the second block
   won silently, so the two had drifted apart. */
.ph-scard__desc { margin: 0; font-size: var(--t-body); color: var(--ink-2); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.45; }
.ph-scard__rating { display: flex; align-items: center; gap: 5px; }
.ph-scard__stars { color: #f5a623; font-size: 12px; letter-spacing: 0.5px; }
.ph-scard__rcount { font-size: 11px; color: var(--ph-color-ink-soft); }
.ph-scard__cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ph-space-2); margin-top: 2px; }
.ph-scard__col-left { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ph-scard__col-right { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ph-scard__row { margin: 0; font-size: var(--ph-text-small); color: var(--ph-color-ink); display: flex; align-items: center; gap: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ph-scard__row .dashicons { font-size: 13px; width: 13px; height: 13px; color: var(--ph-color-primary); flex-shrink: 0; }
.ph-scard__dtag { font-size: 11px; color: var(--ph-color-ink-soft); line-height: 1.5; display: inline-flex; align-items: center; gap: 4px; }
.ph-scard__dtag-icon { display: inline-flex; flex-shrink: 0; }
.ph-scard__dtag-icon svg { width: 13px; height: 13px; }
/* Footer is a vertical stack: top row (city + status + Show on map) then an
   optional stations row spanning the full width underneath. */
.ph-scard__foot { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--ph-color-line); padding: 8px var(--ph-space-4); background: var(--ph-color-bg); }
/* Top row: city + status together on the left, Show on map pushed to the right. */
.ph-scard__foot-top { display: flex; align-items: center; gap: var(--ph-space-2); flex-wrap: nowrap; min-width: 0; }
.ph-scard__area { font-size: var(--ph-text-label); font-weight: 700; color: var(--ph-color-ink); flex-shrink: 0; }
.ph-scard__open, .ph-scard__closed { flex-shrink: 0; }
/* Stations row: full width under the top row, horizontal scroll, never wraps. */
.ph-scard__stations { display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 5px; min-width: 0; width: 100%; -ms-overflow-style: none; scrollbar-width: none; }
.ph-scard__stations::-webkit-scrollbar { display: none; }
.ph-scard__station { flex-shrink: 0; display: inline-flex; align-items: center; gap: 3px; font-size: 10px; color: var(--ph-color-ink-soft); background: var(--ph-color-surface); border: 1px solid var(--ph-color-line); border-radius: var(--ph-radius-pill); padding: 2px 7px; white-space: nowrap; }
.ph-tube-icon { flex-shrink: 0; }
.ph-scard__open  { font-size: 11px; font-weight: 700; color: var(--ph-color-open); }
.ph-scard__open--closing { color: #fff; background: #ea8c00; padding: 2px 7px; border-radius: var(--ph-radius-pill); }
.ph-scard__closed{ font-size: 11px; font-weight: 600; color: var(--ph-color-ink-soft); }
.ph-scard__dist  { font-size: 11px; color: var(--ph-color-ink-soft); }
/* Show on map: pushed to the far right of the top row via auto margin. */
.ph-scard__pin { display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; margin-left: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: var(--ph-text-label); color: var(--ph-color-primary); cursor: pointer; }
.ph-scard__pin .dashicons { font-size: 15px; width: 15px; height: 15px; }
.ph-scard__pin-label { font-weight: 600; }
.ph-scard__directions { font-size: var(--ph-text-label); font-weight: 600; color: var(--ph-color-primary); text-decoration: underline; }

/* ══ Pagination ═════════════════════════════════════════════ */
.ph-search__pagination { display: flex; justify-content: center; gap: var(--ph-space-2); margin-top: var(--ph-space-6); flex-wrap: wrap; }
.ph-page { min-width: 34px; padding: 6px 9px; border: 1px solid var(--ph-color-line); border-radius: var(--ph-radius-sm); background: var(--ph-color-surface); font-family: inherit; font-size: var(--ph-text-small); cursor: pointer; }
.ph-page.is-current { background: var(--ph-color-primary); border-color: var(--ph-color-primary); color: #fff; font-weight: 700; }
.ph-page:disabled { opacity: 0.4; cursor: default; }
.ph-page__dots { align-self: center; color: var(--ph-color-ink-soft); }

/* ══ Sheets ═════════════════════════════════════════════════ */
.ph-sheet { position: fixed; inset: 0; background: rgba(17,24,39,0.45); z-index: 1000; display: flex; align-items: flex-end; justify-content: center; }
.ph-sheet[hidden] { display: none; }
.ph-sheet__panel { background: var(--ph-color-surface); width: 100%; max-width: 560px; max-height: 88vh; border-radius: var(--ph-radius-md) var(--ph-radius-md) 0 0; display: flex; flex-direction: column; }
.ph-sheet__head { display: flex; align-items: center; justify-content: space-between; padding: var(--ph-space-3) var(--ph-space-4); border-bottom: 1px solid var(--ph-color-line); }
.ph-sheet__title { margin: 0; font-size: var(--ph-text-body); font-weight: 700; }
.ph-sheet__close { border: none; background: none; font-size: 26px; line-height: 1; color: var(--ph-color-ink-soft); cursor: pointer; padding: 0 4px; }
.ph-sheet__body { padding: var(--ph-space-4); overflow-y: auto; flex: 1; }
.ph-sheet__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--ph-space-3); padding: var(--ph-space-3) var(--ph-space-4); border-top: 1px solid var(--ph-color-line); }
.ph-sheet__checklist { display: flex; flex-direction: column; }
.ph-sheet__checklist label { display: flex; align-items: center; gap: var(--ph-space-2); padding: 8px var(--ph-space-2); border-radius: var(--ph-radius-sm); font-size: var(--ph-text-small); color: var(--ph-color-ink); cursor: pointer; user-select: none; }
.ph-sheet__checklist label:hover { background: var(--ph-color-bg); }
.ph-sheet__checklist input { width: 14px; height: 14px; accent-color: var(--ph-color-primary); flex-shrink: 0; margin: 0; cursor: pointer; }

/* Sheet dietary 2-col */
.ph-sheet__dietary-grid {
	display: grid; grid-template-columns: 1fr 1fr; gap: var(--ph-space-2);
}
.ph-sheet__dcheck {
	display: flex; flex-direction: column; align-items: center; gap: 4px;
	padding: var(--ph-space-3) var(--ph-space-2);
	border: 1.5px solid var(--ph-color-line); border-radius: var(--ph-radius-sm);
	cursor: pointer; text-align: center; position: relative;
	transition: border-color 0.15s, background 0.1s; user-select: none;
}
.ph-sheet__dcheck:hover { background: var(--ph-color-bg); border-color: var(--ph-color-primary); }
.ph-sheet__dcheck.is-checked { border-color: var(--ph-color-primary); background: rgba(232,86,138,0.06); }
.ph-sheet__dcheck input { position: absolute; opacity: 0; pointer-events: none; }
.ph-sheet__dcheck-icon { width: 20px; height: 20px; color: var(--ph-color-ink-soft); }
.ph-sheet__dcheck.is-checked .ph-sheet__dcheck-icon { color: var(--ph-color-primary); }
.ph-sheet__dcheck-label { font-size: 10.5px; font-weight: 600; color: var(--ph-color-ink-soft); line-height: 1.2; }
.ph-sheet__dcheck.is-checked .ph-sheet__dcheck-label { color: var(--ph-color-primary); }

.ph-mf__section { border-bottom: 1px solid var(--ph-color-line); }
.ph-mf__section:last-child { border-bottom: none; }
.ph-mf__section--dietary { background: rgba(76,154,76,0.03); }
.ph-mf__head { display: flex; align-items: center; justify-content: space-between; padding: 11px 0; font-size: 10.5px; font-weight: 700; font-family: inherit; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ph-color-ink); cursor: pointer; user-select: none; background: none; border: none; width: 100%; }
.ph-mf__head[aria-expanded="true"] .ph-sf__chevron { transform: rotate(180deg); }
.ph-mf__body { padding-bottom: var(--ph-space-3); }
.ph-mf__body--closed { display: none; }
body.ph-sheet-open { overflow: hidden; }

/* ══ Mobile ═════════════════════════════════════════════════ */
@media (max-width: 900px) {
	/* Desktop Map chip hidden on mobile (Map lives in the action row instead).
	   The Video feed button stays visible, pinned far right of the tab row. */
	.ph-search__map-toggle-desktop { display: none; }
	.ph-search__inspo--desktop { display: none; }
	/* Search bar tighter on mobile */
	.ph-search__barwrap { padding: var(--ph-space-2) 0; }
	.ph-search__form-input { font-size: 14px; padding: 10px var(--ph-space-2) 10px 0; }
	.ph-search__form-submit { min-height: 40px; padding: 0 var(--ph-space-4); font-size: 13px; }
	.ph-search__form-icon { font-size: 15px; width: 15px; height: 15px; margin-left: var(--ph-space-3); }

	/* Type chips: at phone width all five tabs plus the video button must fit
	   without clipping or scrolling (per the design). Tabs are slightly smaller
	   and tighter on mobile to make room. No fade mask, no scroll. */
	.ph-search__chips {
		flex: 1; min-width: 0; gap: var(--ph-space-2);
		overflow: visible; justify-content: space-between;
	}
	.ph-search__chips .ph-chip {
		font-size: 9px; letter-spacing: 0.02em; gap: 2px;
	}

	/* Video feed button: compact, two-line label ("Video / Feed"), pinned far
	   right, sized so the tabs to its left are never clipped. */
	.ph-search__videobtn {
		flex-shrink: 0;
		padding: 5px 12px; font-size: 9.5px; line-height: 1.05;
		margin-left: var(--ph-space-2);
		text-align: left;
	}
	.ph-search__videobtn .ph-search__videobtn-label {
		display: inline-block; max-width: 4.5em; white-space: normal;
	}
	.ph-search__videobtn .dashicons { font-size: 14px; width: 14px; height: 14px; flex-shrink: 0; }

	/* Desktop filter button hidden (action row has its own) */
	.ph-search__tabsright .ph-search__filterbtm { display: none; }
	.ph-search__tabsright .ph-search__reset-btn { display: none; }
	.ph-search__tabsright .ph-search__count { display: none; }

	/* Layout: single column */
	.ph-search__layout { grid-template-columns: 1fr; padding-top: 0; gap: 0; }
	.ph-search__sidebar { display: none; }

	/* Mobile map: full width of the page, edge to edge. It loads inline at the
	   top of the results (first child of .ph-search__results, above the pills)
	   and sticks to the top just below the tab bar as the results scroll. No
	   side margins (full bleed), no drop shadow, no floating: it is part of the
	   page flow, exactly like the desktop map but spanning the full width. */
	.ph-search__mapbox {
		position: -webkit-sticky; position: sticky;
		top: 47px; /* tab bar: 44px min-height + 1px top + 2px bottom border */
		z-index: 6;
		width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: calc(50% - 50vw);
		margin-bottom: var(--ph-space-3);
		border-left: none; border-right: none;
		border-radius: 0;
		box-shadow: none;
	}
	body.admin-bar .ph-search__mapbox { top: 93px; } /* 46px admin bar + 47px tab bar */
	.ph-search__map-canvas { height: 240px; }

	.ph-search__results { padding: 0 0 var(--ph-space-3); }
	.ph-search__grid { padding: 0 var(--ph-space-4); }
	.ph-search__inspo { padding: 0 var(--ph-space-4); }
	.ph-search__pagination { padding: 0 var(--ph-space-4); }

	/* Cards: narrower image on mobile */
	.ph-scard__media-wrap { width: 130px; }
	.ph-scard__img--placeholder { min-height: 130px; }
	.ph-scard__cols { grid-template-columns: 1fr; gap: 2px; }

	/* Diet bar: full-width banner across the top of the card, horizontal text.
	   flex-wrap lets it take its own row above the image and body. */
	.ph-scard__inner { flex-wrap: wrap; }
	.ph-scard__dietbar {
		order: -1;
		flex: 0 0 100%;
		width: 100%;
		padding: 4px 0;
	}
	.ph-scard__dietbar-text {
		writing-mode: horizontal-tb;
		transform: none;
		font-size: 11px;
	}

	/* Full-screen sheets on mobile */
	.ph-sheet { align-items: stretch; }
	.ph-sheet__panel { max-width: none; max-height: none; border-radius: 0; height: 100%; }

	/* Show filter button in action row */
	.ph-search__filterbtm { display: inline-flex; }

	/* Mobile action row: drop the outline borders so the controls read as flat
	   text/icon buttons. The map toggle keeps its pink fill when active. */
	.ph-search__toggle--map { border: none; padding-left: 0; padding-right: 0; }
	.ph-search__toggle--map.is-active { padding-left: var(--ph-space-3); padding-right: var(--ph-space-3); }
	.ph-search__filterbtm { border: none; background: none; padding-left: 0; padding-right: 0; }
	.ph-search__reset-btn { border: none; background: none; }

	/* Equal spacing across all five controls (Map, Open Now, Nearby, Filter,
	   Reset). The two wrapper divs collapse with display:contents so every
	   control becomes a direct flex child of the row, then space-between
	   distributes them evenly. Per-control side margins are removed so the only
	   spacing comes from the even distribution. */
	.ph-search__toggles,
	.ph-search__actionright { display: contents; }
	.ph-search__actionrow-inner { justify-content: space-between; gap: var(--ph-space-2); }
	.ph-search__toggle { margin-right: 0; padding-right: 0; }
}

@media (min-width: 901px) {
	/* Action row hidden on desktop (sidebar has toggles, tab bar has chips) */
	.ph-search__actionrow { display: none; }
	/* Mobile inspo row hidden on desktop (desktop inspo lives in results column) */
	.ph-search__inspo--mobile { display: none; }
	/* Desktop: filter button in tab bar */
	.ph-search__filterbtm { display: none; }
}

/* ══ Chips tab bar: soft distinguishing background ══════════ */
/* Gives the Activity/Bar/Cafe/Restaurant/Plans row a subtle tint so the three
   bars stacked above each other (search, chips, action row) are visually
   distinct without being heavy. */
.ph-search__tabs {
	background: var(--ph-color-bg);
}

/* ══ Map marker popup ═══════════════════════════════════════ */
/* Used by Leaflet, Mapbox, and Google Maps. The popup HTML is built in
   popupHtml() in listings.js. Featured image on top, logo overlapping
   the bottom-left of the image, linked title, price band and area in
   small meta, open/closed status underneath. */
/* One design for every viewport (desktop matches mobile): the text block sits
   on the left with the logo stacked above the name, price, cuisine and area,
   then the open/closed status. The featured image bleeds in from the right
   behind a left-hand fade so it melts into the card behind the text. */
.ph-mpop {
	display: block;
	position: relative;
	width: 250px;
	min-height: 96px;
	background: #fff;
	font-family: inherit;
	overflow: hidden;
	border-radius: var(--ph-radius-md);
}
.ph-mpop--noimg { width: 200px; min-height: 0; }
.ph-mpop__media {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 58%;
	display: block;
	background-size: cover;
	background-position: center;
	background-color: var(--ph-color-line);
	text-decoration: none;
}
.ph-mpop__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to right, #fff 6%, rgba(255, 255, 255, 0.55) 46%, rgba(255, 255, 255, 0) 100%);
}
.ph-mpop__body {
	position: relative;
	z-index: 1;
	width: 80%;
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 3px;
}
.ph-mpop--noimg .ph-mpop__body { width: 100%; }
.ph-mpop__logo {
	width: 30px;
	height: 30px;
	border-radius: 50%;
	border: 1px solid var(--ph-color-line);
	object-fit: cover;
	background: #fff;
	margin-bottom: 2px;
}
.ph-mpop__title {
	display: block;
	font-size: 14px;
	font-weight: 700;
	color: var(--ph-color-ink);
	text-decoration: none;
	line-height: 1.25;
}
.ph-mpop__title:hover { color: var(--ph-color-primary); }
.ph-mpop__meta {
	font-size: 11.5px;
	color: var(--ph-color-ink-soft);
}
.ph-mpop__open  { font-size: 11px; font-weight: 700; color: var(--ph-color-open); }
.ph-mpop__closed{ font-size: 11px; font-weight: 600; color: var(--ph-color-ink-soft); }


/* Leaflet popup: tighten default padding so the card fits neatly */
.leaflet-popup-content-wrapper { padding: 0; border-radius: var(--ph-radius-md); overflow: hidden; }
.leaflet-popup-content { margin: 0; }
.leaflet-popup-tip-container { display: none; }

/* Google InfoWindow: by default Google caps the bubble height and scrolls the
   inner container, which clipped the bottom of the card (the open/closed line).
   Let the bubble grow to the whole card and stop the inner scroll. The inline
   max-height/overflow Google sets via JS are overridden by these !important
   rules, so the entire card shows with no scrollbar. */
.gm-style .gm-style-iw-c {
	max-height: none !important;
	overflow: visible !important;
}
.gm-style .gm-style-iw-d {
	max-height: none !important;
	overflow: visible !important;
}

/* ══ Card flash (scroll-to-card from map marker click) ══════ */
@keyframes ph-flash {
	0%   { box-shadow: 0 0 0 3px var(--ph-color-primary); }
	60%  { box-shadow: 0 0 0 3px var(--ph-color-primary); }
	100% { box-shadow: var(--ph-shadow-card); }
}
.ph-scard--flash {
	animation: ph-flash 1.6s ease forwards;
}

/* ══ Safari bottom chrome safe-area ════════════════════════
   viewport-fit=cover is declared in header.php.
   env(safe-area-inset-bottom) covers the home-indicator gap;
   adding 60 px extra clears the Safari toolbar when visible.  */
@media (max-width: 900px) {
	/* Scrollable results: last card can always be scrolled fully into view */
	.ph-search__grid {
		padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 60px);
	}
	/* Filter sheet footer: Apply button never hidden under toolbar */
	.ph-sheet__foot {
		padding-bottom: calc(var(--ph-space-3) + env(safe-area-inset-bottom, 0px));
	}
}

/* --- Search mode switcher and tints --- */
/* Each mode defines its own accent. Explore is the brand pink; Plan leans to a
   calm indigo for itinerary building; Dietary uses a fresh green. The tint is
   applied via a data attribute on the search container so it re-colours the
   mode row and a few accent touches without redesigning the page. */
.ph-search { --ph-accent: var(--ph-color-primary, #e8568a); }
.ph-search[data-search-mode="explore"] { --ph-accent: var(--ph-color-primary, #e8568a); }
.ph-search[data-search-mode="plan"]    { --ph-accent: #4655b8; }
.ph-search[data-search-mode="dietary"] { --ph-accent: #1f7d54; }

.ph-search__modes {
	background: #fff; border-bottom: 1px solid var(--ph-color-line, #e6e7eb);
}
.ph-search__modes-inner { display: flex; gap: 6px; padding: 8px 0; }
.ph-search__mode {
	display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 13px; font-weight: 600;
	padding: 7px 16px; border-radius: 999px; border: 1px solid var(--ph-color-line, #e6e7eb);
	background: #fff; color: var(--ph-color-ink-soft, #6b7280); cursor: pointer;
	min-height: 40px; transition: color .12s, border-color .12s, background .12s;
}
.ph-search__mode .dashicons { font-size: 16px; width: 16px; height: 16px; }
.ph-search__mode:hover { color: var(--ph-accent); border-color: var(--ph-accent); }
.ph-search__mode.is-active {
	color: #fff; background: var(--ph-accent); border-color: var(--ph-accent);
}
/* Accent touches that follow the active mode. */
.ph-search[data-mode] .ph-search__form:focus-within { border-color: var(--ph-accent); }
.ph-search[data-mode] .ph-search__form-submit { background: var(--ph-accent); }

/* ══ Per-city hero ══════════════════════════════════════════
   "Where to eat in Birmingham" (wording per listing type).
   Rendered by listings.js only when exactly one city is
   selected in the Area filter. Warm editorial band that sits
   above the map and results. Zero-count stats are not shown. */
.ph-hero {
	background: linear-gradient(160deg, #9c4a28, #c96a3a 70%, #dd8048);
	color: #fff;
	border-radius: var(--ph-radius-md);
	padding: var(--ph-space-5) var(--ph-space-6);
	margin-bottom: var(--ph-space-4);
}
.ph-hero[hidden] { display: none; }
.ph-hero__eyebrow {
	font-size: 11.5px; font-weight: 700;
	text-transform: uppercase; letter-spacing: 0.08em;
	color: rgba(255, 255, 255, 0.85);
	margin-bottom: 7px;
}
.ph-hero__title {
	font-size: 26px; font-weight: 800; letter-spacing: -0.7px;
	line-height: 1.1; margin: 0; color: #fff;
}
.ph-hero__stats { display: flex; gap: var(--ph-space-5); margin-top: var(--ph-space-4); flex-wrap: wrap; }
.ph-hero__stat { display: flex; flex-direction: column; }
.ph-hero__statn { font-size: 22px; font-weight: 800; line-height: 1.1; }
.ph-hero__statl { font-size: 11.5px; opacity: 0.85; }

@media (max-width: 900px) {
	.ph-hero { padding: var(--ph-space-4) var(--ph-space-4); }
	.ph-hero__title { font-size: 21px; }
	.ph-hero__stats { gap: var(--ph-space-4); }
	.ph-hero__statn { font-size: 19px; }
}

/* ══ Dietary / accessibility modes (search) ═════════════════
   Functional filter pills above the results. Each carries its
   own accent on hover and when active; the active mode also sets
   data-mode on the search wrap for a light page tint. */
.ph-search__dmodes {
	display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
	margin-bottom: var(--ph-space-4);
}
.ph-search__dmodes-label {
	font-size: 11px; font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.06em; color: var(--ph-color-ink-soft); margin-right: 2px;
}
.ph-dmode {
	border: 1.5px solid var(--ph-color-line); background: var(--ph-color-surface);
	border-radius: var(--ph-radius-pill); padding: 7px 15px;
	font-size: 12.5px; font-weight: 700; font-family: inherit; color: var(--ph-color-ink);
	cursor: pointer; transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.ph-dmode--vegan:hover,  .ph-dmode--vegan.is-on  { border-color: #2e9e6b; color: #fff; background: #2e9e6b; }
.ph-dmode--veggie:hover, .ph-dmode--veggie.is-on { border-color: #5a9e3f; color: #fff; background: #5a9e3f; }
.ph-dmode--halal:hover,  .ph-dmode--halal.is-on  { border-color: #1d8a8a; color: #fff; background: #1d8a8a; }
.ph-dmode--access:hover, .ph-dmode--access.is-on { border-color: #2b6fc4; color: #fff; background: #2b6fc4; }

/* Light page tint per active mode: recolours the active type chip
   underline and the map toggle so the mode is felt, not just shown.
   Deliberately subtle (rule 2.6: tint, do not redesign). */
.ph-search[data-mode="vegan"]      { --ph-mode-accent: #2e9e6b; }
.ph-search[data-mode="veggie"]     { --ph-mode-accent: #5a9e3f; }
.ph-search[data-mode="halal"]      { --ph-mode-accent: #1d8a8a; }
.ph-search[data-mode="accessible"] { --ph-mode-accent: #2b6fc4; }
.ph-search[data-mode="vegan"] .ph-search__tab.is-active,
.ph-search[data-mode="veggie"] .ph-search__tab.is-active,
.ph-search[data-mode="halal"] .ph-search__tab.is-active,
.ph-search[data-mode="accessible"] .ph-search__tab.is-active {
	color: var(--ph-mode-accent);
}
.ph-search[data-mode="vegan"] .ph-search__tab.is-active::after,
.ph-search[data-mode="veggie"] .ph-search__tab.is-active::after,
.ph-search[data-mode="halal"] .ph-search__tab.is-active::after,
.ph-search[data-mode="accessible"] .ph-search__tab.is-active::after {
	background: var(--ph-mode-accent);
}

/* Dietary search mode surfaces the dietary filter group: a soft ring and
   accent header so the thing the user switched modes for reads as primary.
   Subtle, per rule 2.6 (tint, do not redesign). */
.ph-sf__section--dietary.ph-sf__section--surfaced {
	background: #f0f9f4; border-radius: var(--ph-radius-md);
	box-shadow: inset 0 0 0 1.5px #1f7d54; padding: 4px 10px 6px;
}
.ph-sf__section--dietary.ph-sf__section--surfaced .ph-sf__head span:first-child { color: #1f7d54; }

/* ── Plan and guide result cards ───────────────────────────────
   Plans appear in the same results grid as venues via the Plans chip, so the
   card borrows the venue card's shell and only differs where a plan differs:
   a wide cover, a Plan or Guide marker, and its categories instead of
   location and price. */
.ph-scard--plan { overflow: hidden; }
.ph-scard--plan .ph-scard__link { display: block; text-decoration: none; color: inherit; }
.ph-scard--plan .ph-scard__media {
	position: relative;
	width: 100%;
	min-height: 0;
	aspect-ratio: 16 / 9;
	overflow: hidden;
}
.ph-scard--plan .ph-scard__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ph-scard--plan .ph-scard__media.is-empty { aspect-ratio: auto; min-height: 0; height: 8px; }
.ph-scard__kind {
	position: absolute;
	top: var(--ph-space-2);
	left: var(--ph-space-2);
	background: var(--ph-color-primary);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	padding: 3px 9px;
	border-radius: var(--ph-radius-pill);
}
.ph-scard--plan .ph-scard__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	font-size: var(--ph-text-small);
	color: var(--ph-color-ink-soft);
	margin-top: 2px;
}
.ph-scard__cat {
	background: var(--ph-color-bg);
	border: 1px solid var(--ph-color-line);
	border-radius: var(--ph-radius-pill);
	padding: 2px 9px;
	font-size: 11.5px;
}

/* ── Plan shape switch (All / Plans / Guides) ──────────────────
   Plans and guides share a results grid but are different things to read, so
   the sidebar lets you narrow to one. Styled as a segmented control rather
   than more checkboxes because the three options are mutually exclusive. */
.ph-sf__shape { display: flex; border: 1px solid var(--ph-color-line); border-radius: var(--ph-radius-pill); overflow: hidden; }
.ph-sf__shapebtn { flex: 1; border: 0; background: var(--ph-color-surface); color: var(--ph-color-ink-soft); font-family: inherit; font-size: 12.5px; font-weight: 600; padding: 8px 6px; cursor: pointer; min-height: 40px; }
.ph-sf__shapebtn:hover { color: var(--ph-color-primary); }
.ph-sf__shapebtn.is-on { background: var(--ph-color-primary); color: #fff; }
.ph-sf__shapehint { font-size: 11.5px; color: var(--ph-color-ink-soft); margin: 8px 0 0; line-height: 1.4; }

/* The plan-type list uses the same row treatment as the other filter groups,
   so it stops looking like a bare card dropped beside them. */
.ph-sf__section--plancats .ph-sf__list { display: flex; flex-direction: column; gap: 2px; }
.ph-sf__section--plancats .ph-sf__list label {
	display: flex; align-items: center; gap: 8px;
	font-size: var(--ph-text-small); color: var(--ph-color-ink);
	padding: 7px 8px; border-radius: var(--ph-radius-sm); cursor: pointer;
	min-height: 40px; box-sizing: border-box;
}
.ph-sf__section--plancats .ph-sf__list label:hover { background: var(--ph-color-bg); }
.ph-sf__section--plancats .ph-sf__list input { accent-color: var(--ph-color-primary); margin: 0; }

/* Heart: an SVG rather than the ♥/♡ text glyphs, which rendered at whatever
   weight and size the system font chose and looked lopsided next to the card
   type. Outline by default, filled once saved. */
/* Save. The v2 card carries this as a pink-outlined circle rather than a
   grey one: it is an action on the card, and at grey it read as a disabled
   control sitting next to the name. Saved fills it. */
.ph-scard__fav { display: inline-flex; align-items: center; justify-content: center; padding: 6px; line-height: 0; color: var(--pink); background: var(--white); border: 1.5px solid var(--pink); border-radius: var(--r-pill); cursor: pointer; min-width: 38px; min-height: 38px; transition: background var(--fast), color var(--fast); }
.ph-scard__fav:hover { background: var(--pink-soft); }
.ph-scard__fav.is-fav { background: var(--pink); color: var(--white); border-color: var(--pink); --ph-heart-fill: currentColor; }
.ph-scard__fav svg { display: block; }

/* Plan and guide cards sit in the same grid as venue cards, so they reuse the
   venue shell and only differ where a plan differs: a Plan or Guide marker on
   the image and its categories in place of dietary icons. */
.ph-scard--plan .ph-scard__media { position: relative; }
.ph-scard--plan .ph-scard__kind { position: absolute; top: 8px; left: 8px; background: var(--ph-color-primary); color: #fff; font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; padding: 3px 9px; border-radius: var(--ph-radius-pill); }
.ph-scard__cats { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.ph-scard__cat { background: var(--ph-color-bg); border: 1px solid var(--ph-color-line); border-radius: var(--ph-radius-pill); padding: 2px 9px; font-size: 11.5px; color: var(--ph-color-ink-soft); }

/* Plan and guide card footer: the venue card's own footer classes are reused
   so the two never drift. Only the extras a plan has need styling here. */
.ph-scard--plan .ph-scard__meta-inline { font-size: var(--ph-text-small); color: var(--ph-color-ink-soft); }
.ph-scard__pin--go { text-decoration: none; margin-left: auto; }

/* ---------- Map toggle prominence ----------
   The Map button sat in the same pill treatment as the type chips, so it read
   as one more filter rather than a mode switch. It now carries the brand
   outline and a filled active state, which is the same weight as the Video
   feed button on the opposite end of the bar. The two mode switches now
   bookend the type chips and look like a matched pair. */
.ph-chip--map {
	border: 1.5px solid var(--ph-color-primary);
	color: var(--ph-color-primary);
	font-weight: 700;
	letter-spacing: 0.02em;
	background: var(--ph-color-surface);
	flex-shrink: 0;
}
.ph-chip--map .dashicons { color: var(--ph-color-primary); }
.ph-chip--map:hover {
	background: var(--ph-color-primary);
	color: #fff;
}
.ph-chip--map:hover .dashicons { color: #fff; }
/* Map open: filled, so it is obvious the map is the thing being toggled. */
.ph-chip--map.is-active,
.ph-chip--map[aria-pressed="true"] {
	background: var(--ph-color-primary);
	border-color: var(--ph-color-primary);
	color: #fff;
}
.ph-chip--map.is-active .dashicons,
.ph-chip--map[aria-pressed="true"] .dashicons { color: #fff; }

/* ══ Occasion filter group ═════════════════════════════════════
   Same pattern as every other sidebar group (rule 2.2): a header, an
   accordion body, a list of checkbox rows. Single-select is enforced in
   listings.js, not here; visually it is a plain checklist. */
.ph-sf__section--occasion .ph-sf__list { display: flex; flex-direction: column; gap: 2px; }

/* ── Applied pills ──────────────────────────────────────────
   Every active filter, separately removable, plus a white "auto" pill when
   an occasion implies a constraint (e.g. "Open 09:00 to 14:00"), so the
   derivation stays visible rather than a silent narrowing. */
.ph-applied {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ph-space-2);
	padding: var(--ph-space-3) var(--ph-space-4);
	border-top: 1px solid var(--ph-color-line);
}
.ph-applied[hidden] { display: none; }

.ph-applied__label {
	font-size: var(--ph-text-label);
	font-weight: 800;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var(--ph-color-ink-soft);
	margin-right: var(--ph-space-1);
}

.ph-applied__pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 5px 6px 5px 12px;
	border-radius: var(--ph-radius-pill);
	background: var(--ph-color-primary);
	color: #fff;
	font-size: var(--ph-text-label);
	font-weight: 700;
}

/* The auto pill is white: it did not come from a tap, it came from picking
   an occasion, and the visual difference is what makes that legible. */
.ph-applied__pill--auto {
	background: var(--ph-color-surface);
	border: 1.5px solid var(--ph-color-line);
	color: var(--ph-color-ink-soft);
}

.ph-applied__pill-x {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border: none;
	border-radius: 999px;
	background: rgba(255,255,255,0.22);
	color: inherit;
	font-size: 10px;
	line-height: 1;
	cursor: pointer;
}
.ph-applied__pill--auto .ph-applied__pill-x { background: var(--ph-color-line); }
.ph-applied__pill-x:hover { filter: brightness(0.92); }

.ph-applied__clear {
	margin-left: auto;
	background: none;
	border: none;
	font-size: var(--ph-text-small);
	font-weight: 800;
	color: var(--ph-color-primary);
	cursor: pointer;
	padding: 6px 4px;
}
.ph-applied__clear:hover { text-decoration: underline; }

@media (min-width: 783px) {
	.ph-applied--mobile { display: none !important; }
}
@media (max-width: 782px) {
	.ph-applied--desktop { display: none !important; }
}

/* ══ Occasion group: icon buttons, not a checklist ═════════════
   "What are you after" leads the sidebar and is meant to feel like the
   primary decision, not one filter among several, so it gets its own tinted
   background and a 3-column icon grid rather than the plain checkbox rows
   every other group uses. Desktop: 3 columns. Mobile follows the dietary
   grid's 2-column pattern, since the sheet is narrower. */
.ph-sf__section--occasion {
	background: linear-gradient(180deg, rgba(232,86,138,0.05), rgba(232,86,138,0) 70%);
}
.ph-sf__section--occasion .ph-sf__head span:first-child {
	font-weight: 800;
	color: var(--ph-color-ink);
}

.ph-sf__occ-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 6px;
}

.ph-sf__occbtn {
	display: flex; flex-direction: column; align-items: center; gap: 5px;
	padding: var(--ph-space-3) var(--ph-space-1);
	border: 1.5px solid var(--ph-color-line);
	border-radius: var(--ph-radius-sm);
	background: var(--ph-color-surface);
	cursor: pointer;
	text-align: center;
	transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.ph-sf__occbtn:hover { border-color: var(--ph-color-primary); background: var(--ph-color-bg); }
.ph-sf__occbtn:active { transform: scale(0.97); }
.ph-sf__occbtn.is-checked {
	border-color: var(--ph-color-primary);
	background: var(--ph-color-primary);
}
.ph-sf__occbtn-icon { width: 22px; height: 22px; color: var(--ph-color-ink-soft); }
.ph-sf__occbtn.is-checked .ph-sf__occbtn-icon { color: #fff; }
.ph-sf__occbtn-label {
	font-size: 10.5px; font-weight: 700; line-height: 1.2;
	color: var(--ph-color-ink-soft);
}
.ph-sf__occbtn.is-checked .ph-sf__occbtn-label { color: #fff; }

/* Mobile sheet: same icon-button idea, 2 columns to match the sheet's
   narrower dietary grid, built on a hidden checkbox so Apply and Clear work
   exactly as they do for every other mobile sheet group. */
[data-ph-occasion-section-mob] {
	background: linear-gradient(180deg, rgba(232,86,138,0.05), rgba(232,86,138,0) 70%);
}
[data-ph-occasion-section-mob] .ph-mf__head span:first-child { font-weight: 800; }

.ph-sheet__occ-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 6px;
}
.ph-sheet__occbtn {
	display: flex; flex-direction: column; align-items: center; gap: 5px;
	padding: var(--ph-space-3) var(--ph-space-2);
	border: 1.5px solid var(--ph-color-line); border-radius: var(--ph-radius-sm);
	cursor: pointer; text-align: center; position: relative;
	transition: border-color 0.15s, background 0.1s; user-select: none;
}
.ph-sheet__occbtn:hover { background: var(--ph-color-bg); border-color: var(--ph-color-primary); }
.ph-sheet__occbtn.is-checked { border-color: var(--ph-color-primary); background: var(--ph-color-primary); }
.ph-sheet__occbtn input { position: absolute; opacity: 0; pointer-events: none; }
.ph-sheet__occbtn-icon { width: 20px; height: 20px; color: var(--ph-color-ink-soft); }
.ph-sheet__occbtn.is-checked .ph-sheet__occbtn-icon { color: #fff; }
.ph-sheet__occbtn-label { font-size: 10.5px; font-weight: 600; color: var(--ph-color-ink-soft); line-height: 1.2; }
.ph-sheet__occbtn.is-checked .ph-sheet__occbtn-label { color: #fff; }

/* ══ Mode banner ═══════════════════════════════════════════
   "N hidden by your Vegan setting, show anyway". Never rendered in trail
   mode, where dietary does not apply (build brief acceptance check 6). */
/* [hidden] must win. A bare `display: flex` here beats the UA
   stylesheet's `[hidden] { display: none }`, which left an empty pink
   strip on every search with no mode set. */
.ph-modebanner[hidden] { display: none; }
.ph-modebanner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ph-space-3);
	margin: var(--ph-space-3) 0;
	padding: var(--ph-space-3) var(--ph-space-4);
	border: 1px solid var(--ph-color-line);
	border-left: 3px solid var(--ph-color-primary);
	border-radius: var(--ph-radius-sm);
	background: var(--pink-soft, #fdeef4);
}
.ph-modebanner__text {
	font-size: var(--ph-text-small);
	font-weight: 600;
	color: var(--ph-color-ink);
}
.ph-modebanner__show {
	flex-shrink: 0;
	padding: 6px 12px;
	border: 1px solid var(--ph-color-primary);
	border-radius: var(--ph-radius-pill);
	background: #fff;
	color: var(--ph-color-primary);
	font-family: inherit;
	font-size: var(--ph-text-label);
	font-weight: 600;
	cursor: pointer;
}
.ph-modebanner__show:hover { background: var(--ph-color-primary); color: #fff; }

/* Filter button count. Sits on the Filter button in the mobile sticky line
   so the reader can see something is narrowing the results without opening
   the sheet (build brief section 7.1). Hidden at zero by the JS. */
/* Same [hidden] trap as the mode banner: a bare display value beats the
   UA stylesheet, which left a "0" badge on every unfiltered search. */
.ph-search__filtercount[hidden] { display: none; }
.ph-search__filtercount {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	margin-left: 4px;
	border-radius: var(--ph-radius-pill);
	background: var(--ph-color-primary);
	color: #fff;
	font-size: 10px;
	font-weight: 700;
	line-height: 1;
}

/* ══ The moment row ═════════════════════════════════════════
   The design's OccRow, sitting between the type chips and the results:
   an icon over a label, in clock order. Tiles rather than pills, because
   an icon carries the idea faster than the word does at this size. */
.ph-search__occrow {
	background: var(--white);
	border-bottom: 1px solid var(--line);
	padding-block: var(--s3);
}
.ph-search__occrow[hidden] { display: none; }
.ph-search__occrow-inner {
	display: flex;
	gap: var(--s2);
	overflow-x: auto;
	scrollbar-width: none;
	max-width: 1180px;
}
.ph-search__occrow-inner::-webkit-scrollbar { display: none; }

.ph-occtile {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	gap: 6px;
	min-width: 92px;
	padding: var(--s3) var(--s2);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--white);
	color: var(--ink);
	font-family: inherit;
	cursor: pointer;
	transition: border-color var(--fast), background var(--fast), color var(--fast);
}
.ph-occtile__icon { display: grid; place-items: center; }
.ph-occtile__icon svg { width: 22px; height: 22px; display: block; }
.ph-occtile__label { font-size: var(--t-xs); font-weight: var(--w-bold); white-space: nowrap; }
.ph-occtile:hover { border-color: var(--pink); color: var(--pink-press); }
.ph-occtile.is-active {
	background: var(--pink-soft);
	border-color: var(--pink);
	color: var(--pink-press);
}

/* ══ Rail order ═════════════════════════════════════════════
   The design leads the rail with Area: where you are is the first thing
   that narrows a directory, and it was sitting under a group that only
   applies to some types. Flex order moves it without moving the markup,
   so nothing that reads the DOM order has to change. */
.ph-search__sidebar .ph-sf__panel { display: flex; flex-direction: column; }
.ph-search__sidebar .ph-sf__section { order: 2; }
.ph-search__sidebar .ph-sf__section--area { order: 1; }

/* The rail is on screen, so the sticky line does not need a Filters pill
   as well. The design only shows it where there is no rail. */
@media (min-width: 1000px) {
	.ph-search__sticky-inner [data-ph-open-filter] { display: none; }
}
