/* Hass - RESPONSIVE: every viewport media query on the site, in the same
   relative order as the source files so the cascade is unchanged.
   Generated by merging the theme's per-section stylesheets.
   Load order is base.css -> main.css -> responsive.css; responsive.css
   is last so its media queries win over everything they override.
   ========================================================================== */


/* ========== base.css (header, footer, shared components) ========== */


/* Single column on small screens, and the mobile design leads with the
   newsletter: Subscribe -> Quick links -> About Hass -> Contact -> Socials.
   Reordering here rather than in the markup keeps the desktop DOM order (and
   so the desktop tab order) exactly as it was. */
@media (max-width: 900px) {
	.footer-newsletter {
		order: -1;
		flex-basis: 100%;
	}
}

@media (max-width: 900px) {
	.feature-banner {
		aspect-ratio: auto;
		min-height: 560px;
	}

	.feature-banner__desc {
		margin-top: 1rem;
	}

	.feature-banner__cta {
		margin-top: 1.75rem;
	}
}

@media (max-width: 900px) {
	.page-hero {
		min-height: min(720px, 100svh);
	}
}

@media (max-width: 768px) {
	/* The mobile design keeps this decoration and makes it BIGGER — a broad
	   vertical motif 411 of the 440 frame, sitting behind the copy rather than
	   beside it. Hiding it (as this used to) is what left the band flat and
	   306 tall against the design's 717. */
	.ready__decoration {
		right: 0;
		left: 20.36%; /* 89.6 of the 440 frame */
		width: auto;
		background-position: center;
		opacity: 0.5; /* keeps the copy legible on top */
	}

	.section--ready {
		/* 717 of the 440 frame; the copy is centred in it, as in the design. */
		min-height: 163vw;
		padding-block: clamp(2.5rem, 8vw, 4rem);
	}

	.ready__content {
		gap: 28px;
	}

	/* line-height: 0.7em is a single-line cap-trim — it assumes the heading
	   never wraps. It does here, and the two lines then overlap by ~8px. Give
	   it a real line box back once wrapping is possible. */
	.ready__heading {
		line-height: 1.16;
	}
}

@media (max-width: 600px) {
	.intro__heading {
		font-size: clamp(1.5rem, 7vw, 1.75rem);
	}
}

@media (max-width: 900px) {
	.about-row__inner,
	.about-row--reverse .about-row__inner {
		flex-direction: column;
		align-items: stretch;
	}

	.about-row__text {
		flex: 1 1 auto;
		max-width: none;
	}

	.about-row__media {
		width: 100%;
	}
}

/* ==========================================================================
   Breakpoints
   ========================================================================== */

/* Tablet / mobile: hide the inline menu — the hamburger + drawer take over. */
@media (max-width: 900px) {
	.site-nav__menu {
		display: none;
	}
}

/* Mobile: stack footer bottom bar. */
@media (max-width: 600px) {
	.site-footer__bottom {
		flex-direction: column;
		align-items: flex-start;
	}
}

@media (max-width: 600px) {
	.book-form .book-row {
		flex-direction: column;
		gap: 25px;
	}

	.book-form .wpcf7-radio {
		flex-wrap: wrap;
	}
}
/* ========== sections/about-awards.css ========== */


@media (max-width: 900px) {
	.about-awards__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: clamp(1.5rem, 4vw, 2.5rem) clamp(1.5rem, 4vw, 3rem);
	}
}

@media (max-width: 480px) {
	.about-awards__grid {
		grid-template-columns: 1fr;
		max-width: 320px;
		margin-inline: auto;
	}
}
/* ========== sections/about-statement.css ========== */


@media (max-width: 600px) {
	.about-statement__watermark {
		font-size: clamp(2rem, 12vw, 3rem);
	}
}
/* ========== sections/about-vision.css ========== */


@media (max-width: 900px) {
	.about-vision__inner {
		flex-direction: column;
		align-items: flex-start;
		gap: clamp(2.5rem, 8vw, 4rem);
	}

	.about-vision__text {
		flex: 1 1 auto;
		max-width: none;
	}

	.about-vision__collage {
		width: min(547.5px, 100%);
		margin-inline: auto;
	}
}

