/**
 * Quote tool - the multi-step "Join the Y" membership explorer.
 *
 * Ported from join.ymcachicago.org and re-expressed in this theme's tokens
 * (defaults.css) - no raw hex outside the shell's own custom property below.
 *
 * Layout notes (all inherited from the Chicago build - they are load-bearing):
 * - No form-id selectors. Everything is scoped to #quote-tool with attribute
 *   selectors ([id^="gform_submit_button_"], …) so the form id lives only in
 *   QUOTE_TOOL_FORM_ID.
 * - Pages are identified by ROLE via :has() - never by GF's numbered ids. The
 *   intro page is the one holding .qt-copy-intro, the finder page holds
 *   .quote-tool-map-field, the rates page holds .quote-tool-radio. The intro
 *   page can be switched off entirely ([quote_tool contact_info="false"]).
 * - The rates step sits on the blue gradient: JS stamps .quote-tool--on-last
 *   on the module (keyed off data-total-steps, never "page 3").
 *
 * Step-2 card styles live in archive-cards/archive-card-locations.css (the
 * cards ARE the locations-archive cards); only in-form overrides live here.
 */

.quote-tool__hidden {
	display: none !important;
}

/* Section shell ---------------------------------------------------------- */

/* The wrapper is a <section> so the tool is a named region like every other
   content block. Its vertical rhythm is #quote-tool's own 3rem margin, so
   defaults.css's blanket `section { padding: 36px 0 }` - and the 50px
   `section:first-of-type` bump - must not land on top of it.
   Inside a .page-row the theme's own `.page-row … .container` rules already
   zero that padding; this covers the tool rendering anywhere else, and needs
   two classes to outrank :first-of-type without !important.
   Delete it if the tool should ever take the standard block padding. */
.quote-tool-section.container {
	padding-top: 0;
	padding-bottom: 0;
}


/* Module shell ----------------------------------------------------------- */

#quote-tool {
	/* The thank-you panel's photo, and the side photo it falls back to; both
       are set inline by the template (shortcode attribute, else the defaults
       in quote_tool_default_image()). A gradient is a valid background-image,
       so the fallback paints brand blue instead of a broken frame.
       --qt-side-photo no longer paints anything itself: step 1 lost its photo
       column on 2026-09-21 and the variable is kept only as the
       confirmation's fallback (and so the photo can be restored in one rule). */
	--qt-side-photo: var(--blue-background-gradient);
	--qt-confirm-photo: var(--qt-side-photo);

	--qt-pad-x: 40px;
	position: relative;
	margin: 3rem auto;
	border-radius: var(--box-border-radius-lg);
	overflow: hidden;
	background: var(--white);
	box-shadow: 0 10px 40px rgba(0, 42, 78, 0.16);
}

#quote-tool .quote-tool-notice,
.quote-tool-notice {
	color: var(--gray-dk);
}

#quote-tool .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* Icons (get_icon() output) inherit currentColor and size in em. */
#quote-tool .icon {
	display: inline-flex;
	flex: none;
}

/* Blue band ------------------------------------------------------------------
   The step header every page shares: eyebrow, heading, segmented progress,
   step labels. Headings/segments/labels are all server-rendered per step;
   quoteToolUpdateBanner() toggles which is visible. */

#quote-tool .quote-tool__band {
	padding: 45px var(--qt-pad-x);
	background: var(--blue-dk);
	color: var(--white);
	transition: background 0.3s ease;
}

#quote-tool .quote-tool__eyebrow {
	margin: 0;
	font-family: "Cachet", sans-serif;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: -0.4px;
	text-transform: uppercase;
	/* --blue-lt sits too close to the band's --blue-dk ground to read. */
	color: var(--white);
}

#quote-tool .quote-tool__heading {
	margin: 10px 0 0;
	font-size: 44px;
	line-height: 1;
	color: var(--white);
}

#quote-tool .quote-tool__progress {
	display: flex;
	gap: 24px;
	margin-top: 32px;
}

#quote-tool .quote-tool__progress span {
	flex: 1;
	height: 5px;
	border-radius: 9999px;
	background: rgba(255, 255, 255, 0.3);
	transition: background 0.3s ease;
}

#quote-tool .quote-tool__progress span.is-done {
	background: var(--blue-lt);
}

/* Current segment: solid light blue like a done segment, with a glowing spot
   that glides left-to-right along it on a loop - the bar "filling up". */
#quote-tool .quote-tool__progress span.is-current {
	position: relative;
	background: var(--blue-lt);
}

#quote-tool .quote-tool__progress span.is-current::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 0;
	width: 44px;
	height: 5px;
	margin-top: -2.5px;
	border-radius: 9999px;
	background: var(--white);
	box-shadow:
		0 0 4px 1px rgba(255, 255, 255, 0.38),
		0 0 10px 3px rgba(255, 255, 255, 0.16);
	opacity: 0;
	animation: qt-progress-glide 2.8s ease-in-out infinite;
}

/* The blob travels edge-to-edge but never past one, and is fully faded well
   before it stops; the 88-100% hold is a rest between sweeps. */
@keyframes qt-progress-glide {
	0% {
		left: 0;
		opacity: 0;
	}
	18% {
		opacity: 0.4;
	}
	68% {
		opacity: 0.4;
	}
	88% {
		left: calc(100% - 44px);
		opacity: 0;
	}
	100% {
		left: calc(100% - 44px);
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	#quote-tool .quote-tool__progress span.is-current::after {
		animation: none;
		content: none;
	}
}

