/* Andersens single store page (v1.4) — built to the Figma individual-store
   frame: file UF4J4qKLGRiLqUhMab8bur ("Andersens Website (Shared)"), canvas
   340:2186 "Find a Store + Individual Store", desktop frame 348:2
   ("Desktop - 10", 1440x5159) and mobile frame 458:1709 (402x7004).
   Node ids in the comments below refer to that file.
   Deploy to child theme css/store-page.css.

   Conventions follow css/store-finder.css so the two redesign pages stay
   consistent: same palette vars, same full-bleed trick, same defensive
   !important overrides where OceanWP/Elementor fight us.
   Display face is Instrument Serif (Brand Guidelines V4), shared with the Homepage build
   (page 17442); body copy inherits the theme font. */

.asp {
	/* Figma palette (file UF4J4qKLGRiLqUhMab8bur, frame 348:2 "Desktop - 10").
	   Replaces the ANDERSENS-DESIGN-SYSTEM palette here the same way the 33
	   .acp pages were repalletted on 7 Sep 2026 — the Figma supersedes the doc. */
	--asp-cream: #f6f5ef;       /* Figma "Light"  — hero band, panels, cards */
	--asp-offwhite: #ffffff;    /* Figma page ground is plain white */
	--asp-panel: #f6f5ef;       /* Figma "Light"  — one panel tone, not two */
	--asp-green: #00833f;       /* Figma "Green"  */
	--asp-green-dark: #00622f;  /* hover only — no Figma equivalent */
	--asp-mint: #2bde81;        /* Figma "Bright" */
	--asp-gold: #ffa400;        /* Figma "Yellow" */
	--asp-ink: #000000;         /* Figma body copy is black, not #3a3a3a */
	--asp-muted: #5c5c56;
	--asp-line: #e6e2d6;
	--asp-ph: #dedcd4;          /* placeholder image grey */
	--asp-ph-ink: #8d8b81;
	--asp-serif: var(--and-display);

	/* Full-bleed band — escapes the boxed page container. --asp-vw is set by
	   store-page.js to the real viewport width (clientWidth, i.e. minus the
	   scrollbar) so the bleed never overshoots; 100vw is the pre-JS fallback. */
	width: var(--asp-vw, 100vw);
	margin-left: calc(50% - (var(--asp-vw, 100vw) / 2));
	background: var(--asp-offwhite);
	color: var(--asp-ink);
	/* Figma body: Inter 14 / 1.4. Dropping the base from 16 shrinks every
	   em-based width, so the two lede max-widths below are in px. */
	font-size: 14px;
	line-height: 1.4;
	text-align: left; /* theme centres text at mobile widths — design is left-aligned */
}

/* The 100vw breakout can add ~15px of horizontal scroll unless the page clips it. */
body:has(.asp) { overflow-x: clip; }

.asp-wrap {
	max-width: 1560px;
	margin: 0 auto;
	padding: 0 30px;
}

/* Shared type -------------------------------------------------------------- */

.asp .asp-eyebrow {
	color: var(--asp-gold);
	font-family: inherit;
	font-size: 10px;          /* Figma 348:227 — 10px / 700 / 2px tracking */
	font-weight: 700;
	letter-spacing: 0.2em;    /* self-corrects to exactly 2px at 10px */
	text-transform: uppercase;
	/* The artboard does NOT use one eyebrow gap. 14 is the common case
	   (showroom and testimonials 13.5, community 14.5); the hero, the why
	   statement and the map card each get their own below. Measured
	   frame-to-frame off frame 348:2. */
	margin: 0 0 14px;
	line-height: 0.95;
}
/* Hero: eyebrow frame ends 168.5, H1 starts 185. */
.asp .asp-hero .asp-eyebrow { margin-bottom: 16px; }
/* The centred 120px statement sits much further off its eyebrow: 949.5 -> 983. */
.asp .asp-why-head .asp-eyebrow { margin-bottom: 33px; }

.asp h1.asp-h1,
.asp h2.asp-h2 {
	font-family: var(--asp-serif);
	/* 400, not 600: only instrument-serif-400 exists, so 600 was faux bold.
	   Figma declares 400 throughout. */
	font-weight: 400;
	color: var(--asp-green);
	line-height: 0.95;
	letter-spacing: 0;
	margin: 0;
	text-transform: none;
}
/* Figma has FOUR display sizes on this page, not one. Every ramp below is
   based on the LAYOUT width (1425 on a 1440 screen once the scrollbar is out,
   402 on the mobile artboard), which is what vw actually resolves against —
   basing them on 1440 lands ~0.25px short of the cap.
     H1 / section H2   68 -> 52   (348:102, 348:103, 348:104 / 458:1816)
     "Why locals..."  120 -> 52   (348:124 / 458:1714) — the statement size
     Community H2      48 -> 36   (348:224 / 458:1993)
     Map card title    48 flat    (348:5 / 458:1997) */