/* On the narrowest screens the offset accents would dominate; pull them in. */
@media (max-width: 560px) {
	.about-vision__accent--red {
		left: 42%;
		width: 70%;
	}

	.about-vision__accent--beige {
		left: 16%;
		width: 92%;
	}
}
/* ========== sections/contact-form.css ========== */


@media (max-width: 900px) {
	.contact {
		grid-template-columns: 1fr;
		row-gap: 2.5rem;
	}

	.contact__intro {
		margin-top: 0;
	}
}
/* ========== sections/detail-awards.css ========== */


@media (max-width: 1100px) {
	.awards__grid {
		grid-template-columns: repeat(2, 1fr);
		justify-content: stretch;
	}

	.award__logo {
		width: 100%;
	}
}

/* The mobile design keeps two columns here (188 wide in the 440 frame) — the
   logos are square and the captions short, so a single column just made the
   section 2505px against the design's 846. The heading also moves from centred
   to flush left, lining up with the first column. */
@media (max-width: 600px) {
	.awards__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 1.5rem 24px;
	}

	.awards__heading {
		text-align: left;
	}
}
/* ========== sections/detail-gallery.css ========== */


/* The mobile design keeps the mosaic rather than stacking it: one landscape
   image across the top, then a tall one on the left with two small ones
   stacked beside it. Reference frame 440: 407.8x252.73 on top, then
   206.95x348.49 next to two 192.83x170.25.
   Shapes are mapped by proportion, not by index — item 1 is the wide one on
   desktop so it takes the wide slot here, and item 4 is the tall one so it
   takes the tall slot. Stacking all four instead made this section 1838px
   against the design's 877. */
@media (max-width: 900px) {
	.collage__grid {
		grid-template-columns: 206.947fr 192.832fr;
		grid-template-rows: 252.734fr 170.254fr 170.254fr;
	}

	.collage__item--1 {
		grid-column: 1 / -1;
		grid-row: 1;
		width: 100%;
		justify-self: stretch;
	}

	.collage__item--4 {
		grid-column: 1;
		grid-row: 2 / span 2;
		width: 100%;
		justify-self: stretch;
	}

	.collage__item--2 {
		grid-column: 2;
		grid-row: 2;
		width: 100%;
		justify-self: stretch;
	}

	.collage__item--3 {
		grid-column: 2;
		grid-row: 3;
		width: 100%;
		justify-self: stretch;
	}

	/* Seven swatches, four across (91 of the 408 inner width), not two.
	   The row is full-bleed by default; the design insets it 16 a side, which
	   is what turns a 99 swatch into the design's 91. */
	.finishes {
		flex-wrap: wrap;
		gap: 14.3px;
		padding-inline: 16px;
	}

	.finish-item {
		flex: 0 0 calc(25% - 10.725px);
	}

	/* The desktop cell is 177x143 — a landscape tile. The mobile one is 91x93,
	   near square, so the fixed 143 height has to go or the swatches come out
	   tall and the labels overflow them. */
	.finish {
		height: auto;
		aspect-ratio: 91 / 93;
	}

	/* Tag measures 53x25 on a 91 swatch, against 40 tall on the desktop cell.
	   Holding the desktop 16px/14px is what clipped "Grigio Fango". These ramp
	   with the viewport and reach the desktop values by ~900, where the cells
	   are back to full size. */
	.finish__label {
		padding: clamp(7px, 2.05vw, 14px);
		font-size: clamp(9px, 2.27vw, 16px);
	}
}
/* ========== sections/detail-hero.css ========== */


@media (max-width: 900px) {
	.detail-hero {
		min-height: min(720px, 100svh);
	}
}
/* ========== sections/detail-openings.css ========== */


/* Design order on mobile is heading -> image -> copy -> arrows, but the heading
   lives inside .openings__body, which follows the image in the DOM. Dissolving
   the body with `display: contents` promotes the heading and the copy to be
   flex children of .openings, so `order` alone can lift the heading above the
   image — no markup change, and the desktop two-column layout is untouched.
   The media is also a near-square on desktop (725.9/729.2) but landscape here
   (400/325.7), which is most of why this ran 1430px against the design's 584. */