#quote-tool .quote-tool__steplabels {
	display: flex;
	gap: 24px;
	margin-top: 12px;
}

#quote-tool .quote-tool__steplabels span {
	flex: 1;
	font-family: "Cachet", sans-serif;
	font-size: 25px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.75);
}

#quote-tool .quote-tool__steplabels span.is-current {
	color: var(--white);
}

/* Body --------------------------------------------------------------------- */

#quote-tool .quote-tool__body {
	padding: 40px var(--qt-pad-x);
}

#quote-tool .gform_wrapper {
	width: 100%;
}

/* Injected step copy (fields 990-992). */

#quote-tool .qt-copy__title {
	margin: 0;
	color: var(--blue-dk);
}

#quote-tool .qt-copy__text {
	margin: 12px 0 0;
	max-width: 660px;
	font-size: 17px;
	line-height: 1.5;
	text-wrap: pretty;
}

/* Gravity Forms chrome ------------------------------------------------------ */

#quote-tool input,
#quote-tool select,
#quote-tool textarea,
#quote-tool button {
	box-shadow: none;
}

#quote-tool .gform_required_legend,
#quote-tool [id^="gf_progressbar_wrapper_"] {
	display: none;
}

#quote-tool [id^="gform_confirmation_wrapper_"] {
	width: 100%;
}

#quote-tool .gform_page_footer.top_label {
	display: flex;
	justify-content: space-between;
	align-items: center;
	position: relative;
	margin: 35px 0 0;
	padding: 25px 0 0;
	border-top: 1px solid var(--gray-lt);
}

#quote-tool [id^="gform_ajax_spinner_"] {
	position: absolute;
	right: -20px;
	top: 50%;
	transform: translateY(-50%);
}

/* The prospect submits by clicking a rate card's ActiveNet link; quoteTool.js
   forwards that click to this button, so it must stay in the layout
   (visibility, never display). */
#quote-tool [id^="gform_submit_button_"] {
	visibility: hidden;
}

#quote-tool .gform-theme--framework .gform-field-label--type-inline {
	margin: 0;
}

/* Footer buttons: Next/submit wear the house purple button; Previous is a
   plain text link. */

#quote-tool .gform_page_footer .gform_next_button,
#quote-tool .gform_page_footer [id^="gform_submit_button_"] {
	padding: 16px 32px;
	background: var(--purple-md);
	color: var(--white);
	font-family: "Cachet", sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.4px;
	text-transform: uppercase;
	border: 0;
	border-radius: var(--btn-border-radius-sm);
	cursor: pointer;
	transition: all 0.3s ease;
}

#quote-tool .gform_page_footer .gform_next_button:hover,
#quote-tool .gform_page_footer .gform_next_button:focus {
	background: var(--blue-dk);
	color: var(--white);
}

#quote-tool .gform_page_footer .gform_previous_button {
	padding: 0;
	background: none;
	border: 0;
	color: var(--blue-dk);
	font-family: "Verdana", sans-serif;
	font-size: 16px;
	text-transform: none;
	letter-spacing: -0.5px;
	cursor: pointer;
	transition: all 0.3s ease;
}

#quote-tool .gform_page_footer .gform_previous_button:hover {
	color: var(--purple-dk);
	background: none;
}

/* A footer with no Previous (step 1) keeps its button on the right. */
#quote-tool .gform_page_footer .gform_next_button:only-child,
#quote-tool .gform_page_footer .gform_next_button:first-child:not(:only-child) {
	margin-left: auto;
}

/* Inputs: white fields on the white body (the site-wide #page GF rules assume
   a colored section behind the form). Hover/focus signal via border color. */

#quote-tool .gform_wrapper .gfield input[type="text"],
#quote-tool .gform_wrapper .gfield input[type="email"],
#quote-tool .gform_wrapper .gfield input[type="tel"],
#quote-tool .gform_wrapper .gfield select {
	width: 100%;
	box-sizing: border-box;
	height: 56px;
	padding: 0 18px;
	font-family: "Verdana", sans-serif;
	font-size: 16px;
	color: var(--black);
	background: var(--white);
	border: 1px solid var(--gray);
	border-radius: var(--box-border-radius-sm);
	transition: border-color 0.25s ease;
}

#quote-tool .gform_wrapper .gfield input[type="text"]:hover,
#quote-tool .gform_wrapper .gfield input[type="email"]:hover,
#quote-tool .gform_wrapper .gfield input[type="tel"]:hover,
#quote-tool .gform_wrapper .gfield select:hover {
	border-color: var(--blue-dk);
}

#quote-tool .gform_wrapper .gfield input:focus-visible,
#quote-tool .gform_wrapper .gfield select:focus-visible {
	outline: 2px solid var(--blue-lt);
	outline-offset: 1px;
}

#quote-tool .gform_wrapper .gfield_label {
	font-family: "Cachet", sans-serif;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: -0.2px;
	text-transform: uppercase;
	color: var(--black);
}

/* GF renders "(Required)" text (the form-level indicator setting is read from
   stored meta, so a render filter can't switch it) - collapse the text and draw
   the design's magenta asterisk instead. */
