/**
 * HouseBro Base Layer
 *
 * Font face, element defaults, layout primitives, buttons, utilities.
 * Everything here is either a bare element selector or a primitive that
 * many components build on. Component styling lives in components.css.
 *
 * New in Redesign v2 (2026-09-04). This layer did not previously exist —
 * element defaults, the container, the section rhythm and the button
 * primitives were scattered through components.css and were repeatedly
 * re-specified by later override passes. Separating them is what lets
 * components.css contain only components.
 *
 * ON SPECIFICITY. The parent theme (Hello Elementor) ships reset.css and
 * theme.css with bare-tag selectors, and functions.php now guarantees our
 * stylesheets load after them, so a bare tag selector here wins on source
 * order. The `body` prefix on the heading rules is kept because it costs
 * nothing and survives a future load-order change.
 */

/* ==========================================================================
   FONT — self-hosted Inter, one variable file, latin subset.

   Replaces the Google Fonts request the site inherited from Elementor's
   kit. 47KB covering weights 100-900, so no second request for bold and
   no render-blocking third-party connection. functions.php preloads this
   exact file.
   ========================================================================== */

@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url('../fonts/inter-var-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
		U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
		U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   ELEMENTS
   ========================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;

	/* The header is sticky and the service strip sits under it, so an
	   in-page jump (the strip's own "Services" anchor, or any #id link)
	   would otherwise land with its heading hidden behind both. Reserving
	   their combined height means the target arrives just below the
	   chrome, at every width, with no per-link offset. */
	scroll-padding-top: calc(var(--hb-header-h) + 52px);
}