.asp h1.asp-h1,
.asp h2.asp-h2 { font-size: clamp(52px, calc(45.7126px + 1.56403vw), 68px); }
.asp h1.asp-h1 { text-wrap: balance; }
/* The one 120px statement heading. */
.asp .asp-why-head .asp-h2 { font-size: clamp(52px, calc(25.2786px + 6.64712vw), 120px); }
/* Community sits in a 400px column, so it takes the smaller step. */
.asp .asp-community-panel .asp-h2 {
	font-size: clamp(36px, calc(31.2845px + 1.17302vw), 48px);
	line-height: 1.05;
}
.asp .asp-h1 em,
.asp .asp-h2 em { font-style: normal; color: var(--asp-mint); }
/* Some headings in the design start the accent phrase on its own line; others
   let it wrap naturally. This opts a heading into the former. */
.asp .asp-em-block em { display: block; }

/* Card / sub-head step: Figma 348:166 — Instrument Serif 32 / 1.4 / -0.96px.
   Flat at every width; the serif scale is 120/68/48/32 with no step below. */
.asp h3.asp-h3 {
	font-family: var(--asp-serif);
	font-weight: 400;
	font-size: 32px;
	line-height: 1.4;
	letter-spacing: -0.96px;
	color: var(--asp-green);
	margin: 0 0 2px;
	text-transform: none;
}

.asp .asp-lede { color: var(--asp-ink); margin: 0; }

/* Arrow link */
.asp .asp-arrow {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: var(--asp-green);
	/* Figma 348:167 — Inter 12 / 600, no rule under it, 18px glyph. */
	font-size: 12px;
	font-weight: 600;
	line-height: normal;
	text-decoration: none;
}
.asp .asp-arrow:hover { color: var(--asp-green-dark); }
.asp .asp-arrow svg { flex: none; }

/* Placeholder images ------------------------------------------------------- */
/* Grey boxes stand in for photography until real assets are supplied. */
.asp-ph {
	background: var(--asp-ph);
	border-radius: 15px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 6px;
	text-align: center;
	padding: 20px;
	color: var(--asp-ph-ink);
	overflow: hidden;
}
.asp-ph b {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	line-height: 1.5;
}
.asp-ph span { font-size: 11px; letter-spacing: 0.06em; opacity: 0.85; }

/* Real imagery ------------------------------------------------------------- */
/* Slot geometry lives on the slot rules above, shared with .asp-ph, so an
   image and a placeholder occupy exactly the same box. The wrapper owns the
   radius and the crop; the img fills it. */
/* Figma's radius vocabulary on this page is 15px, 10px and pill — nothing
   else. 15 is the card/photo default, 10 is an inner block (the mounted
   feature photo and the hours box). */
.asp-media {
	position: relative;
	overflow: hidden;
	border-radius: 15px;
	background: var(--asp-ph);
}
.asp-media img,
.asp .asp-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	margin: 0;
	border-radius: inherit;
}

/* 1. Hero ------------------------------------------------------------------ */

/* Figma: light band, content top at y159 with the header sitting over the top
   of it; copy column 430 (the card's width), 35px gutter, media 915x633. */
.asp-hero { background: var(--asp-cream); padding: 64px 0 60px; }
.asp-hero-grid {
	display: grid;
	grid-template-columns: minmax(0, 430px) minmax(0, 1fr);
	gap: 35px;
	align-items: start;
}
.asp-hero-copy { display: flex; flex-direction: column; height: 100%; }
/* `.asp .asp-hero-lede`, not `.asp-hero-lede`: the element carries BOTH
   classes (`class="asp-lede asp-hero-lede"`) and `.asp .asp-lede { margin: 0 }`
   above is two classes, so a single-class rule here is silently dropped and the
   lede lands hard on the H1's descenders. 17px is the artboard gap: H1 frame
   ends 380, lede frame starts 397 (which reads as 15px of ink-to-ink). */
.asp .asp-hero-lede { margin: 17px 0 0; max-width: 416px; }
.asp-hero-media { align-self: stretch; position: relative; }

/* Hero quote badge — Figma card 348:316 (162 wide, radius 15, Light ground)
   with text 397:52 (Instrument Serif 24 / 1.1 / -0.72px, first line mint).
   Optional: only a store whose copy supplies `hero_quote` renders one.
   It is a sibling of .asp-media rather than a child, because .asp-media
   clips (overflow:hidden) and the badge overhangs the photo when stacked. */
.asp .asp-hero-quote {
	position: absolute;
	right: 55px;
	bottom: 176px;
	z-index: 2;
	/* Figma draws this card 162 wide, sized to a 62-character placeholder
	   ("Hi I'm Jimmy..."). Cannon Hill's real line is 87 characters, which in
	   162px runs to seven lines and a 225px tower. Bron chose 10 Sep 2026 to
	   keep both owners and widen the box instead of cutting the words.
	   236 = 200px of measured text + the 18px side padding: the smallest width
	   that puts the greeting on one line and the whole line in four, which
	   brings the height back to ~146px, i.e. Figma's drawn 147.
	   Type, ground, radius and position are all still exactly as drawn. */
	width: 236px;
	box-sizing: border-box;
	margin: 0;
	padding: 20px 18px;
	background: var(--asp-cream);
	border-radius: 15px;
	font-family: var(--asp-serif);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.72px;
	color: var(--asp-green);
}
/* Figma breaks after the greeting and sets it in Bright, same em convention
   as the headings. */