#quote-tool .gform_wrapper .gfield_required {
	color: var(--purple-md);
}

#quote-tool .gform_wrapper .gfield_required_text {
	font-size: 0;
}

#quote-tool .gform_wrapper .gfield_required_text::before {
	content: "*";
	font-size: 16px;
}

/* The marketing-consent checkbox row (scoped by field type so the location and
   rate radios stay untouched). Full-row: its old grid partner, the referral
   select, is removed at render. */

#quote-tool .gfield--type-checkbox {
	grid-column: 1 / -1;
}

#quote-tool .gfield--type-checkbox .gchoice {
	display: flex;
	gap: 12px;
	align-items: flex-start;
}

#quote-tool .gfield--type-checkbox input[type="checkbox"] {
	width: 20px;
	height: 20px;
	margin: 2px 0 0;
	accent-color: var(--blue-dk);
	flex: none;
}

#quote-tool .gfield--type-checkbox .gform-field-label {
	font-size: 14px;
	line-height: 22px;
	font-weight: 400;
	text-transform: none;
	font-family: "Verdana", sans-serif;
	text-wrap: pretty;
}

/* Step 1 - full-width field grid (client dropped the side photo 2026-09-21;
   the ::before that painted --qt-side-photo beside the fields is gone, so the
   fields run the width of the module like the finder and rates pages). --- */

/* The required-fields note sits left of the Next button on the intro footer. */
#quote-tool .gform_page:has(.qt-copy-intro) .gform_page_footer::before {
	content: '"*" indicates required fields';
	font-size: 14px;
	color: var(--gray-dk);
}

/* Step 2 - the finder page becomes a grid: copy and search span both columns,
   then the map sits beside the card rail. display:contents promotes the
   finder's inner wrappers to grid items without moving any DOM (the finder JS
   queries structure, not layout). */

#quote-tool .gform_page:has(.quote-tool-map-field) .gform_fields {
	display: grid;
	grid-template-columns: minmax(320px, 470px) 1fr;
	gap: 25px;
	align-items: start;
}

#quote-tool
	.gform_page:has(.quote-tool-map-field)
	.gform_fields
	> .gfield.quote-tool-step-copy,
#quote-tool .gform_page:has(.quote-tool-map-field) .loc-finder__searchbar,
#quote-tool .gform_page:has(.quote-tool-map-field) .loc-finder__msg {
	grid-column: 1 / -1;
}

#quote-tool .gfield.quote-tool-map-field,
#quote-tool .quote-tool-map-field .loc-finder,
#quote-tool .quote-tool-map-field .loc-finder__layout,
#quote-tool .quote-tool-map-field .loc-finder__map {
	display: contents;
}

#quote-tool .quote-tool-map-field .shortcode-map {
	grid-column: 1;
	width: 100%;
	height: 540px;
	margin: 0;
	border: 0;
	border-radius: var(--box-border-radius-lg);
}

#quote-tool .gform_page:has(.quote-tool-map-field) .gfield.location-cards {
	grid-column: 2;
	align-self: stretch;
}

#quote-tool .shortcode-map .marker {
	display: none;
}

/* Search row - the archive finder's bar, adapted to life inside the GF form.
   The bar chrome and flex layout live on .loc-finder__searchbar here, NOT on
   the inner .loc-finder__search <form> as the archive does: a <form> nested
   inside the GF <form> is silently dropped by the HTML parser on a full-page
   render, so that element only exists after an AJAX re-render. Styling the
   wrapper (always present) and collapsing the form with display:contents
   makes both DOM shapes lay out identically. Two more fights, overridden
   below: the generic gfield input sizing above must not capture the finder
   input (width:100% pushed the buttons onto their own row), and Gravity
   Forms' control theming must not repaint the buttons (it turned the
   outlined geolocate button blue-on-blue). */
#quote-tool .loc-finder__searchbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;

	padding: 16px 18px;

	background: var(--white);
	border: 1px solid var(--gray-lt);
	border-radius: var(--box-border-radius-sm);
	box-shadow: 0 3px 6px rgba(0, 0, 0, 0.08);
}

#quote-tool .loc-finder__search {
	display: contents;
}

/* Gravity Forms parents its hidden Akismet <p> into the searchbar once the
   nested form is dropped - keep it out of the flex row. */
#quote-tool .loc-finder__searchbar > .akismet-fields-container {
	display: none;
}

#quote-tool .gform_wrapper .gfield input[type="text"].loc-finder__search-input {
	width: auto;
	flex: 1;
	min-width: 220px;
	height: auto;
	padding: 14px 16px;
	font-family: "Verdana", sans-serif;
	font-size: 15px;
	letter-spacing: -0.3px;
	background: var(--white);
	border: 1px solid var(--gray);
	border-radius: var(--btn-border-radius-lg);
}

#quote-tool .loc-finder__searchbar .btn {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 13px 20px;
	border: 0;
	cursor: pointer;
	border-radius: var(--btn-border-radius-sm);
	transition: all 0.3s ease;
}

#quote-tool .loc-finder__searchbar .btn .btn-text {
	font-family: "Cachet", sans-serif;
	font-weight: 700;
	font-size: 15px;
	line-height: 1;
	letter-spacing: -0.4px;
	text-transform: uppercase;
}