body {
	margin: 0;
	background: var(--hb-color-ground);
	color: var(--hb-color-ink);
	font-family: var(--hb-font-family);
	font-size: var(--hb-font-size-body);
	line-height: var(--hb-line-height-body);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* The sticky CTA bar is fixed over the page bottom on phones. This
   reserves exactly its height so it never covers the last element.
   Gated on the class functions.php only adds when a real number is
   configured, so an unconfigured site gets no phantom gutter. */
body.hb-has-sticky-cta {
	padding-bottom: calc(var(--hb-sticky-cta-h) + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 1024px) {
	body.hb-has-sticky-cta {
		padding-bottom: 0;
	}
}

body h1,
body h2,
body h3,
body h4 {
	font-family: var(--hb-font-family);
	color: var(--hb-color-ink);
	margin: 0;
	text-wrap: balance;
	letter-spacing: -.01em;
}

body h1 {
	font-size: var(--hb-font-size-h1);
	font-weight: 700;
	line-height: var(--hb-line-height-h1);
}

body h2 {
	font-size: var(--hb-font-size-h2);
	font-weight: 700;
	line-height: var(--hb-line-height-h2);
}

body h3 {
	font-size: var(--hb-font-size-h3);
	font-weight: 600;
	line-height: var(--hb-line-height-h3);
}

body h4 {
	font-size: var(--hb-font-size-h4);
	font-weight: 600;
	line-height: var(--hb-line-height-h4);
}

body p {
	margin-block: 0 var(--hb-space-16);
}

body p:last-child {
	margin-bottom: 0;
}

img,
svg,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

ul,
ol {
	margin: 0;
	padding: 0;
}

a {
	color: var(--hb-brand-green);
	text-underline-offset: 2px;
}

a:hover {
	color: var(--hb-green-deep);
}

button {
	font: inherit;
	color: inherit;
}

:focus-visible {
	outline: 2px solid var(--hb-brand-green);
	outline-offset: 2px;
	border-radius: 2px;
}

::selection {
	background: var(--hb-green-soft);
	color: var(--hb-color-ink);
}

/* ==========================================================================
   LAYOUT PRIMITIVES
   ========================================================================== */

.hb-container {
	width: 100%;
	max-width: var(--hb-container);
	margin-inline: auto;
	padding-inline: var(--hb-gutter);
}

.hb-main {
	display: block;
}

/* A vertical rhythm unit. One token drives it, so section spacing can
   never drift apart between page types the way it previously did
   between Elementor-rendered and plain-template pages. */
.hb-section {
	padding-block: var(--hb-section-y);
}

.hb-section--tight {
	padding-block: var(--hb-section-y-tight);
}

/* Alternating grounds. This is what gives the page rhythm without
   adding decoration — the previous build was one continuous beige from
   header to footer. */
.hb-section--alt {
	background: var(--hb-color-ground-alt);
}

.hb-section--surface {
	background: var(--hb-color-surface);
}

/* A full-bleed dark green band. Its own foreground tokens are set here
   so anything dropped inside inherits readable colour rather than each
   child having to opt in. */
.hb-section--green {
	background: linear-gradient(160deg, var(--hb-brand-green), var(--hb-green-deep));
	color: var(--hb-color-on-dark);
}

.hb-section--green h2,
.hb-section--green h3,
.hb-section--green h4 {
	color: var(--hb-color-on-dark);
}

.hb-section--green p {
	color: var(--hb-color-on-dark-muted);
}

/* ==========================================================================
   THE PLAIN WORDPRESS PAGE TEMPLATE

   front-page.php and single-service_area.php are ours and use .hb-container
   directly. Everything else — both pillar pages, About, Contact, Gallery,
   FAQ, Delhi NCR — renders through Hello Elementor's own page template,
   whose markup we do not control. This block brings those pages onto the
   same container, rhythm and link treatment as the templates we do own.

   Without it, that content sits flush against the viewport edge and picks
   up the parent theme's defaults, including its #c36 pink links.
   ========================================================================== */

.hb-main .site-main,
.hb-main .elementor-shortcode {
	width: 100%;
	max-width: var(--hb-container);
	margin-inline: auto;
	padding-inline: var(--hb-gutter);
}

/* An .hb-container nested inside one of the above would double the gutter.
   Anything already carrying its own container keeps it and this one stands
   down. */
.hb-main .site-main .hb-container,
.hb-main .elementor-shortcode .hb-container {
	padding-inline: 0;
}

.hb-main .site-main {
	padding-block: var(--hb-section-y);
}

/* Prose rhythm inside page content. The old build set this with an
   `.hb-main h2` descendant selector, which also caught every heading inside
   every card and then had to be undone component by component. Scoped to
   direct children of the content wrapper, so a card's <h3> is never
   affected. */
.page-content > h2,
.entry-content > h2 {
	margin-block: var(--hb-section-y-tight) var(--hb-heading-gap);
}

.page-content > h3,
.entry-content > h3 {
	margin-block: var(--hb-space-32) var(--hb-space-12);
}

.page-content > h2:first-child,
.entry-content > h2:first-child {
	margin-top: 0;
}

/* Hello Elementor sets `.page-content a { color: #c36 }` — a pink with no
   relationship to this brand — at a specificity our bare `a` rule cannot
   beat regardless of load order. Matched here rather than raised to
   !important.

   BUTTONS AND CARDS ARE EXCLUDED, and that exclusion is the fix for a real
   defect rather than tidiness. This rule is (0,2,1); `.hb-btn-call` is
   (0,1,0). So on every page rendered through Hello Elementor's page
   template — both pillar pages, About, Contact, Gallery, FAQ, Delhi NCR —
   this rule won the `color` declaration on the Call button, which kept its
   dark green BACKGROUND from .hb-btn-call and took dark green TEXT from
   here. Same colour on both: the label and the phone icon rendered
   invisible, on the primary conversion control, on six pages.

   Verified on the running site before the fix: three buttons on
   /tile-cleaning/ computed background and color both rgb(15,77,58).

   A link that is styled as a component must never be restyled as prose. */
.hb-main .page-content a:not(.hb-btn):not(.hb-card),
.hb-main .entry-content a:not(.hb-btn):not(.hb-card) {
	color: var(--hb-brand-green);
}

/* The same parent rule underlines links inside its content area, which
   turned Call/WhatsApp buttons dropped into page content into underlined
   text. */
.hb-main .hb-btn,
.hb-main .hb-card,
.hb-main .page-content a.hb-btn {
	text-decoration: none;
}

.hb-main .hb-contact-card-row a {
	color: inherit;
	text-decoration: underline;
}

.hb-main .hb-contact-card-row a:hover {
	text-decoration: none;
}

/* A bare Call/WhatsApp pair in page content — About, Gallery, FAQ and the
   Delhi NCR page each end with one, written as a plain paragraph with no
   wrapping element.

   It used to be given a large padded gradient card with a shadow, which is
   the oversized empty CTA box this redesign removes. It is now simply a
   centred button row: the buttons are the call to action, and wrapping them
   in a panel added weight without adding meaning. */
.page-content p:has(> a.hb-btn-call) {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--hb-space-12);
	margin-block: var(--hb-space-32) 0;
}

.page-content p:has(> a.hb-btn-call) br {
	display: none;
}

.page-content p:has(> a.hb-btn-call) .hb-btn {
	flex: 1 1 auto;
	min-width: 160px;
	max-width: 260px;
}

/* ==========================================================================
   SECTION HEADINGS

   One treatment, defined once. The previous build set this with an
   `.hb-main h2` descendant selector plus a brass underline pseudo-element,
   which several later passes then had to undo per component.  Here the
   eyebrow/title/lead trio is an explicit component the templates opt into,
   so a heading inside a card is never accidentally given a 64px margin and
   an underline.
   ========================================================================== */

.hb-section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--hb-space-8) var(--hb-space-16);
	margin-bottom: var(--hb-heading-gap);
}