@media (max-width: 900px) {
	.openings {
		flex-direction: column;
		align-items: stretch;
		gap: 1.5rem;
	}

	.openings__body {
		display: contents;
	}

	.openings__heading {
		order: -1;
	}

	.openings__media {
		flex: none;
		aspect-ratio: 400 / 325.703;
	}

	/* The design drops the ring around the slider arrows here and shows the
	   glyph on its own at 24px. */
	.openings__arrow {
		width: 24px;
		height: 24px;
	}

	.openings__arrow .slider__arrow-icon {
		width: 24px;
		height: 24px;
	}

	.openings__arrow .slider__arrow-icon circle {
		display: none;
	}

	.openings__nav {
		gap: 39px;
	}
}
/* ========== sections/home-hero.css ========== */


@media (max-width: 900px) {
	.section--hero {
		min-height: min(720px, 100svh);
	}
}

@media (max-width: 600px) {
	.hero__heading {
		font-size: clamp(1.6rem, 7vw, 2rem);
	}
}
/* ========== sections/home-quality.css ========== */


@media (max-width: 900px) {
	.quality__sticky {
		aspect-ratio: 3 / 4;
	}

	.quality__arch,
	.quality__mask {
		left: calc(12% * (1 - var(--p, 0)));
		width: calc(76% + 24% * var(--p, 0));
	}
}

/* The long heading can't sit on one line on a phone — let the pill wrap. */
@media (max-width: 700px) {
	.quality__pill {
		white-space: normal;
		width: max-content;
		max-width: 88vw;
	}
}
/* ========== sections/home-stats.css ========== */


/* ==========================================================================
   Small screens — horizontal track. Reference frame 440 wide: cards 244 in a
   400 window with a 24 gap, so the 780 track overflows and only ~1.6 cards are
   ever on screen. Stacking these vertically instead made the section 2126 tall
   against the design's 405.

   Two behaviours, in this order:
     1. no JS / reduced motion — the window scrolls natively (swipe), so every
        card stays reachable;
     2. .is-scrub (added by assets/js/stats.js) — the window stops scrolling and
        the track is translated by --stats-x, which the script scrubs from the
        page's vertical scroll. Cards travel right to left as the user scrolls.
   The alternating image-top/image-bottom rhythm is KEPT here; the design uses
   it on mobile too, and side by side it reads as intended rather than as an
   inconsistency (which is why the old stacked layout reset it).
   ========================================================================== */
@media (max-width: 900px) {
	.stats__grid {
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}

	.stats__grid::-webkit-scrollbar {
		display: none;
	}

	.stats__track {
		display: flex;
		/* 24 of the 440 frame. */
		gap: 5.4545vw;
		width: max-content;
		align-items: start;
	}

	.stat {
		/* 244 of the 440 frame — just over half the viewport, so the next card
		   is always partly visible and the row reads as scrollable. */
		flex: none;
		width: 55.4545vw;
	}

	/* JS is driving it: kill the native scroll so the two cannot fight. */
	.stats__grid.is-scrub {
		overflow-x: hidden;
	}

	.stats__grid.is-scrub .stats__track {
		transform: translate3d(var(--stats-x, 0px), 0, 0);
		will-change: transform;
	}
}
/* ========== sections/listing-filters.css ========== */


@media (max-width: 900px) {
	.filters {
		grid-template-columns: repeat(2, 1fr);
		gap: 1.5rem 1rem;
	}
}

/* line-height: 0.727em on .page-hero__title is Inter's cap height — a trim that
   only holds while the title is ONE line. Narrow screens wrap it ("KITCHENS
   STYLES" breaks in two) and the lines then sit on top of each other. Give it a
   real line box back here. Only .page-hero__title: .feature-banner__title shares
   the desktop rule but its titles are single words, so leaving it alone keeps
   the home banners exactly where they are. */
@media (max-width: 900px) {
	.page-hero__title {
		line-height: 1.15;
	}
}