#quote-tool .loc-finder__searchbar .btn .icon {
	font-size: 14px;
}

/* Both keep the .loc-finder__searchbar scope: the shared .btn rule above
   zeroes the border, and a bare #quote-tool .loc-finder__geo would lose to it
   on specificity - which strips the outline that separates the geolocate
   button from the white bar. */
#quote-tool .loc-finder__searchbar .loc-finder__submit {
	background: var(--blue-dk);
}

#quote-tool .loc-finder__searchbar .loc-finder__submit .btn-text,
#quote-tool .loc-finder__searchbar .loc-finder__submit .icon {
	color: var(--white);
}

#quote-tool .loc-finder__searchbar .loc-finder__submit:hover {
	background: var(--purple-md);
}

/* Geolocate - outlined so it reads against the white bar. */
#quote-tool .loc-finder__searchbar .loc-finder__geo {
	background: var(--white);
	border: 1px solid var(--blue-dk);
}

#quote-tool .loc-finder__searchbar .loc-finder__geo .btn-text,
#quote-tool .loc-finder__searchbar .loc-finder__geo .icon {
	color: var(--blue-dk);
}

#quote-tool .loc-finder__searchbar .loc-finder__geo:hover {
	background: var(--blue-dk);
}

#quote-tool .loc-finder__searchbar .loc-finder__geo:hover .btn-text,
#quote-tool .loc-finder__searchbar .loc-finder__geo:hover .icon {
	color: var(--white);
}

#quote-tool .loc-finder__clear {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 4px;
	border: none;
	background: transparent;
	cursor: pointer;
	font-family: "Cachet", sans-serif;
	text-transform: uppercase;
	font-weight: 700;
	font-size: 13px;
	letter-spacing: -0.2px;
	color: var(--purple-dk);
}

#quote-tool .loc-finder__clear .icon {
	font-size: 11px;
}

#quote-tool .loc-finder__clear:hover {
	text-decoration: underline;
}

#quote-tool .loc-finder__msg {
	margin: 0;
}

#quote-tool .loc-finder__msg[hidden] {
	display: none;
}

/* Step-2 rail - the location-cards radio field ------------------------------ */

#quote-tool .quote-tool-radio legend,
#quote-tool .location-cards legend {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
}

#quote-tool .location-cards .gfield_description,
#quote-tool .quote-tool-radio .gfield_description {
	display: none;
}

#quote-tool .location-cards {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 15px;
	height: 100%;
	box-sizing: border-box;
}

/* quoteToolRail.js moves this page's native Next control into the selected
   location's detail panel and relabels it "Select This Y". While it is parked
   in the footer (no panel open) keep it hidden, so the panel's button is the
   location step's only forward action. The footer goes with it when there is
   no Previous to show either (intro step off). */
#quote-tool .gform_page:has(.quote-tool-map-field) .gform_page_footer .gform_next_button {
	display: none;
}

#quote-tool .gform_page:has(.quote-tool-map-field) .gform_page_footer:not(:has(.gform_previous_button)) {
	display: none;
}

/* Every location shows at once - two columns where the rail is wide enough,
   one where it isn't, scrolling past the map's bottom edge. Nearest-first once
   a search has run (the sort re-appends in distance order, then snaps to top).
   The max() pins each track to at least half the rail, so auto-fill tops out
   at two columns no matter how wide the screen gets. */
#quote-tool .location-cards .gfield_radio {
	display: grid;
	grid-template-columns: repeat(
		auto-fill,
		minmax(max(280px, calc(50% - 8px)), 1fr)
	);
	padding-top: 20px;
	gap: 15px;
	max-height: 505px;
	overflow-y: auto;
}

/* position: relative keeps each hidden radio's containing block INSIDE the
   scrolling list. Without it the 1px inputs resolve against the field root
   (position: relative, outside the scroller) at their UNSCROLLED positions, so
   once the rail is scrolled, clicking a card label makes the browser's
   focus-into-view scroll chase a phantom input far below - the page jumps and
   the form leaves the viewport. */
#quote-tool .location-cards .gfield_radio .gchoice {
	position: relative;
	min-width: 0;
}

/* Bottom fade - "there's more below". quoteToolRail.js drops it (via the
   at-end class) once the list is scrolled to the end or nothing overflows. */
#quote-tool .location-cards::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 64px;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--white));
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.25s ease;
}

#quote-tool .location-cards--at-end::after,
#quote-tool .location-cards--detail::after {
	opacity: 0;
}

/* Detail state: the panel replaces the rail in place. */
#quote-tool .location-cards--detail .gfield_radio,
#quote-tool .location-cards--detail .qt-rail__count {
	display: none;
}

/* The card IS the control; the input is redundant to sighted users but must stay
   focusable, so it's clipped rather than display:none. */
#quote-tool .location-cards input[type="radio"] {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

#quote-tool .location-cards .gchoice label {
	display: block;
	width: 100%;
	cursor: pointer;
}

#quote-tool
	.location-cards
	input[type="radio"]:focus-visible
	+ label
	.loc-card {
	outline: 2px solid var(--purple-md);
	outline-offset: 2px;
}

/* In-form card overrides - the card itself is styled by
   archive-cards/archive-card-locations.css. */

#quote-tool .loc-card {
	cursor: pointer;
}

/* Initial-render selected state (a back-navigation re-render arrives with the
   radio already checked, before any change event has let the JS paint it). */