.hb-section-head--center {
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.hb-section-eyebrow {
	display: block;
	font-size: var(--hb-font-size-xs);
	font-weight: 700;
	letter-spacing: var(--hb-tracking-label);
	text-transform: uppercase;
	color: var(--hb-color-brass);
	margin-bottom: var(--hb-space-8);
}

.hb-section--green .hb-section-eyebrow {
	color: var(--hb-brand-gold);
}

.hb-section-title {
	font-size: var(--hb-font-size-h2);
	font-weight: 700;
	line-height: var(--hb-line-height-h2);
	margin: 0;
}

.hb-section-lead {
	max-width: 62ch;
	color: var(--hb-color-stone-grey);
	margin-top: var(--hb-space-8);
}

.hb-section-head--center .hb-section-lead {
	margin-inline: auto;
}

.hb-section--green .hb-section-lead {
	color: var(--hb-color-on-dark-muted);
}

.hb-section-link {
	font-size: var(--hb-font-size-small);
	font-weight: 600;
	color: var(--hb-brand-green);
	text-decoration: none;
	white-space: nowrap;
}

.hb-section-link:hover {
	text-decoration: underline;
}

/* ==========================================================================
   CARD PRIMITIVE

   Border-led, not shadow-led. Every block being a shadowed rounded card
   on the same ground is what flattened the previous build's hierarchy;
   here a card is a quiet container and emphasis is spent deliberately.
   ========================================================================== */

.hb-card {
	background: var(--hb-color-surface);
	border: 1px solid var(--hb-color-divider);
	border-radius: var(--hb-radius-card);
	box-shadow: var(--hb-shadow-premium-resting);
}

/* Only interactive cards lift. A static card that lifts on hover
   promises a click that does not exist.

   DELIBERATELY SETS NO `display`. An element+class selector like
   `a.hb-card` (0,1,1) outranks a component's own `.hb-catalogue-tile`
   (0,1,0), so declaring `display: block` here silently overrode the
   flex-column layout of every anchor-based card in components.css —
   which is what put the "Flagship" badge inline in the middle of a
   wrapped tile name. Each card sets its own display; this rule only
   carries the interactive affordances. */
a.hb-card,
button.hb-card {
	text-decoration: none;
	color: inherit;
	transition: border-color var(--hb-transition), box-shadow var(--hb-transition), transform var(--hb-transition);
}

a.hb-card:hover,
button.hb-card:hover {
	border-color: var(--hb-green-border);
	box-shadow: var(--hb-shadow-premium-hover);
	transform: translateY(-2px);
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */

.hb-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--hb-space-8);
	min-height: 48px;
	padding-inline: var(--hb-space-24);
	border: 1px solid transparent;
	border-radius: var(--hb-radius-button);
	font-size: var(--hb-font-size-button);
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--hb-transition), border-color var(--hb-transition), transform var(--hb-transition);
}

.hb-btn:active {
	transform: translateY(1px);
}

.hb-btn .hb-icon {
	width: 18px;
	height: 18px;
	flex: none;
}

/* ==========================================================================
   BUTTON COLOUR — DECLARED ONCE, SET PER CONTEXT

   Each button owns a pair of custom properties for its ground and its
   foreground. One low-level rule paints from that pair; a context that
   needs different colours reassigns the pair rather than re-declaring
   `background` and `color` itself.

   WHY IT IS BUILT THIS WAY. The previous version painted directly and let a
   context override with a descendant selector, which meant every button's
   final colour depended on winning a specificity race against any other
   rule that could match an <a>. It lost one: `.hb-main .page-content a`
   (0,2,1) beat `.hb-btn-call` (0,1,0) and repainted the label dark green on
   a dark green button — invisible text and an invisible phone icon on the
   site's primary conversion control.

   A custom property cannot be captured that way. `--hb-call-fg` is only
   ever set by a rule that deliberately targets the button, so a prose rule
   somewhere else in the cascade has nothing to win. The paint rule below
   also states :link and :visited explicitly, because a tel: link genuinely
   becomes :visited after a call and a stray a:visited rule would otherwise
   reach it.

   Adding a new dark surface means adding it to the ONE list below, and the
   foreground travels with it automatically.
   ========================================================================== */