/* --------------------------------------------------------------------------
   Small screens: the bar is a single row — the search field plus the sliders
   button — and every dropdown moves into a sheet that button opens. Reference
   frame 440: bar 400 wide x 60, search 317, button 46x46.
   Stacking the four controls instead cost ~290px of vertical space before the
   first product was visible.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
	.filters {
		display: block;
	}

	.filters__bar {
		display: flex;
		align-items: center;
		/* Search ends at 317 and the button starts at 354 in the 440 frame. */
		gap: clamp(16px, 8.4vw, 37px);
	}

	.filters__search {
		flex: 1;
		min-width: 0;
	}

	/* Bare glyph, no chrome — the design draws no box around it. The 46px box
	   is kept for the tap target (over the 44px minimum). */
	.filters__toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: none;
		width: 46px;
		height: 46px;
		padding: 0;
		border: 0;
		background: none;
		color: var(--white);
		cursor: pointer;
		transition: opacity 0.2s ease;
	}

	.filters__toggle:hover,
	.filters__toggle[aria-expanded="true"] {
		opacity: 0.7;
	}

	.filters__toggle-icon {
		width: 22px;
		height: 22px;
	}

	/* The sheet. Off-canvas until .is-open so it is never in the tab order or
	   read out while closed (visibility, not just opacity). */
	.filters__panel {
		position: fixed;
		z-index: 1000;
		right: 0;
		bottom: 0;
		left: 0;
		display: block;
		max-height: 85vh;
		overflow-y: auto;
		padding: 0 var(--container-pad) calc(var(--container-pad) + env(safe-area-inset-bottom, 0px));
		background: var(--color-bg);
		border-top: 1px solid var(--color-border);
		visibility: hidden;
		transform: translateY(100%);
		transition: transform 0.28s ease, visibility 0s linear 0.28s;
	}

	.filters__panel.is-open {
		visibility: visible;
		transform: translateY(0);
		transition: transform 0.28s ease, visibility 0s;
	}

	.filters__panel-head {
		position: sticky;
		top: 0;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 1rem;
		padding: 1.25rem 0 0.75rem;
		background: var(--color-bg);
	}

	.filters__panel-title {
		margin: 0;
		font-family: var(--font-body);
		font-size: 1.25rem;
		font-weight: 500;
		color: var(--white);
	}

	.filters__panel-close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		margin-right: -10px;
		padding: 0;
		border: 0;
		background: none;
		font-size: 2rem;
		line-height: 1;
		color: var(--white);
		cursor: pointer;
	}

	/* Inside the sheet the controls stack full width. */
	.filters__panel .filters__field {
		width: 100%;
		margin-bottom: 0.5rem;
	}

	.filters__panel-actions {
		display: block;
		position: sticky;
		bottom: 0;
		padding: 1rem 0 0.25rem;
		background: var(--color-bg);
	}

	.filters__panel-apply {
		width: 100%;
	}

	.filters__backdrop {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 999;
		background: rgba(0, 0, 0, 0.55);
	}

	.filters__backdrop[hidden] {
		display: none;
	}

	/* --- Dropdowns inside the sheet behave as an accordion ------------------
	   On desktop each list is an absolutely-positioned popover floating over
	   the page, which is right there. Inside the sheet that same popover covers
	   the controls above and below it. Here the list joins the flow instead and
	   pushes the rest of the sheet down, so nothing is ever obscured. The field
	   becomes a block (it is a fixed 56px flex row otherwise, which is what the
	   list would have to escape) and the underline moves onto the toggle so it
	   stays under the label rather than under the opened list. */
	.filters__panel .filters__field {
		display: block;
		height: auto;
		padding: 0;
		border-bottom: 0;
		overflow: visible;
	}

	.filters__panel .filter-dd {
		display: block;
	}

	.filters__panel .filter-dd__toggle {
		height: 56px;
		padding: 13px 6px;
		border-bottom: 1px solid rgba(255, 255, 255, 0.22);
	}

	.filters__panel .filters__field.is-open .filter-dd__toggle {
		border-color: rgba(255, 255, 255, 0.5);
	}

	.filters__panel .filter-dd__panel {
		position: static;
		max-height: 0;
		margin: 0;
		padding: 0 6px;
		border: 0;
		border-radius: 0;
		box-shadow: none;
		background: none;
		overflow: hidden;
		transform: none;
		/* max-height animates; the list is short enough that a fixed target
		   reads as a smooth open rather than a jump. */
		transition: max-height 0.28s ease, opacity 0.22s ease, padding 0.28s ease;
	}

	.filters__panel .filters__field.is-open .filter-dd__panel {
		max-height: 300px;
		padding: 6px;
		overflow-y: auto;
	}

	/* Breathing room under the last control for the expanded list. */
	.filters__panel .filters__field:last-of-type {
		margin-bottom: 1rem;
	}
}
/* ========== sections/listing-grid.css ========== */