#quote-tool .location-cards .gchoice:has(input:checked) .loc-card {
	border-color: var(--purple-md);
	box-shadow: inset 0 0 0 2px var(--purple-md);
	background: var(--purple-tint);
}

#quote-tool
	.location-cards
	.gchoice:has(input:checked)
	.loc-card
	.loc-card__flag {
	display: block;
}

#quote-tool .loc-card__more {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 4px;
	font-family: "Cachet", sans-serif;
	font-weight: 700;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: -0.2px;
	color: var(--blue-dk);
	transition: color 0.25s ease;
}

#quote-tool .loc-card:hover .loc-card__more {
	color: var(--purple-dk);
}

#quote-tool .loc-card__more .icon {
	font-size: 12px;
}

/* Rail chrome (inserted by quoteToolRail.js) ------------------------------- */

#quote-tool .qt-rail__count {
	margin: 0;
	font-family: "Cachet", sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var(--gray-dk);
}

/* Location detail panel (cloned from each card's <template>) --------------- */

#quote-tool .qt-hub-detail {
	display: flex;
	flex-direction: column;
	height: 100%;
	box-sizing: border-box;
	padding: 24px;
	background: var(--white);
	border: 1px solid var(--gray-lt);
	border-radius: var(--box-border-radius-lg);
}

#quote-tool .qt-hub-detail__back {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	align-self: flex-start;
	padding: 0;
	border: 0;
	background: none;
	font-family: "Cachet", sans-serif;
	font-weight: 700;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: -0.2px;
	color: var(--blue-dk);
	cursor: pointer;
	transition: color 0.25s ease;
}

#quote-tool .qt-hub-detail__back:hover {
	color: var(--purple-dk);
}

/* Compact head: small thumbnail beside the name + address. */
#quote-tool .qt-hub-detail__head {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-top: 14px;
}

#quote-tool .qt-hub-detail__head-text {
	min-width: 0;
}

#quote-tool .qt-hub-detail__media {
	flex: 0 0 104px;
	width: 104px;
	height: 78px;
	border-radius: var(--box-border-radius-sm);
	overflow: hidden;
}

#quote-tool .qt-hub-detail__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

#quote-tool .qt-hub-detail__title {
	margin: 0;
	font-family: "Cachet", sans-serif;
	font-weight: 700;
	text-transform: uppercase;
	font-size: 24px;
	line-height: 1;
	letter-spacing: -0.7px;
	color: var(--black);
}

#quote-tool .qt-hub-detail__meta {
	margin: 6px 0 0;
	font-size: 13px;
	line-height: 19px;
	color: var(--gray-dk);
}

#quote-tool .qt-hub-detail__label {
	margin: 14px 0 0;
	font-family: "Cachet", sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var(--gray-dk);
}

#quote-tool .qt-hub-detail__hours {
	margin-top: 4px;
}

#quote-tool .qt-hub-detail__hours-row {
	display: flex;
	justify-content: space-between;
	gap: 15px;
	padding: 5px 0;
	border-bottom: 1px solid var(--gray-lt);
}

#quote-tool .qt-hub-detail__days {
	font-size: 13px;
	color: var(--gray-dk);
}

#quote-tool .qt-hub-detail__times {
	font-size: 13px;
	color: var(--black);
	text-align: right;
}

#quote-tool .qt-hub-detail__amenities {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0 15px;
	margin: 6px 0 0;
	padding: 0;
	list-style: none;
}

#quote-tool .qt-hub-detail__amenities li {
	font-size: 12px;
	line-height: 22px;
	letter-spacing: 0.4px;
	text-transform: uppercase;
}

#quote-tool .qt-hub-detail__phone {
	margin: 12px 0 0;
	font-size: 14px;
}

#quote-tool .qt-hub-detail__phone a {
	color: var(--blue-dk);
}

/* "Select This Y" - full-width purple button pinned to the panel bottom. */
#quote-tool .qt-hub-detail__cta {
	margin-top: auto;
	padding-top: 22px;
}

#quote-tool .qt-hub-detail__select {
	display: block;
	width: 100%;
	box-sizing: border-box;
	min-height: 0;
	margin: 0;
	padding: 16px 32px;
	background: var(--purple-md);
	color: var(--white);
	font-family: "Cachet", sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.4px;
	text-transform: uppercase;
	text-align: center;
	border: 0;
	border-radius: var(--btn-border-radius-sm);
	cursor: pointer;
	transition: all 0.3s ease;
}

#quote-tool .qt-hub-detail__select:hover {
	background: var(--blue-dk);
}

#quote-tool .qt-hub-detail__select.gform-has-spinner,
#quote-tool .qt-hub-detail__select.gform-has-spinner:hover,
#quote-tool .qt-hub-detail__select.gform-has-spinner:focus {
	color: transparent;
}

/* Step-2 motion -------------------------------------------------------------
   The card ⇄ panel swap (quoteToolRail.js) and the search re-sort
   (locationsFinder.js) run inside view transitions with transient
   view-transition-names; browsers without the API get the instant behavior. */

/* The map repaints on its own (tiles, camera flights) - snapshot it as its own
   stable group so it doesn't strobe inside the page crossfade. */
#quote-tool .shortcode-map {
	view-transition-name: qt-map;
}