/* ---- Call: gold ground, white label (approved mobile UI, 2026-10-02 —
        was brand green). Primary weight, because a phone call is the
        highest-intent action on the site. .hb-btn-gold is the same
        treatment for non-call primary actions ("View Details",
        "Continue to {City}"). ------------------------------------------- */
.hb-btn-call,
.hb-btn-gold {
	--hb-call-bg: var(--hb-gold-action);
	--hb-call-fg: #FFFFFF;
	--hb-call-bg-hover: var(--hb-gold-action-hover);
	--hb-call-border: var(--hb-gold-action-solid);
}

/* ---- WhatsApp: deep WhatsApp green, white label (2026-10-02). The
        reference pairs a white label with a deep green; white on the bright
        #25D366 was only ~1.9:1, white on this green is 5.4:1. ------------ */
.hb-btn-whatsapp {
	--hb-wa-bg: var(--hb-whatsapp-deep);
	--hb-wa-fg: #FFFFFF;
	--hb-wa-bg-hover: var(--hb-whatsapp-deep-hover);
}

/* ---- Contexts. These set the pair and nothing else, so a context can
        never accidentally drop a foreground and leave a button unpainted.

        Every dark green surface on the site is named here. A Call button on
        a dark ground inverts to a white pill with green text; the WhatsApp
        button keeps its own green, which reads correctly on both. -------- */
.hb-hero .hb-btn-call,
.hb-cta-block .hb-btn-call,
.hb-work-in-action .hb-btn-call,
.hb-section--green .hb-btn-call,
.hb-footer .hb-btn-call {
	--hb-call-bg: var(--hb-color-surface);
	--hb-call-fg: var(--hb-brand-green);
	--hb-call-bg-hover: var(--hb-color-ground);
	--hb-call-border: var(--hb-color-surface);
}

/* ---- Paint. :link and :visited are stated so no generic anchor rule,
        including a visited-link rule, can reach these. ------------------- */
.hb-btn-call,
a.hb-btn-call,
a.hb-btn-call:link,
a.hb-btn-call:visited,
.hb-btn-gold,
a.hb-btn-gold,
a.hb-btn-gold:link,
a.hb-btn-gold:visited {
	background: var(--hb-call-bg);
	color: var(--hb-call-fg);
	border-color: var(--hb-call-border);
}

.hb-btn-whatsapp,
a.hb-btn-whatsapp,
a.hb-btn-whatsapp:link,
a.hb-btn-whatsapp:visited {
	background: var(--hb-wa-bg);
	color: var(--hb-wa-fg);
	border-color: var(--hb-wa-bg);
}

a.hb-btn-call:hover,
a.hb-btn-call:focus,
a.hb-btn-call:active,
.hb-btn-call:hover,
a.hb-btn-gold:hover,
a.hb-btn-gold:focus,
a.hb-btn-gold:active,
.hb-btn-gold:hover {
	background: var(--hb-call-bg-hover);
	color: var(--hb-call-fg);
}

.hb-btn-gold:disabled {
	opacity: .45;
	cursor: not-allowed;
}

/* ---- Two secondary treatments from the service page (2026-10-02):
        "Get Free Inspection" (brand green, white label, 9.8:1) and "View
        Process" (white with a quiet border). ----------------------------- */
.hb-btn-inspect,
a.hb-btn-inspect,
a.hb-btn-inspect:link,
a.hb-btn-inspect:visited {
	background: var(--hb-brand-green);
	border-color: var(--hb-brand-green);
	color: #FFFFFF;
}

a.hb-btn-inspect:hover,
a.hb-btn-inspect:focus {
	background: var(--hb-green-deep);
	color: #FFFFFF;
}

.hb-btn-outline,
a.hb-btn-outline,
a.hb-btn-outline:link,
a.hb-btn-outline:visited {
	background: var(--hb-color-surface);
	border-color: var(--hb-color-divider);
	color: var(--hb-color-ink);
	box-shadow: var(--hb-shadow-premium-resting);
}