@media (max-width: 768px) {
	.listing__grid {
		grid-template-columns: 1fr;
		row-gap: 3rem;
	}
}
/* ========== sections/media-feed.css ========== */


@media (max-width: 900px) {
	.feed__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.feed__grid {
		grid-template-columns: 1fr;
	}

	.feed__tabs {
		gap: 1.25rem;
	}
}
/* ========== sections/pro-audience.css ========== */


@media (max-width: 768px) {
	.pro-audience__cols {
		grid-template-columns: 1fr;
		gap: 1.5rem;
	}
}
/* ========== sections/pro-form.css ========== */


@media (max-width: 900px) {
	.pro-form__inner {
		flex-direction: column;
	}

	.pro-form__card {
		flex-basis: auto;
		max-width: none;
		min-height: 420px;
	}
}
/* ========== single-post.css ========== */


@media (max-width: 900px) {
	.article {
		grid-template-columns: 1fr;
		row-gap: 3rem;
	}
}
/* ==========================================================================
   Mobile header + heroes
   The mobile designs do NOT overlay the header on the hero image the way every
   wider frame does. It becomes a solid bar on the page background with the
   media starting below it: 125.75 bar + 633 media = the 759 hero of the 440
   frame. Overlaying it instead meant the logo sat on the photograph and the
   hero ran the full 720 on its own.
   Kept to 600px and below: the 1440 frame still overlays, so tablets keep the
   wide behaviour.
   ========================================================================== */
@media (max-width: 600px) {
	:root {
		/* The in-flow bar's real height: 30 above the logo + 59.9 logo + 35.85
		   below = the design's 125.75. Named so the hero below can subtract
		   exactly this and the two can never drift apart. */
		--header-bar-h: 125.75px;
	}

	.site-header {
		position: static;
		background: var(--color-bg);
	}

	.site-header__inner {
		padding-block: 30px 35.85px;
	}

	.site-header__logo img,
	.custom-logo {
		height: 59.9px;
	}

	/* Bar + hero fill the screen exactly. The design's 633 media is the 440
	   frame's proportion, but a phone is taller than that frame, so holding it
	   left a band of background under the fold; filling the viewport is what
	   the hero is meant to do. svh (not vh/dvh) means it still fits with the
	   browser's URL bar showing, so nothing is ever cut off.
	   min-height rather than height so an unusually long title can push it
	   taller instead of being clipped. */
	.section--hero,
	.page-hero,
	.detail-hero {
		aspect-ratio: auto;
		min-height: calc(100svh - var(--header-bar-h));
	}

	/* This clears the header because it is normally out of flow; here it is in
	   flow, so only the design's own top gap is wanted. */
	.section--article {
		padding-top: clamp(1.5rem, 6.1vw, 98px);
	}

	.hero__inner,
	.page-hero__inner,
	.detail-hero__inner {
		padding-top: 0;
	}

	/* Mobile header is the logo and the hamburger only. */
	.site-header__lang {
		display: none;
	}

	/* The hero title's clamp floor (2.25rem) is a desktop figure and far too
	   big here: the design's box is 20 tall, which over the 0.727 cap trim is a
	   ~27.5px face. 6.25vw lands exactly on that at 440. */
	.page-hero__title {
		font-size: clamp(1.125rem, 6.25vw, 1.875rem);
	}

	/* The slider dots are pinned 16px off the hero bottom and the CTAs sit
	   there too, so they collided. The design ends the last CTA at 682 and puts
	   the dots at 732 in a 759 hero — 77 and 19 from the bottom. */
	.detail-hero__inner {
		padding-bottom: 17.5vw;
	}

	.detail-hero__dots {
		bottom: 4.36vw;
	}
}