::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
	animation-duration: 0.3s;
	animation-timing-function: ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
	::view-transition-group(*),
	::view-transition-old(*),
	::view-transition-new(*) {
		animation: none !important;
	}
}

/* Rates step - the whole module wears the blue gradient; the discounts panel
   sits ON it beside the cards, and only the footer stays quiet. -------------- */

#quote-tool.quote-tool--on-last .quote-tool-container {
	background: var(--blue-dk);
}

#quote-tool.quote-tool--on-last .quote-tool__band {
	background: transparent;
}

/* Full-width rates page: step copy above, then the card grid across the whole
   module (the side panel this layout once reserved a column for is gone -
   quote_tool_remove_sheet_field strips field 22 at render). */
#quote-tool
	.gform_page:has(.gfield.quote-tool-radio)
	.gfield.quote-tool-step-copy {
	margin-bottom: 28px;
}

/* The footer stays on the gradient - the band runs to the module's bottom
   corners, so Previous reads white. */
#quote-tool.quote-tool--on-last .gform_page_footer.top_label {
	margin-top: 30px;
	padding-top: 0;
	background: transparent;
	border-top: 0;
}

/* Previous wears the house .btn--white on the dark blue (white bg, purple
   text, purple fill on hover). */
#quote-tool.quote-tool--on-last .gform_page_footer .gform_previous_button {
	padding: 16px 32px;
	background: var(--white);
	color: var(--purple-dk);
	font-family: "Cachet", sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.4px;
	text-transform: uppercase;
	border-radius: var(--btn-border-radius-sm);
}

#quote-tool.quote-tool--on-last
	.gform_page_footer
	.gform_previous_button:hover {
	background: var(--purple-md);
	color: var(--white);
}

/* Step-3 body copy sits on the gradient - same anatomy as the other steps'
   qt-copy, opted to white. */
#quote-tool .qt-copy-rates .qt-copy__title,
#quote-tool .qt-copy-rates .qt-copy__text {
	color: var(--white);
}

/* In the on-gradient intro sentence the change-location link reads white. */
#quote-tool .qt-sheet__change-hub {
	/* GF themes bare buttons inline-flex and top-aligned, which drops this one
       below the sentence it sits in. */
	display: inline-block;
	vertical-align: baseline;
	padding: 0;
	background: none;
	border: 0;
	font: inherit;
	color: var(--blue-dk);
	cursor: pointer;
	transition: color 0.25s ease;
}

#quote-tool .qt-sheet__change-hub:hover {
	color: var(--purple-dk);
}

#quote-tool .qt-rates-intro .qt-sheet__change-hub {
	color: var(--white);
	text-decoration: underline;
}

#quote-tool .qt-rates-intro .qt-sheet__change-hub:hover {
	color: rgba(255, 255, 255, 0.8);
}

/* Rate cards ----------------------------------------------------------------
   Full-width grid of white cards on the gradient - the location_tabs Rates
   pane, verbatim: group headings in white, 3-up cards, title in brand blue on
   the left, price in brand purple on the right, lift on hover, the whole card
   clickable (the Select anchor stretches over it). */

#quote-tool .quote-tool-radio {
	margin-top: 0;
}

#quote-tool .quote-tool-radio .gfield_radio {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
	align-content: start;
}

/* Group caption rows ("Individual Plans", …) inserted by quoteTool.js. */
#quote-tool .quote-tool-group-caption {
	grid-column: 1 / -1;
	margin: 20px 0 0;
	font-family: "Cachet", sans-serif;
	font-weight: 700;
	font-size: 24px;
	line-height: 1;
	letter-spacing: -0.7px;
	text-transform: uppercase;
	color: var(--white);
}

#quote-tool .quote-tool-group-caption:first-child {
	margin-top: 0;
}

/* Equal-height cards per row: the gchoice→label→.quote-item chain stretches. */
#quote-tool .quote-tool-radio .gchoice {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

#quote-tool .quote-tool-radio .gchoice label {
	display: flex;
	flex-direction: column;
	/* form.css sets align-items: center + gap on every .gfield_radio label;
       in this column layout that shrink-wraps and centers the card, knocking
       it out of line with the heading and footer. Re-assert the stretch. */
	align-items: stretch;
	gap: 0;
	flex: 1;
	cursor: pointer;
}

/* !important + both selectors: the card is the control here, and this must
   out-rank Gravity Forms' own choice-input styling and any optimizer-reordered
   copy of it. */
#quote-tool .quote-tool-radio input[type="radio"],
#quote-tool .quote-tool-radio .gfield-choice-input {
	display: none !important;
}

/* form.css (the form content block) draws a fake radio widget on every
   .gform_wrapper .gfield_radio label::before/::after - hiding the input doesn't
   touch it. Inside the quote tool the card is the control, so kill it here. */
#quote-tool .quote-tool-radio .gchoice label::before,
#quote-tool .quote-tool-radio .gchoice label::after,
#quote-tool .location-cards .gchoice label::before,
#quote-tool .location-cards .gchoice label::after {
	content: none !important;
}

#quote-tool .quote-item {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex: 1;
	gap: 16px;
	padding: 22px 16px;
	background: var(--white);
	color: var(--black);
	border-radius: var(--box-border-radius-sm);
	transition:
		transform 0.2s ease,
		box-shadow 0.2s ease;
}