a.hb-btn-outline:hover,
a.hb-btn-outline:focus {
	border-color: var(--hb-gold-border);
	color: var(--hb-color-ink);
}

.hb-btn-outline .hb-icon {
	color: var(--hb-gold-text);
}

.hb-btn-inspect .hb-icon {
	color: #FFFFFF;
}

/* Two-line label (sticky bar): "Call Now" over the number. */
.hb-btn-label-main,
.hb-btn-label-sub {
	display: block;
	text-align: left;
}

.hb-btn-label-sub {
	font-size: .78em;
	font-weight: 500;
	opacity: .92;
	margin-top: 2px;
}

a.hb-btn-whatsapp:hover,
a.hb-btn-whatsapp:focus,
a.hb-btn-whatsapp:active,
.hb-btn-whatsapp:hover {
	background: var(--hb-wa-bg-hover);
	color: var(--hb-wa-fg);
}

/* The icon is painted from the same property as the label rather than left
   to inherit `currentColor`. Inheritance is what failed above: whatever
   repainted the label repainted the icon with it, so both vanished
   together. Pinning it to the token means the icon is correct even if
   something ever wins `color` on the anchor again. */
.hb-btn-call .hb-icon,
.hb-btn-gold .hb-icon {
	color: var(--hb-call-fg);
}

.hb-btn-whatsapp .hb-icon {
	color: var(--hb-wa-fg);
}

/* A CTA pair. Used by the hero, the pricing card and the closing panel —
   one definition rather than three near-identical ones. */
.hb-cta-pair {
	display: flex;
	flex-wrap: wrap;
	gap: var(--hb-space-12);
}

.hb-cta-pair .hb-btn {
	flex: 1 1 auto;
	min-width: 150px;
}

@media (min-width: 640px) {
	.hb-cta-pair .hb-btn {
		flex: 0 0 auto;
	}
}

/* ==========================================================================
   SMALL SHARED PIECES
   ========================================================================== */

.hb-badge-pill {
	display: inline-flex;
	align-items: center;
	gap: var(--hb-space-4);
	padding: 4px 10px;
	border-radius: var(--hb-radius-pill);
	font-size: var(--hb-font-size-xs);
	font-weight: 600;
	line-height: 1.3;
}

.hb-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 5px 11px;
	background: var(--hb-color-surface);
	border: 1px solid var(--hb-color-divider);
	border-radius: var(--hb-radius-pill);
	font-size: var(--hb-font-size-xs);
	font-weight: 500;
	color: var(--hb-color-ink);
	line-height: 1.35;
}

.hb-chip .hb-icon {
	width: 14px;
	height: 14px;
	color: var(--hb-color-brass);
	flex: none;
}

.hb-icon {
	width: 20px;
	height: 20px;
	flex: none;
}

/* ==========================================================================
   THE HIDDEN ATTRIBUTE MUST ALWAYS WIN

   The city filter works by setting `el.hidden = true`. The browser's own
   rule for that is `[hidden] { display: none }` in the UA stylesheet, and
   ANY author rule that sets `display` beats it — author styles outrank the
   UA sheet regardless of specificity.

   That is not theoretical. `.hb-service-cards > li { display: flex }` made
   the homepage's service cards ignore the attribute completely: on a Pune
   homepage the header strip, the catalogue and the heading all filtered
   correctly while the service cards carried on showing Marble Polishing
   and Tile Cleaning — the single most visible surface, silently exempt
   from the rule the whole city-first architecture rests on.

   One rule here fixes it for every element the filter touches today and
   every one it will touch later, instead of each component having to
   remember to re-declare `display: none`. `!important` is load-bearing
   rather than lazy: it has to outrank component display rules by design,
   because the attribute means "this is not here".
   ========================================================================== */

[hidden] {
	display: none !important;
}

/* ==========================================================================
   ACCESSIBILITY UTILITIES
   ========================================================================== */

.hb-visually-hidden {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.hb-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 200;
	padding: 12px 20px;
	background: var(--hb-brand-green);
	color: var(--hb-color-on-dark);
	font-weight: 600;
	text-decoration: none;
	border-radius: 0 0 var(--hb-radius-button) 0;
}

.hb-skip-link:focus {
	left: 0;
	color: var(--hb-color-on-dark);
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		scroll-behavior: auto !important;
	}
}