.asp .asp-hero-quote em {
	display: block;
	font-style: normal;
	color: var(--asp-mint);
}
.asp-hero-media .asp-ph,
.asp-hero-media .asp-media { height: 100%; min-height: 633px; border-radius: 15px; }

/* Contact card (hero) */
/* Figma 348:228 — 430x273, radius 15, copy inset 19px, and no shadow on any
   card in the file. */
.asp-card {
	background: #fff;
	border-radius: 15px;
	/* Artboard: title 16 below the card top, hours box 16 above the bottom,
	   copy 19 in from the sides (348:228 vs 348:230 / 348:245). */
	padding: 16px 19px;
}
/* auto keeps the card bottom-aligned with the photograph, which is how the
   artboard ends both at y792. No padding override — the base 16 is correct. */
.asp-hero-contact { margin-top: auto; }
.asp .asp-card-title {
	font-family: var(--asp-serif);
	font-weight: 400;
	font-size: 32px;
	line-height: 1.4;
	letter-spacing: -0.96px;
	color: var(--asp-green);
	margin: 0 0 7px;
	text-transform: none;
}
.asp .asp-addr {
	margin: 0 0 18px;
	color: var(--asp-ink);
	font-size: 14px;
	line-height: 1.4;
}
/* Figma puts the hours box beside the link list, 157px wide, and gives the
   link column 240px (x49 to the hours box at x289) with the two effectively
   butted together. A 26px gap left only 183px for the label — exactly the
   width of "cannonhill@andersens.com.au", so Cannon Hill's email wrapped to a
   second line and shunted the "Leave a Review" row 10px down, breaking the
   35px row pitch. 10px keeps visible separation and still clears the longest
   email in the network. */
.asp-contact-split {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 157px);
	gap: 10px;
	align-items: start;
}

/* Icon rows */
.asp-links { list-style: none; margin: 0; padding: 0; }
/* Figma 348:232 — 15px icon at the card inset, label 26px further in, rows on
   a 35px pitch. */
.asp-links li { display: flex; align-items: flex-start; gap: 11px; margin: 0 0 11px; min-width: 0; }
.asp-links li:last-child { margin-bottom: 0; }
.asp-links svg { flex: none; width: 15px; height: 15px; color: var(--asp-green); margin-top: 4px; }
.asp-links a {
	color: var(--asp-green);
	font-size: 12px;
	font-weight: 600;
	text-decoration: underline;
	/* break-word, not anywhere: long store emails should wrap at the @ or a
	   dot rather than mid-word. min-width:0 is what actually lets a flex item
	   shrink below its longest word — without it the address overflows the
	   card instead of wrapping. */
	overflow-wrap: break-word;
	min-width: 0;
	/* 24px minimum tap target (WCAG 2.2 2.5.8); these are a link list, not
	   inline prose links, so the exemption does not apply. */
	display: inline-block;
	/* Figma leading is normal; the padding is what buys the 24px tap target
	   without changing the type. */
	line-height: normal;
	padding: 4px 0;
	min-height: 24px;
	box-sizing: border-box;
}
.asp-links a:hover { color: var(--asp-green-dark); }

/* Hours block */
/* Figma 348:245 — Light ground, radius 10, label green (not gold, unlike
   every other eyebrow on the page). */
.asp-hours { background: var(--asp-cream); border-radius: 10px; padding: 11px 13px 13px; }
.asp-hours-plain { background: none; border-radius: 0; padding: 0; }
.asp-hours-label {
	color: var(--asp-green);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	line-height: 0.95;
	margin: 0 0 8px;
}
.asp-hours table { width: 100%; border: 0; margin: 0 0 8px; font-size: 12px; }
.asp-hours table,
.asp-hours td { background: none !important; border: 0 !important; padding: 0 !important; }
/* nowrap on both cells: the design keeps each day on one line, and the column
   is narrow enough that "9am-5pm" would otherwise break across two.
   The explicit colour matters — this table also renders inside the white card
   on the map band, where it would otherwise inherit that card's white text. */
.asp-hours td { white-space: nowrap; line-height: 1.4; color: var(--asp-ink); }
.asp-hours tr td:first-child { padding-right: 10px !important; }
.asp-hours-note { margin: 0; font-size: 12px; color: var(--asp-ink); line-height: 1.4; }

/* 2. What sets us apart ---------------------------------------------------- */

/* Figma stacks three grounds here: solid Light under the hero, Light at 50%
   under this band, and a 179px gradient joining each end to the white page.
   One gradient reproduces all three (348:12, 348:20, 348:96). */