#quote-tool .quote-item:hover {
	transform: translateY(-4px) scale(1.02);
	box-shadow: 0 12px 26px rgba(35, 31, 32, 0.22);
}

/* Selected state - the loc-card--active recipe. */
#quote-tool .quote-tool-radio .gchoice:has(input:checked) .quote-item {
	box-shadow: inset 0 0 0 2px var(--purple-md);
	background: var(--purple-tint);
}

#quote-tool .quote-item__text {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}

#quote-tool .quote-item__title {
	margin: 0 0 4px;
	color: var(--blue-dk);
}

#quote-tool .quote-item__line {
	margin: 0;
	font-size: 14px;
	line-height: 1.35;
	color: var(--black);
}

#quote-tool .quote-item__price {
	flex: 0 0 auto;
	margin: 0; /* drop the .h4 bottom margin so the price sits vertically centered */
	color: var(--purple-dk);
	white-space: nowrap;
}

/* The Select anchor is the submit trigger (quoteTool.js binds it) - stretched
   invisibly over the whole card so the card behaves exactly like the
   location_tabs rate cards, which are one big link. */
#quote-tool .quote-item__select {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	overflow: hidden;
	text-indent: -9999px;
	background: none;
	border-radius: var(--box-border-radius-sm);
}

#quote-tool .quote-item__select:focus-visible {
	outline: 2px solid var(--blue-lt);
	outline-offset: 2px;
}

/* Shown by quoteTool.js if a location somehow renders with no plans at all (a
   rates fetch degrading, not a normal state). Created in JS, so it has no
   markup counterpart. Sits on the gradient. */
#quote-tool .quote-tool-empty {
	grid-column: 1 / -1;
	margin: 1rem 0 0;
	padding: 1.5rem;
	border: 1px dashed rgba(255, 255, 255, 0.6);
	border-radius: var(--box-border-radius-sm);
	text-align: center;
	color: var(--white);
	font-size: 17px;
}

/* Confirmation ----------------------------------------------------------------
   The purple thank-you panel (gform_confirmation filter). .submitted is added
   by quoteTool.js at click time and re-asserted by gform_confirmation_loaded. */

#quote-tool.submitted .quote-tool__band {
	display: none;
}

/* Belt and braces: gform_confirmation_loaded does not fire for a custom
   confirmation string, so the on-last gradient could linger behind the panel. */
#quote-tool.submitted .quote-tool-container {
	background: none;
}

#quote-tool.submitted .quote-tool__body {
	padding: 0;
}

#quote-tool .qt-confirm {
	display: flex;
	align-items: stretch;
	min-height: 520px;
	background: linear-gradient(
		156.86deg,
		var(--purple-md) 0,
		var(--purple-dk) 62%
	);
}

#quote-tool .qt-confirm__media {
	flex: 0 0 40%;
	background-image:
		linear-gradient(
			156.86deg,
			rgba(146, 39, 143, 0.55) 0,
			rgba(92, 46, 145, 0.55) 62%
		),
		var(--qt-confirm-photo);
	background-size: cover, cover;
	background-position: center, center;
}

#quote-tool .qt-confirm__content {
	flex: 1;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 45px 40px;
	color: var(--white);
}

#quote-tool .qt-confirm__eyebrow {
	margin: 0;
	font-family: "Cachet", sans-serif;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.9);
}

#quote-tool .qt-confirm__title {
	margin: 12px 0 0;
	font-size: 44px;
	line-height: 1;
	color: var(--white);
}

#quote-tool .qt-confirm__body {
	margin: 20px 0 0;
	max-width: 440px;
	font-size: 18px;
	line-height: 1.5;
	text-wrap: pretty;
}

#quote-tool .qt-confirm__summary {
	max-width: 440px;
	margin-top: 0;
}

/* Heading for the summary rows; carries the divider the list used to. */
#quote-tool .qt-confirm__summary-title {
	max-width: 440px;
	margin: 28px 0 0;
	padding: 18px 0 6px;
	font-family: "Cachet", sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 22px;
	border-top: 1px solid rgba(255, 255, 255, 0.35);
}

#quote-tool .qt-confirm__row {
	display: flex;
	justify-content: space-between;
	gap: 20px;
	padding: 12px 0;
	border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}

#quote-tool .qt-confirm__row:last-child {
	border-bottom: 0;
}

#quote-tool .qt-confirm__row dt {
	font-family: "Cachet", sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.9);
}

#quote-tool .qt-confirm__row dd {
	margin: 0;
	font-size: 16px;
	text-align: right;
}

/* Two paths side by side: Explore Programs, and (when a signup link resolved)
   Continue Membership Signup. One column on phones, below. */
#quote-tool .qt-confirm__actions {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px;
	max-width: 720px;
	margin-top: 32px;
}

#quote-tool .qt-confirm__path {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	padding: 22px;
	background: rgba(255, 255, 255, 0.08);
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: var(--box-border-radius-sm);
}

#quote-tool .qt-confirm__path-title {
	margin: 0;
	font-family: "Cachet", sans-serif;
	font-size: 19px;
	font-weight: 700;
	line-height: 22px;
}

#quote-tool .qt-confirm__path-copy {
	margin: 8px 0 18px;
	font-size: 14px;
	line-height: 20px;
	color: rgba(255, 255, 255, 0.9);
}

/* White CTA on the purple panel, pinned to the path's bottom edge so the two
   buttons line up whatever the copy length above them. */
#quote-tool .qt-confirm__cta {
	display: flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 100%;
	min-height: 58px;
	margin-top: auto;
	padding: 16px 18px;
	background: var(--white);
	color: var(--purple-dk);
	font-family: "Cachet", sans-serif;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -0.4px;
	text-transform: uppercase;
	text-align: center;
	text-decoration: none;
	border: 1px solid var(--white);
	border-radius: var(--btn-border-radius-sm);
	transition: all 0.3s ease;
}

#quote-tool .qt-confirm__cta:hover {
	background: var(--purple-md);
	color: var(--white);
}

/* Outlined variant for the secondary path. */
#quote-tool .qt-confirm__cta--secondary {
	background: transparent;
	color: var(--white);
}

#quote-tool .qt-confirm__cta--secondary:hover {
	background: var(--white);
	color: var(--purple-dk);
}

#quote-tool .qt-confirm__restart {
	align-self: flex-start;
	margin-top: 18px;
	color: var(--white);
	font-size: 14px;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	text-decoration-color: rgba(255, 255, 255, 0.55);
}

#quote-tool .qt-confirm__restart:hover {
	color: var(--white);
	text-decoration-color: currentColor;
}

#quote-tool .qt-confirm__note {
	margin: 28px 0 0;
	max-width: 440px;
	font-size: 14px;
	line-height: 21px;
	color: rgba(255, 255, 255, 0.9);
}

#quote-tool .qt-confirm__note a {
	color: var(--white);
	text-decoration: underline;
}

/* Responsive ---------------------------------------------------------------- */

@media (max-width: 992px) {
	#quote-tool {
		--qt-pad-x: 24px;
	}

	#quote-tool .quote-tool__band {
		padding-top: 30px;
		padding-bottom: 30px;
	}

	#quote-tool .quote-tool__heading {
		font-size: 34px;
	}

	#quote-tool .quote-tool__progress,
	#quote-tool .quote-tool__steplabels {
		gap: 12px;
	}

	#quote-tool .quote-tool__steplabels span {
		font-size: 12px;
	}

	/* Step 2: single column, map first (DOM order: copy, search, map, cards). */
	#quote-tool .gform_page:has(.quote-tool-map-field) .gform_fields {
		grid-template-columns: 1fr;
	}

	#quote-tool
		.gform_page:has(.quote-tool-map-field)
		.gform_fields
		> .gfield.quote-tool-step-copy,
	#quote-tool .gform_page:has(.quote-tool-map-field) .loc-finder__searchbar,
	#quote-tool .gform_page:has(.quote-tool-map-field) .loc-finder__msg,
	#quote-tool .quote-tool-map-field .shortcode-map,
	#quote-tool .gform_page:has(.quote-tool-map-field) .gfield.location-cards {
		grid-column: 1;
	}

	#quote-tool .quote-tool-map-field .shortcode-map {
		height: 320px;
	}

	/* Stacked layout: the list flows in full, so there's no scroll to hint at. */
	#quote-tool .location-cards .gfield_radio {
		max-height: none;
		grid-template-columns: repeat(
			auto-fill,
			minmax(max(265px, calc(50% - 8px)), 1fr)
		);
	}

	#quote-tool .location-cards::after {
		content: none;
	}

	#quote-tool .qt-hub-detail {
		height: auto;
	}

	#quote-tool .qt-hub-detail__head {
		flex-wrap: wrap;
	}
	#quote-tool .qt-hub-detail__media {
		height: 200px;
		flex: 0 0 100%;
	}

	/* Narrow panel: two amenity columns fit, three don't. */
	#quote-tool .qt-hub-detail__amenities {
		grid-template-columns: 1fr;
	}

	/* Step 3: two cards per row. */
	#quote-tool .quote-tool-radio .gfield_radio {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Confirmation stacks, photo on top. */
	#quote-tool .qt-confirm {
		flex-direction: column;
	}

	#quote-tool .qt-confirm__media {
		flex: none;
		min-height: 200px;
	}

	#quote-tool .qt-confirm__content {
		padding: 30px 24px;
	}

	#quote-tool .qt-confirm__title {
		font-size: 34px;
	}
}

@media (max-width: 768px) {
	/* Step 2: single column, map first (DOM order: copy, search, map, cards). */
	#quote-tool .qt-hub-detail__media {
		height: 100px;
	}

	/* Step 3: single column of rate cards. */
	#quote-tool .quote-tool__body {
		padding: 10px var(--qt-pad-x) 30px;
	}

	#quote-tool .quote-tool-radio .gfield_radio {
		grid-template-columns: 1fr;
	}

	#quote-tool .gform_page_footer.top_label {
		flex-direction: column-reverse;
		gap: 15px;
		align-items: stretch;
	}

	#quote-tool .gform_page_footer .gform_next_button,
	#quote-tool .gform_page_footer .gform_next_button:only-child {
		width: 100%;
		margin-left: 0;
	}

	#quote-tool .gform_page:has(.qt-copy-intro) .gform_page_footer::before {
		order: 1;
		text-align: center;
	}

	#quote-tool .qt-confirm__actions {
		grid-template-columns: 1fr;
	}
}