.asp-why {
	background: linear-gradient(
		to bottom,
		var(--asp-cream) 0,
		rgba(246, 245, 239, 0.5) 179px,
		rgba(246, 245, 239, 0.5) calc(100% - 179px),
		#fff 100%
	);
	padding: 88px 0 100px;
}
/* em here would resolve against the 16px container, not the display size —
   use a px cap so the heading keeps the design's two-line break. */
/* Figma caps this block at 926px, but that was measured against "Andersens
   Helensvale." — at 120px "Andersens Cannon Hill." is 953px and wrapped to a
   third line, losing the design's green-line / mint-line break. The cap is
   widened to hold the longest store name on one line; a short name is centred
   and renders identically to the artboard either way. */
.asp-why-head { text-align: center; max-width: 1180px; margin: 0 auto 73px; }
.asp .asp-why-head .asp-eyebrow,
.asp .asp-why-head .asp-h2 { text-align: center !important; }

.asp-why-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 15px;
	align-items: start;
}
/* Figma steps each card exactly 100px further down (tops 1284/1384/1483). */
.asp-why-grid > *:nth-child(2) { margin-top: 100px; }
.asp-why-grid > *:nth-child(3) { margin-top: 200px; }

/* Figma 348:171 — 450x447, radius 15, white at 90%, and a 10px mount around a
   430x240 photo whose own radius is 10. The mount is deliberate: see the
   homepage cards, which are the reference implementation. */
.asp-feature {
	background: rgba(255, 255, 255, 0.9);
	border-radius: 15px;
	padding: 10px;
}
.asp-feature .asp-ph,
.asp-feature .asp-media { height: 240px; border-radius: 10px; }
/* 15px here + the card's 10px mount = the 25px copy inset Figma draws. */
.asp-feature-body { padding: 17px 15px 22px; }
.asp-feature-body p { margin: 0 0 17px; font-size: 14px; line-height: 1.4; }

/* 3. Showroom carousel ----------------------------------------------------- */

.asp-showroom { background: var(--asp-offwhite); padding: 106px 0 90px; }
.asp-showroom .asp-lede { margin-top: 14px; max-width: 486px; font-size: 14px; line-height: 1.4; }
/* 24, not 28: .asp-rail adds 4px of top padding, and the artboard gap from the
   lede to the tile is 28. Same -4 applies to .asp-testi-head below. */
.asp-carousel-head { margin: 0 0 24px; }

/* Rails bleed to the right edge like the design; scroll-snap does the paging. */
.asp-rail {
	display: flex;
	gap: 15px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	padding: 4px 30px 4px 0;
	margin: 0;
	list-style: none;
}
.asp-rail::-webkit-scrollbar { display: none; }
.asp-rail > li { scroll-snap-align: start; flex: 0 0 auto; }

/* Figma 348:196 — tile 334x300, radius 15. */
.asp-room { width: 334px; position: relative; }
.asp-room .asp-ph,
.asp-room .asp-media { height: 300px; border-radius: 15px; }
/* The notch. Figma masks the photo with a rounded rect that has a ~115x50
   bite out of the top-right corner and a concave fillet on the bite's inner
   corner. An opaque label box in that corner, carrying the band ground and a
   convex bottom-left radius, renders identically and costs no mask. Measured
   off the artboard: bite 115 wide x 50 tall, fillet 15. */
.asp-room-label {
	position: absolute;
	top: 0;
	right: 0;
	min-width: 115px;
	height: 50px;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--asp-offwhite);
	border-bottom-left-radius: 15px;
	border-top-right-radius: 15px;
	padding: 0 8px 0 14px;
	font-family: var(--asp-serif);
	font-weight: 400;
	font-size: 36px;
	line-height: 1;
	color: var(--asp-green);
}

/* Carousel controls */
.asp-carousel-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	margin: 24px 0 0;
}
.asp-dots { display: flex; align-items: center; gap: 6px; }
/* Figma 348:—  the progress marks are 3px bars with a 20px radius: 60px wide
   and Bright when current, 24px and Green otherwise. The bar is 3px but the
   tap target must be 24px (WCAG 2.2 2.5.8), so the button carries the height
   and the bar is drawn as a pseudo-element. */
.asp-dot {
	width: 24px;
	height: 24px;
	border: 0;
	padding: 0;
	background: none;
	cursor: pointer;
	display: flex;
	align-items: center;
	transition: width 0.2s ease;
}
.asp-dot::before {
	content: '';
	display: block;
	width: 100%;
	height: 3px;
	border-radius: 20px;
	background: var(--asp-green);
	opacity: 1;
	transition: background 0.2s ease, opacity 0.2s ease;
}
.asp-dot[aria-current="true"] { width: 60px; }
.asp-dot[aria-current="true"]::before { background: var(--asp-mint); opacity: 1; }

.asp-navs { display: flex; gap: 12px; }
.asp-nav {
	/* Figma 348:219 — 64x30 pill, 1px green ring, white ground. */
	width: 64px;
	height: 30px;
	border: 1px solid var(--asp-green);
	border-radius: 999px;
	background: #fff;
	color: var(--asp-green);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	padding: 0;
}
.asp-nav:hover { background: var(--asp-green); color: #fff; }
.asp-nav[disabled] { opacity: 0.35; cursor: default; }
.asp-nav[disabled]:hover { background: #fff; color: var(--asp-green); }

/* 4. Testimonials ---------------------------------------------------------- */

/* Figma keeps this band on the plain white page ground, with no rounded top. */
.asp-testi {
	background: #fff;
	padding: 78px 0 80px;
}
.asp-testi-head { text-align: center; margin: 0 auto 31px; }  /* 35 - the rail's 4px top padding */
.asp .asp-testi-head .asp-eyebrow,
.asp .asp-testi-head .asp-h2 { text-align: center !important; }

/* Figma 348:190 — 450x286, Light ground, radius 15, 38px inset.
   margin: 0 is load-bearing: this is a <blockquote> and OceanWP gives every
   blockquote `margin: 20px 40px`, which pushed the whole rail 40px off the
   page gutter and dropped it 20px. */
.asp-quote {
	margin: 0;
	width: 450px;
	background: var(--asp-panel);
	border-radius: 15px;
	padding: 53px 38px 39px;
	/* Uniform cards with the attribution on the baseline. Figma draws all
	   three the same height; real reviews are not the same length, so without
	   this the row had ragged bottoms (494/533/494/456) and the names floated
	   at four different heights. The rail's li stretches but a blockquote does
	   not fill it, so the li has to become a flex parent. */
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
}
.asp-testi .asp-rail > li { display: flex; }
/* The slack goes on .asp-quote-text's margin-bottom, set in its own block
   below — putting it here instead loses to that block, which declares the
   shorthand `margin`. */
.asp-stars { display: flex; gap: 12px; margin: 0 0 23px; color: var(--asp-green); }
.asp-stars svg { width: 28px; height: 28px; }
.asp .asp-quote-text {
	font-family: var(--asp-serif);
	font-weight: 400;
	/* 24px, NOT the 32 Figma draws on 348:251 — a deliberate, recorded step
	   down. Figma's card is 450x286 and its chrome (53 top inset, 28px stars,
	   23 gap, 20 gap, the attribution, 39 bottom inset) plus the "Google
	   review" source line this build carries and the artboard does not comes
	   to ~226px. That leaves ~60px for the quote inside a 286px card, i.e.
	   about a line and a half at 32px — so 286 cannot hold even Figma's OWN
	   97-character placeholder here, let alone Cannon Hill's real reviews at
	   209-260 characters.
	   24px is not invented: it is the other serif step Figma specifies on this
	   page, the hero quote badge 397:52 (24 / 1.1 / -0.72px). It takes the
	   tallest card from 533 to 398 and keeps every review verbatim, which is
	   the constraint that matters — see the note against editing review
	   wording in the Coorparoo filter. Trimming the quotes is the only way to
	   reach 286 and that is Bron's call, not a CSS one. */
	font-size: 24px;
	line-height: 1.2;
	letter-spacing: -0.72px;
	color: var(--asp-green);
	/* auto, not a fixed gap: this is the flex column's slack, which pushes the
	   name and source group down onto the card's bottom padding so every card
	   in the row attributes on the same line. The minimum gap moved to
	   .asp-quote-name's margin-top. */
	margin: 0 0 auto;
}
.asp .asp-quote-source {
	margin: 5px 0 0;
	font-size: 10px;
	color: var(--asp-muted);
	letter-spacing: 0.2em;
	line-height: 0.95;
	text-transform: uppercase;
}
.asp .asp-quote-name {
	/* 20px top is the minimum gap to the quote; the quote's own auto bottom
	   margin is what actually pushes this group to the foot of the card. */
	margin: 20px 0 0;
	color: var(--asp-gold);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.2em;
	line-height: 0.95;
	text-transform: uppercase;
}

/* 5. Community ------------------------------------------------------------- */

.asp-community { background: #fff; padding: 69px 0 90px; }
/* Figma 348:8 / 348:111 — the Light panel is 1239 wide starting 142px in, and
   the 915x583 photo sits ON it, overhanging its left edge to the page gutter.
   So the panel is a background layer, not the copy column's own box. */
.asp-community-grid {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 915px) minmax(0, 1fr);
	gap: 65px;
	align-items: stretch;
}
.asp-community-grid::before {
	content: '';
	position: absolute;
	left: 142px;
	right: 0;
	top: 0;
	bottom: 0;
	background: var(--asp-panel);
	border-radius: 15px;
	z-index: 0;
}
.asp-community-grid > * { position: relative; z-index: 1; }
.asp-community-grid .asp-ph,
.asp-community-grid .asp-media { height: 100%; min-height: 583px; border-radius: 15px; }
.asp-community-panel {
	background: none;
	border-radius: 0;
	padding: 0 43px 0 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
}
/* Figma 348:225 — this band's body copy is the 1.5 leading, not 1.4. */
.asp-community-panel .asp-lede { margin-top: 14px; font-size: 14px; line-height: 1.5; }

/* 6. Contact + map --------------------------------------------------------- */
/* Basemap is a single pre-rendered JPEG stitched from OpenStreetMap/CARTO
   raster tiles — same approach as the store locator card thumbnails, so the
   page makes no runtime map/geocoding requests and needs no API key. */

.asp-map-section { position: relative; background: var(--asp-panel); }
.asp-map {
	background-color: var(--asp-panel);
	background-repeat: no-repeat;
	background-position: center;
	background-size: cover;
	aspect-ratio: 2048 / 1024;
	/* Figma's map band is 919px tall (y3841-4760) and the card sits 33px down
	   from its top edge, not centred. cover crops, so the basemap never
	   distorts. */
	min-height: 919px;
	width: 100%;
}
.asp-map-overlay {
	position: absolute;
	inset: 0;
	pointer-events: none;
}
.asp-map-overlay .asp-wrap {
	height: 100%;
	display: flex;
	align-items: flex-start;
	padding-top: 33px;
}
.asp-map-card {
	pointer-events: auto;
	width: 100%;
	max-width: 450px;
	background: var(--asp-green);
	border-radius: 15px;
	/* 38px sides matches the eyebrow/title/body inset; the two inner cards
	   break 8px back out of it to land on Figma's 30px inset and 390px width. */
	padding: 28px 38px 36px;
	color: #fff;
}
.asp .asp-map-eyebrow {
	color: #fff;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.2em;
	line-height: 0.95;
	text-transform: uppercase;
	margin: 0 0 11px;
}
.asp .asp-map-title {
	font-family: var(--asp-serif);
	font-weight: 400;
	/* Figma 348:5 — 48px flat, desktop and mobile alike. */
	font-size: 48px;
	line-height: 1.05;
	letter-spacing: 0;
	color: #fff;
	margin: 0 0 6px;   /* artboard: title frame ends 3973.4, text starts 3979 */
	text-transform: none;
}
.asp .asp-map-text { color: #fff; margin: 0 0 26px; font-size: 14px; line-height: 1.5; }
/* Figma 348:256 / 348:271 — 390 wide at a 30px inset: address card radius 15,
   hours card radius 10. */
.asp-map-card .asp-card { padding: 18px 19px 26px; margin: 0 -8px 19px; }
.asp-map-card .asp-card:last-child { margin-bottom: -8px; }
.asp-map-card .asp-card:has(.asp-hours-plain) { padding: 19px 20px 14px; border-radius: 10px; }
/* Two columns, days then times, as Figma sets them (348:273 / 348:274). */
.asp-map-card .asp-hours table { margin: 0 0 11px; }
.asp-map-card .asp-hours td { line-height: 1.8; }
.asp-map-card .asp-hours tr td:first-child { width: 83px; padding-right: 0 !important; }
/* OpenStreetMap/CARTO attribution is a licence obligation, so it stays — but
   Figma runs the map straight into the footer with no strip under it, so it
   sits over the bottom-right of the basemap rather than adding a band. */
.asp-map-attrib {
	position: absolute;
	right: 8px;
	bottom: 8px;
	z-index: 2;
	margin: 0;
	padding: 3px 8px;
	border-radius: 10px;
	background: rgba(255, 255, 255, 0.75);
	font-size: 10px;
	line-height: 1.4;
	color: #5c5c56;
	text-align: right;
}

/* Optional extra module inside the community panel. Only renders when a store
   supplies the copy, so the default page is unchanged. */
.asp-community-extra {
	margin: 26px 0 0;
	padding: 20px 22px;
	background: #fff;
	border-radius: 15px;
}
.asp .asp-community-extra-title {
	font-family: var(--asp-serif);
	font-weight: 400;
	font-size: 32px;
	line-height: 1.4;
	letter-spacing: -0.96px;
	color: var(--asp-green);
	margin: 0 0 4px;
	text-transform: none;
}
.asp .asp-community-extra-text { margin: 0; font-size: 14px; line-height: 1.4; color: var(--asp-ink); }

/* Theme/Elementor centre headings and paragraphs at narrow widths, and
   OceanWP restyles tables — pin the elements the design needs left-aligned. */
.asp .asp-eyebrow,
.asp .asp-h1,
.asp .asp-h2,
.asp .asp-h3,
.asp .asp-lede,
.asp .asp-card-title,
.asp .asp-addr,
.asp .asp-hours-label,
.asp .asp-hours-note,
.asp .asp-quote-text,
.asp .asp-quote-name,
.asp .asp-quote-source,
.asp .asp-community-extra-title,
.asp .asp-community-extra-text,
.asp .asp-map-eyebrow,
.asp .asp-map-title,
.asp .asp-map-text,
.asp .asp-hero-quote,
.asp .asp-feature-body p { text-align: left !important; }

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

@media (max-width: 1200px) {
	.asp-hero-grid { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: 36px; }
	/* Too narrow to keep hours beside the contact links. */
	.asp-contact-split { grid-template-columns: 1fr; }
	.asp-hours { max-width: 300px; }
	.asp-why-grid > *:nth-child(2) { margin-top: 70px; }
	.asp-why-grid > *:nth-child(3) { margin-top: 140px; }
	/* The 915px photo no longer fits, so the panel goes back to being the
	   copy column's own box and the background layer is dropped. */
	.asp-community-grid { grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr); gap: 26px; }
	.asp-community-grid::before { display: none; }
	.asp-community-panel {
		background: var(--asp-panel);
		border-radius: 15px;
		padding: 44px 36px;
	}
}

@media (max-width: 960px) {
	.asp-wrap { padding: 0 20px; }
	.asp-hero { padding: 36px 0 60px; }
	/* The badge straddles the photo's bottom edge here, as drawn. */
	.asp .asp-hero-quote { right: 24px; bottom: -24px; }
	/* The gap is set on `.asp-wrap.asp-hero-grid` in the hero-responsive block
	   at the foot of this file, which is the only place that wins. */
	.asp-hero-grid { grid-template-columns: 1fr; }
	/* NO `order: -1`. The mobile artboard 458:1709 runs eyebrow, H1, lede,
	   contact card, THEN the photograph, so plain DOM order is the design.
	   The 1.3.x rule that hoisted the image above the copy predates having a
	   mobile frame to check against. */
	.asp-hero-media .asp-ph,
	.asp-hero-media .asp-media { min-height: 304px; }
	/* Stacked, `margin-top: auto` collapses to nothing, so the card sat flush
	   against the lede. The artboard has 17px (lede frame ends 362, card
	   starts 379) and the same 16px title inset as desktop. */
	.asp-hero-contact { margin-top: 17px; }
	.asp-why { padding: 60px 0 70px; }
	.asp-why-grid { grid-template-columns: 1fr; gap: 20px; }
	.asp-why-grid > *:nth-child(2),
	.asp-why-grid > *:nth-child(3) { margin-top: 0; }
	.asp-community { padding-top: 40px; }
	.asp-community-grid { grid-template-columns: 1fr; }
	.asp-community-grid .asp-ph,
	.asp-community-grid .asp-media { min-height: 300px; }
	.asp-community-panel { padding: 32px 24px; }
	.asp-rail { padding-right: 20px; }
	.asp-showroom { padding-top: 60px; }

	/* Stack the map above the card — a 2:1 map is too short to hold the card. */
	.asp-map { aspect-ratio: auto; height: 320px; min-height: 0; }
	.asp-map-overlay { position: static; inset: auto; }
	.asp-map-overlay .asp-wrap { display: block; padding: 0 20px; }
	.asp-map-card { max-width: none; margin: -60px 0 0; position: relative; z-index: 2; }
	.asp-map-attrib { position: static; right: auto; bottom: auto; background: none; text-align: left; padding: 10px 20px 0; }
	.asp-map-section { padding-bottom: 24px; }
}

/* Mobile is the 402px artboard 458:1709. Everything here is measured off it. */
@media (max-width: 640px) {
	.asp-contact-split { grid-template-columns: 1fr; gap: 18px; }
	/* Figma runs the hours box to the card's full inner width (338 of 361). */
	.asp-hours { max-width: none; }

	/* Tiles keep the desktop 1.11 aspect: 282x254 with a 10px gap. */
	.asp-rail { gap: 10px; }
	.asp-room { width: 282px; }
	.asp-room .asp-ph,
	.asp-room .asp-media { height: 254px; }
	.asp-room-label { min-width: 89px; height: 38px; font-size: 28px; padding: 0 6px 0 11px; }

	/* The quote card is the full content width, so the neighbours peek. Type
	   stays on the 32px step — Figma does not step it down on mobile. */
	.asp-quote { width: calc(100vw - 40px); max-width: 362px; padding: 44px 38px 32px; }
	.asp-stars { gap: 10px; margin-bottom: 20px; }
	.asp-testi { padding: 56px 0 60px; }

	/* Figma's mobile map card keeps the 48px title, and the two inner cards
	   sit on the card's own 25px inset rather than breaking out of it. */
	.asp-map-card { padding: 24px 25px 25px; }
	.asp-map-card .asp-card { margin: 0 0 16px; }
	.asp-map-card .asp-card:last-child { margin-bottom: 0; }
	.asp-map-card .asp-card:has(.asp-hours-plain) { padding: 16px 17px 12px; }

	/* Bars left, arrows right, still on one row (458:1933 and the pair above
	   it sit on the same baseline). The bars halve to 2px, 24 current / 10 not. */
	.asp-carousel-foot { flex-direction: row; align-items: center; gap: 16px; }
	.asp-dots { gap: 3px; }
	.asp-dot { width: 10px; }
	.asp-dot::before { height: 2px; }
	.asp-dot[aria-current="true"] { width: 24px; }

	/* Both centred desktop headings are left-aligned on the mobile artboard
	   (458:1714 and 458:1931 both sit on the 20px gutter). */
	.asp .asp-why-head .asp-eyebrow,
	.asp .asp-why-head .asp-h2,
	.asp .asp-testi-head .asp-eyebrow,
	.asp .asp-testi-head .asp-h2 { text-align: left !important; }
	.asp-why-head,
	.asp-testi-head { text-align: left; max-width: none; }
}

/* Reduced motion ---------------------------------------------------------- */
/* The rails animate two things: the smooth scroll and the active progress
   dash widening. Both are decoration, so drop them rather than easing them. */
@media (prefers-reduced-motion: reduce) {
	.asp-rail { scroll-behavior: auto; }
	.asp-dot,
	.asp-dot::before,
	.asp-nav,
	.asp-arrow,
	.asp-links a { transition: none; }
}

/* ===== ASP-HERO-RESPONSIVE BLOCK: START ===== */
/* The store hero between 960px and 1200px, reported by Bron on Cannon Hill:
 * "not responsive" and one of the two owners cut off.
 *
 * ONE CAUSE, TWO SYMPTOMS. `.asp-hero-media` is `align-self: stretch` and its
 * media box is `height: 100%; min-height: 620px`, so the image box takes whatever
 * height the COPY column ends up. At 1200px the grid narrows the copy column to
 * 360px, the text wraps much taller, and the media box was dragged to match:
 * measured at 1009px it rendered **553 wide by 743 tall**, i.e. PORTRAIT, holding
 * a 3:2 landscape photograph. `object-fit: cover` then threw away **258px off
 * each side** and took both owners' faces with it.
 *
 * So the cropping was not a framing problem, it was a layout problem.
 *
 * 1. Stack the hero from 1200px down instead of 960px. The stacked layout already
 *    exists and is already designed (media first, min-height 300px); this just
 *    applies it over the band where the two-column version was too cramped to
 *    work. A 360px copy column at a 1009px viewport was the "not responsive"
 *    complaint in its own right. After: media 949x620, ZERO crop, copy full width.
 *
 *    `!important` and the doubled `.asp-wrap.asp-hero-grid` are both needed: the
 *    existing 1200px rule is written at two classes, so a single-class override is
 *    silently ignored. A first attempt without them moved the image but left the
 *    columns alone, which made it worse.
 *
 * 2. Cap the media height so copy length can never stretch it into a portrait box
 *    again, on any store, at any width. It was already `min-height: 620px`, so
 *    pinning the max to the same number makes the desktop hero a predictable
 *    height rather than however long the copy happens to run.
 *
 *    Retuned to 633 for the Figma build (mask 348:107 is 915x633). It has to
 *    match the min-height above, not the old 620: where the two disagree the
 *    min wins, which left the pair contradictory and the cap dead. */
.asp-hero-media .asp-ph,
.asp-hero-media .asp-media { max-height: 633px; }

@media (max-width: 1200px) {
	.asp-wrap.asp-hero-grid {
		grid-template-columns: minmax(0, 1fr) !important;
		/* 14px, measured off the mobile artboard (contact card bottom y772 to
		   photo top y786). This is the rule that decides it — the doubled
		   class above beats the single-class `.asp-hero-grid` in the 960
		   block, so setting the gap there alone does nothing. */
		gap: 14px;
	}
	/* Media stays in DOM order, i.e. below the copy — see the 960 block. */
	/* 304 is the mobile artboard's hero mask (458:—, 361x304). */
	.asp-hero-media .asp-ph,
	.asp-hero-media .asp-media { min-height: 304px; max-height: 520px; }
}

/* 3. Cannon Hill's own framing. Both owners stand in the left two thirds and the
 *    right third is signage, so a centred crop takes a slice off the nearer man
 *    before it takes anything worth keeping off the right. At the desktop box
 *    (831x620) a centred crop cut 55px a side and his face begins at about 51px;
 *    at 30% it cuts 33px and clears him.
 *
 *    15%, not 30%, because the crop gets much harder as the box narrows. At the
 *    desktop box it removes 109px of the 1024 variant; at 375px the box is 335x300
 *    and removes 96px of a 375 variant, a full 26% of the width. 30% cleared him on
 *    desktop but still clipped him on a phone. 15% is the first value that clears
 *    at every width, and costs only more of the signage on the right.
 *
 *    Targeted at the one photograph by filename rather than at every store hero:
 *    this is a framing decision about this picture, and a left bias would be wrong
 *    for a storefront shot composed centrally. Other stores keep centre. */
.asp-hero-media img[src*='cannon-hill-owners-storefront'] { object-position: 15% 50%; }
/* ===== ASP-HERO-RESPONSIVE BLOCK: END ===== */
