/*
Theme Name: Myriad InfoTech
Theme URI: https://myriadinfotech.com/
Author: Myriad InfoTech
Author URI: https://myriadinfotech.com/
Description: A production-ready Full Site Editing (FSE) block theme for modern IT and technology enterprises. Cinematic GSAP scroll choreography, a dark engineering-grade palette, GPU-safe layout, and a native reduced-motion fallback. Built for Myriad InfoTech, Sonipat, Haryana.
Version: 1.0.17
Requires at least: 6.3
Tested up to: 6.6
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sonipat-it
Tags: Full Site Editing, Block Editor, Dark, Custom Menu, Wide Blocks, Translation Ready
*/


/* ==========================================================================
   1. DESIGN TOKENS
   --------------------------------------------------------------------------
   Every visual value in the theme resolves to one of these custom
   properties. They read the theme.json palette and fall back to the value
   theme.json ships, so the shipped site looks exactly the same as it did
   while the Customizer's Colours & type panel lets the owner repaint a
   preset and have the whole sheet follow. Override them in a child theme
   and the whole site re-skins without touching a single rule below.
   ========================================================================== */

:root {

	/* --- Surface stack (light, back to front) -------------------------- */
	--sonipat-bg: var(--wp--preset--color--canvas, #ffffff);
	--sonipat-bg-elevated: var(--wp--preset--color--band, #f6f3fe);
	--sonipat-surface: var(--wp--preset--color--surface, #ffffff);
	--sonipat-surface-hover: var(--wp--preset--color--surface-tint, #faf7ff);
	--sonipat-border: var(--wp--preset--color--hairline, rgba(23, 1, 44, 0.10));
	--sonipat-border-strong: var(--wp--preset--color--hairline-strong, rgba(23, 1, 44, 0.20));

	/* --- Type ------------------------------------------------------------ */
	--sonipat-text: var(--wp--preset--color--ink, #17012c);
	--sonipat-text-muted: var(--wp--preset--color--ink-muted, #504e4e);
	--sonipat-text-faint: var(--wp--preset--color--ink-faint, #6a6678);

	/* --- Brand ----------------------------------------------------------- */
	--sonipat-primary: var(--wp--preset--color--primary, #6a47ed);
	--sonipat-primary-hover: var(--wp--preset--color--primary-deep, #5434d0);
	--sonipat-primary-soft: var(--wp--preset--color--primary-soft, rgba(106, 71, 237, 0.10));
	/* Lime is a fill, never a text colour on a light surface — it fails
	   contrast there. Use --sonipat-accent-ink for type on top of it. */
	--sonipat-secondary: var(--wp--preset--color--accent-lime, #c6f806);
	--sonipat-accent-ink: var(--wp--preset--color--ink, #17012c);
	--sonipat-glow: var(--wp--preset--color--primary-glow, rgba(106, 71, 237, 0.24));

	/* --- Washes ---------------------------------------------------------- */
	/* Chips, eyebrows and card gradients sit on either surface, so they read
	   tokens rather than a literal. The dark-band remap below flips all three
	   in one place. */
	--sonipat-wash: var(--wp--preset--color--primary-wash, rgba(106, 71, 237, 0.07));
	--sonipat-wash-strong: var(--wp--preset--color--band-wash, rgba(246, 243, 254, 0.92));
	--sonipat-chip: var(--wp--preset--color--band-chip, rgba(246, 243, 254, 0.85));

	/* --- Rhythm ---------------------------------------------------------- */
	--sonipat-radius: 18px;
	--sonipat-radius-sm: 10px;
	/* A shadow is the text colour at low alpha, so a repainted site should not keep
	   the ink it shipped with. The literal above is what a browser without
	   color-mix() gets. */
	--sonipat-shadow: 0 22px 50px -30px rgba(23, 1, 44, 0.22);
	--sonipat-shadow: 0 22px 50px -30px color-mix( in srgb, var(--sonipat-text) 22%, transparent );
	--sonipat-shadow-lift: 0 38px 80px -40px rgba(23, 1, 44, 0.30);
	--sonipat-shadow-lift: 0 38px 80px -40px color-mix( in srgb, var(--sonipat-text) 30%, transparent );
	--sonipat-gap: clamp(1.25rem, 3vw, 2.5rem);
	--sonipat-section-y: clamp(4.5rem, 11vw, 9rem);

	/* --- Motion ---------------------------------------------------------- */
	--sonipat-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--sonipat-duration: 0.45s;

	/* WordPress injects the editor's fluid font sizes here; these are the
	   front-end fallbacks so standalone <p>/<h*> still scale correctly. */
	--wp--preset--font-size--small: clamp(0.875rem, 0.83rem + 0.22vw, 1rem);
	--wp--preset--font-size--medium: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
	--wp--preset--font-size--large: clamp(1.35rem, 1.15rem + 1vw, 2rem);
	--wp--preset--font-size--x-large: clamp(2rem, 1.5rem + 2.6vw, 3.25rem);
}

/* Dark bands on a light site. Every rule below reads the tokens, so
   remapping them on a band re-skins the whole subtree — header, hero, CTA,
   footer — without a single colour declaration per component.
   The band tones are the same two colours the page is written in, seen from
   the other side, so they read the derived palette: repaint the text colour
   and the footer follows it instead of staying the shipped purple-black. */
.sonipat-header,
.sonipat-footer,
.hero-scroll-section,
.booking-cta {
	--sonipat-bg: var(--wp--preset--color--inverse, #17012c);
	--sonipat-bg-elevated: var(--wp--preset--color--inverse-soft, #1e0737);
	--sonipat-surface: var(--wp--preset--color--inverse-surface, #24103f);
	--sonipat-surface-hover: var(--wp--preset--color--inverse-surface-hover, #2c1a4c);
	--sonipat-border: var(--wp--preset--color--inverse-hairline, rgba(255, 255, 255, 0.13));
	--sonipat-border-strong: var(--wp--preset--color--inverse-hairline-strong, rgba(255, 255, 255, 0.26));
	--sonipat-text: var(--wp--preset--color--on-inverse, #f4f1ff);
	--sonipat-text-muted: var(--wp--preset--color--on-inverse-muted, #b6a7dd);
	--sonipat-text-faint: var(--wp--preset--color--on-inverse-faint, #8d7cb8);
	--sonipat-primary-soft: var(--wp--preset--color--primary-soft-inverse, rgba(106, 71, 237, 0.22));
	--sonipat-glow: var(--wp--preset--color--primary-glow-inverse, rgba(106, 71, 237, 0.45));
	--sonipat-shadow: 0 22px 50px -30px rgba(0, 0, 0, 0.55);
	--sonipat-shadow-lift: 0 38px 80px -40px rgba(0, 0, 0, 0.7);
	--sonipat-wash: var(--wp--preset--color--inverse-wash, rgba(255, 255, 255, 0.09));
	--sonipat-wash-strong: var(--wp--preset--color--inverse-wash-strong, rgba(255, 255, 255, 0.05));
	--sonipat-chip: var(--wp--preset--color--inverse-chip, rgba(255, 255, 255, 0.07));

	/* The band paints its own surface. Header, CTA and hero all declare a
	   background later in the cascade and still win; this is the fallback that
	   keeps a band that declares none (the hero group) from showing the page's
	   white canvas behind light-coloured text. */
	background: var(--sonipat-bg);

	/* theme.json writes block colours as --wp--preset--color--* variables, so
	   band text that comes from a preset (paragraph muted, post date, link
	   hover) only follows the band if the presets are remapped too. */
	--wp--preset--color--canvas: var(--wp--preset--color--inverse, #17012c);
	--wp--preset--color--band: var(--wp--preset--color--inverse-soft, #1e0737);
	--wp--preset--color--surface: var(--wp--preset--color--inverse-surface, #24103f);
	--wp--preset--color--surface-tint: var(--wp--preset--color--inverse-surface-hover, #2c1a4c);
	--wp--preset--color--ink: var(--wp--preset--color--on-inverse, #f4f1ff);
	--wp--preset--color--ink-muted: var(--wp--preset--color--on-inverse-muted, #b6a7dd);
	--wp--preset--color--ink-faint: var(--wp--preset--color--on-inverse-faint, #8d7cb8);
	--wp--preset--color--hairline: var(--wp--preset--color--inverse-hairline, rgba(255, 255, 255, 0.13));

	color: var(--sonipat-text);
}


/* ==========================================================================
   2. BASE / RESET
   ========================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background-color: var(--sonipat-bg);
	color: var(--sonipat-text);
	font-family: var(--wp--preset--font-family--sonipat-sans, "Plus Jakarta Sans", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif);
	font-size: var(--wp--preset--font-size--medium, 1.0625rem);
	line-height: 1.7;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* Ambient depth: two fixed radial washes so the dark canvas never reads flat. */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	/* The second background is the same wash with the brand tokens in place of the
	   shipped literals; a browser without color-mix() keeps the one above. */
	background:
		radial-gradient(60vw 60vw at 12% -10%, rgba(106, 71, 237, 0.14), transparent 60%),
		radial-gradient(50vw 50vw at 90% 10%, rgba(198, 248, 6, 0.09), transparent 62%);
	background:
		radial-gradient(60vw 60vw at 12% -10%, color-mix( in srgb, var(--sonipat-primary) 14%, transparent ), transparent 60%),
		radial-gradient(50vw 50vw at 90% 10%, color-mix( in srgb, var(--sonipat-secondary) 9%, transparent ), transparent 62%);
}

a {
	color: var(--sonipat-primary-hover);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.25em;
	transition: color var(--sonipat-duration) var(--sonipat-ease);
}

a:hover {
	color: var(--sonipat-text);
}

img,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

::selection {
	background: var(--sonipat-primary);
	color: #ffffff;
}

/* Visible, high-contrast focus ring on every interactive element. */
:focus-visible {
	outline: 2px solid var(--sonipat-primary);
	outline-offset: 3px;
	border-radius: 4px;
}

.screen-reader-text {
	clip: rect(0, 0, 0, 0);
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	white-space: nowrap;
}

.skip-link:focus {
	position: fixed;
	top: 1rem;
	left: 1rem;
	z-index: 99999;
	clip: auto;
	width: auto;
	height: auto;
	padding: 0.75rem 1.25rem;
	background: var(--sonipat-primary);
	color: #fff;
	border-radius: 8px;
}


/* ==========================================================================
   3. LAYOUT SHELL
   ========================================================================== */

.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

main#wp-block-site-content,
.entry-content {
	flex-grow: 1;
}

.is-layout-constrained > .alignwide {
	max-width: var(--wp--style--global--wide-size, 1400px);
}

/* Section band used by the block patterns. */
.sonipat-section {
	padding-block: var(--sonipat-section-y);
	position: relative;
}

.sonipat-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.4rem 0.9rem;
	border: 1px solid var(--sonipat-border-strong);
	border-radius: 999px;
	background: var(--sonipat-wash);
	color: var(--sonipat-text-muted);
	font-size: 0.78rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.sonipat-eyebrow::before {
	content: "";
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--sonipat-primary);
	box-shadow: 0 0 12px var(--sonipat-glow);
}


/* ==========================================================================
   4. HEADER / NAVIGATION
   ========================================================================== */

/* Stickiness is the owner's choice, not a fact about the layout, so the rule that
   makes the header part stick lives in assets/css/header-behaviour.css behind a
   body class. What stays here is the shape that rule needs: the header template
   part is a flex item of `.wp-site-blocks`, which spans the whole document, so the
   *part wrapper* is the box that has to stick — a sticky child inside the short
   part wrapper would never travel. */
.wp-site-blocks > .wp-block-template-part:first-child,
.wp-site-blocks > .wp-block-template-part:has(.sonipat-header) {
	z-index: 100;
}

/* The header is the one band the sheet paints sheer, so its share is a floor rather
   than a fixed value: PHP solves `--sonipat-header-scrim` for the picked ink and page
   colour, and only pushes past 72% when the lifted band text could not hold 4.5:1 on
   the ground the scrim would leave. Nothing is written when the palette is untouched,
   so the fallback is the shipped sheerness. The hover and scrolled states take the
   larger of their own share and the floor, so they can never end up sheerer than the
   header they replace. */
.sonipat-header {
	backdrop-filter: blur(14px);
	-webkit-backdrop-filter: blur(14px);
	background: rgba(23, 1, 44, 0.72);
	background: color-mix( in srgb, var(--wp--preset--color--inverse, #17012c) var(--sonipat-header-scrim, 72%), transparent );
	border-bottom: 1px solid var(--sonipat-border);
	transition: background var(--sonipat-duration) var(--sonipat-ease);
}

.sonipat-header:hover {
	background: rgba(23, 1, 44, 0.92);
	background: color-mix( in srgb, var(--wp--preset--color--inverse, #17012c) max( 92%, var(--sonipat-header-scrim, 72%) ), transparent );
}

/* Solidifies once ScrollTrigger reports the page has scrolled. */
.sonipat-header.is-scrolled {
	background: rgba(23, 1, 44, 0.96);
	background: color-mix( in srgb, var(--wp--preset--color--inverse, #17012c) max( 96%, var(--sonipat-header-scrim, 72%) ), transparent );
	box-shadow: var(--sonipat-shadow);
}

.wp-block-site-title a {
	color: var(--sonipat-text);
	font-weight: 700;
	letter-spacing: -0.02em;
	text-decoration: none;
}

.wp-block-site-title span {
	color: var(--sonipat-primary);
}

.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--sonipat-bg);
	padding-block: 4rem;
}

/* Sticky offset for the WP admin bar so the header never hides underneath. */
.admin-bar .wp-site-blocks > .wp-block-template-part:first-child {
	top: 32px;
}

@media only screen and (max-width: 782px) {
	.admin-bar .wp-site-blocks > .wp-block-template-part:first-child {
		top: 46px;
	}
}


/* ==========================================================================
   5. BLOCK TREATMENT
   --------------------------------------------------------------------------
   Core blocks only - no wrapper markup, nothing the editor cannot reach.
   ========================================================================== */

/* Buttons */
.wp-block-button__link {
	background: var(--sonipat-primary);
	color: #ffffff;
	border: 1px solid transparent;
	border-radius: 12px;
	padding: 0.9em 1.7em;
	font-weight: 600;
	letter-spacing: 0.01em;
	box-shadow: 0 14px 34px -18px var(--sonipat-glow);
	transition:
		transform var(--sonipat-duration) var(--sonipat-ease),
		background var(--sonipat-duration) var(--sonipat-ease),
		box-shadow var(--sonipat-duration) var(--sonipat-ease);
}

.wp-block-button__link:hover {
	background: var(--sonipat-primary-hover);
	color: #ffffff;
	transform: translateY(-2px);
	box-shadow: 0 22px 48px -20px var(--sonipat-glow);
}

.is-style-outline > .wp-block-button__link:not(.has-text-color),
.wp-block-button__link.is-style-outline {
	color: var(--sonipat-text);
	background: transparent;
	border-color: var(--sonipat-border-strong);
	box-shadow: none;
}

.is-style-outline > .wp-block-button__link:hover {
	background: var(--sonipat-primary-soft);
	border-color: var(--sonipat-primary);
	color: var(--sonipat-text);
}

/* Headings */
h1, h2, h3, h4, h5, h6 {
	line-height: 1.12;
	letter-spacing: -0.025em;
	font-weight: 700;
	color: var(--sonipat-text);
}

/* Cards: any group/column given the `is-card` class */
.is-card,
.sonipat-card {
	background: linear-gradient(160deg, var(--sonipat-surface), var(--sonipat-wash-strong));
	border: 1px solid var(--sonipat-border);
	border-radius: var(--sonipat-radius);
	box-shadow: var(--sonipat-shadow);
	transition:
		border-color var(--sonipat-duration) var(--sonipat-ease),
		transform var(--sonipat-duration) var(--sonipat-ease),
		box-shadow var(--sonipat-duration) var(--sonipat-ease);
}

.is-card:hover,
.sonipat-card:hover {
	border-color: rgba(106, 71, 237, 0.4);
	border-color: color-mix( in srgb, var(--sonipat-primary) 40%, transparent );
	box-shadow: var(--sonipat-shadow-lift);
}

/* Pull-quote / stats wells used in the story pattern */
.sonipat-stat {
	padding: 1.5rem;
	border-left: 2px solid var(--sonipat-primary);
	background: var(--sonipat-chip);
	border-radius: 0 var(--sonipat-radius-sm) var(--sonipat-radius-sm) 0;
}

.sonipat-stat strong {
	display: block;
	font-size: var(--wp--preset--font-size--x-large, 2.5rem);
	line-height: 1;
	color: var(--sonipat-text);
	letter-spacing: -0.03em;
}

.sonipat-stat span {
	color: var(--sonipat-text-muted);
	font-size: 0.88rem;
}

/* Lists */
ul.wp-block-list,
ol.wp-block-list {
	color: var(--sonipat-text-muted);
}

.wp-block-list li::marker {
	color: var(--sonipat-primary);
}

/* Separator */
.wp-block-separator {
	border: none;
	border-top: 1px solid var(--sonipat-border);
	opacity: 1;
}

/* Footer */
.sonipat-footer {
	background: var(--sonipat-bg-elevated);
	border-top: 1px solid var(--sonipat-border);
	color: var(--sonipat-text-muted);
}

.sonipat-footer a {
	color: var(--sonipat-text-muted);
	text-decoration: none;
}

.sonipat-footer a:hover {
	color: var(--sonipat-primary-hover);
}

.sonipat-footer h1,
.sonipat-footer h2,
.sonipat-footer h3,
.sonipat-footer h4 {
	color: var(--sonipat-text);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	font-size: 0.85rem;
}


/* ==========================================================================
   6. CINEMATIC LAYERS
   --------------------------------------------------------------------------
   These rules describe the *resting* (pre-animation) state. GSAP only ever
   writes inline transforms/opacities on top of them, and removes them again
   on cleanup - so the CSS below stays the single source of truth.
   ========================================================================== */

/* 6.1 Hero -----------------------------------------------------------------
   The scroll track owns its own height so shrinking never collapses the
   layout or causes ScrollTrigger's measurements to drift. */
.hero-scroll-section {
	position: relative;
	min-height: min(100vh, 900px);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	padding-block: var(--sonipat-section-y);
	text-align: center;
}

/* GSAP animates this wrapper: scale 1 -> 0.88, opacity 1 -> 0. */
.hero-scroll-section .hero-visual {
	will-change: transform, opacity;
	max-width: var(--wp--style--global--wide-size, 1400px);
	margin-inline: auto;
	padding-inline: 1.5rem;
}

/* Decorative grid + gradient wash, pinned behind the hero copy. */
.hero-scroll-section::before {
	content: "";
	position: absolute;
	inset: -10% 0 auto;
	height: 120%;
	pointer-events: none;
	background-image:
		linear-gradient(rgba(23, 1, 44, 0.06) 1px, transparent 1px),
		linear-gradient(90deg, rgba(23, 1, 44, 0.06) 1px, transparent 1px);
	background-image:
		linear-gradient(color-mix( in srgb, var(--wp--preset--color--inverse, #17012c) 6%, transparent ) 1px, transparent 1px),
		linear-gradient(90deg, color-mix( in srgb, var(--wp--preset--color--inverse, #17012c) 6%, transparent ) 1px, transparent 1px);
	background-size: 72px 72px;
	mask-image: radial-gradient(70% 60% at 50% 35%, #000 20%, transparent 78%);
	-webkit-mask-image: radial-gradient(70% 60% at 50% 35%, #000 20%, transparent 78%);
}

/* 6.2 Stacking cards -------------------------------------------------------
   Sticky holds the deck, so nothing may clip it: an `overflow: hidden` (or a
   scroll container) ancestor silently disables sticky for the whole deck. */
.stacking-cards-container {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: clamp(1.5rem, 4vw, 3rem);
	overflow: visible;
	padding-bottom: var(--sonipat-section-y);
}

.stacking-card {
	position: sticky;
	background: linear-gradient(150deg, var(--sonipat-surface) 0%, var(--sonipat-surface-hover) 100%);
	border: 1px solid var(--sonipat-border);
	border-radius: var(--sonipat-radius);
	box-shadow: var(--sonipat-shadow);
	padding: clamp(1.75rem, 4vw, 3.25rem);
	min-height: clamp(320px, 46vh, 480px);
	display: flex;
	flex-direction: column;
	justify-content: center;
	will-change: transform, opacity;
	margin-inline: auto;   /* centres the deck in the column, pinned or not */
	width: min(100%, 980px);
	/* Deck rest line — must stay in sync with PIN_TOP / PIN_STEP in
	   assets/js/cinematic-animations.js, which reads the same numbers. */
	top: 12vh;
}

/* Each card settles 3vh lower than the one before it, so the edges of the
   cards behind stay visible. Sticky (not GSAP Pin) holds the deck: Pin would
   have to reserve flow space the deck no longer occupies, and releasing a
   pinned card snaps it back into a visible position mid-scroll. */
.stacking-card:nth-child(2) { top: 15vh; }
.stacking-card:nth-child(3) { top: 18vh; }
.stacking-card:nth-child(4) { top: 21vh; }
.stacking-card:nth-child(5) { top: 24vh; }

/* The deck's hold. A sticky card may only travel inside its container's
   content box, and neither container padding nor the card's own bottom margin
   extends that reach — both count against the containment. An in-flow tail
   does, so the hold is a generated child: it is how long the finished deck
   stays readable before it slides away. */
.stacking-cards-container::after {
	content: "";
	display: block;
	height: clamp(12rem, 34vh, 26rem);
}

.stacking-card:nth-child(even) {
	background: linear-gradient(150deg, var(--sonipat-bg-elevated) 0%, var(--sonipat-surface-hover) 100%);
	border-color: rgba(106, 71, 237, 0.18);
	border-color: color-mix( in srgb, var(--sonipat-primary) 18%, transparent );
}

.stacking-card .card-index {
	font-size: 0.8rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--sonipat-primary);
	font-weight: 600;
}

/* 6.3 Story section --------------------------------------------------------- */
.story-section {
	position: relative;
	overflow: hidden;
}

.story-section .wp-block-columns {
	align-items: center;
}

/* 6.4 Booking / lead CTA --------------------------------------------------- */
.booking-cta {
	position: relative;
	background:
		radial-gradient(120% 140% at 50% 0%, rgba(106, 71, 237, 0.22), transparent 60%),
		linear-gradient(180deg, var(--sonipat-bg-elevated), var(--sonipat-bg));
	background:
		radial-gradient(120% 140% at 50% 0%, color-mix( in srgb, var(--sonipat-primary) 22%, transparent ), transparent 60%),
		linear-gradient(180deg, var(--sonipat-bg-elevated), var(--sonipat-bg));
	border: 1px solid rgba(106, 71, 237, 0.28);
	border-color: color-mix( in srgb, var(--sonipat-primary) 28%, transparent );
	border-radius: calc(var(--sonipat-radius) + 8px);
	box-shadow: var(--sonipat-shadow-lift);
	overflow: hidden;
}

/* 6.5 Generic reveal (the JS adds `.gsap-ready` to <html> only when GSAP
   actually loaded, so nothing is hidden if the CDN is unreachable). */
html:not(.gsap-ready) .gsap-reveal {
	opacity: 1;
	transform: none;
}

.gsap-reveal {
	--gsap-reveal-y: 28px;
}

/* 6.6 Word-by-word headline reveal. The motion engine splits any heading tagged
   `h2-words` (and the front-page hero) into one mask per word, so these two rules
   live in the sheet every page loads: the class is meant to work on a block page
   as well as a builder one. Each word sits in an overflow-hidden mask so it can
   slide up from below the baseline; the negative margin buys back the space so
   descenders (g, y, p) are not clipped by the mask. */
.h2-word-mask {
	display: inline-block;
	overflow: hidden;
	vertical-align: bottom;
	padding-bottom: 0.16em;
	margin-bottom: -0.16em;
}

.h2-word {
	display: inline-block;
	will-change: transform;
}


/* ==========================================================================
   7. RESPONSIVE TWEAKS
   ========================================================================== */

@media only screen and (max-width: 960px) {

	.stacking-card {
		position: static;   /* no deck on touch/narrow: plain column of cards */
		width: 100%;
		min-height: auto;
		padding: clamp(1.5rem, 5vw, 2rem);
	}

	.stacking-cards-container::after {
		display: none;   /* nothing is sticking, so no hold space */
	}

	.hero-scroll-section {
		min-height: 82svh;
	}
}

@media only screen and (max-width: 600px) {

	:root {
		--sonipat-section-y: clamp(3rem, 12vw, 5rem);
		--sonipat-radius: 14px;
	}

	.wp-block-navigation__responsive-container.is-menu-open {
		padding-block: 5rem 3rem;
	}
}


/* ==========================================================================
   8. ACCESSIBILITY - REDUCED MOTION FALLBACK
   --------------------------------------------------------------------------
   The JS aborts before creating a single tween when this preference is set,
   but GSAP's Pin leaves wrapper divs (`.pin-spacer`), sticky rules, 3D card
   stacking and will-change layers behind that must also be neutralised so the
   page reads as a clean vertical document with no dead space or clipping.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

	/* 8.1 Kill all CSS-driven motion, transitions and smooth scrolling. */
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		animation-delay: 0s !important;
		animation-name: none !important;
		transition-duration: 0.001ms !important;
		transition-delay: 0s !important;
		transition-property: none !important;
		scroll-behavior: auto !important;
	}

	/* 8.2 Undo everything GSAP may have written inline before the preference
	   changed (or on a hard reload where the browser kept a pinned DOM). */
	[style*="transform"],
	[style*="opacity"] {
		transform: none !important;
		opacity: 1 !important;
		will-change: auto !important;
		filter: none !important;
	}

	/* A word mask is a clip, not a transform, so the rules above cannot free a
	   descender left behind by a split heading. */
	.h2-word-mask {
		overflow: visible;
	}

	/* 8.3 Flatten GSAP Pin: promote the pinned node back into the flow and
	   drop the spacer that ScrollTrigger injects around it. */
	.pin-spacer,
	.gsap-pin-spacer {
		display: contents !important;
		position: static !important;
		width: auto !important;
		height: auto !important;
		min-height: 0 !important;
		padding: 0 !important;
		margin: 0 !important;
		transform: none !important;
	}

	.hero-scroll-section,
	.hero-scroll-section .hero-visual,
	.stacking-card,
	.stacking-card .card-inner,
	.story-section,
	.booking-cta {
		position: static !important;
		top: auto !important;
		inset: auto !important;
		transform: none !important;
		scale: none !important;
		rotate: none !important;
		opacity: 1 !important;
		filter: none !important;
		will-change: auto !important;
		backface-visibility: visible !important;
	}

	/* 8.4 Sticky states -> normal flow. */
	.wp-site-blocks > .wp-block-template-part:first-child,
	.wp-site-blocks > .wp-block-template-part:has(.sonipat-header),
	.sonipat-header,
	.sonipat-header.is-scrolled {
		position: static !important;
		top: auto !important;
		box-shadow: none;
		background: var(--sonipat-bg-elevated);
	}

	/* 8.5 Card stacking -> plain vertical stack with visible separation. */
	.stacking-cards-container {
		display: block !important;
		position: static !important;
		overflow: visible !important;
		gap: 0 !important;
		padding-bottom: 0 !important;
	}

	.stacking-cards-container::after {
		display: none !important;   /* the sticky hold space is meaningless here */
	}

	.stacking-card {
		width: 100% !important;
		max-width: 100% !important;
		min-height: 0 !important;
		margin: 0 auto var(--wp--preset--spacing--m) !important;
		border-color: var(--sonipat-border-strong);
		box-shadow: var(--sonipat-shadow);
	}

	.stacking-card:last-child {
		margin-bottom: 0 !important;
	}

	/* 8.6 Hero returns to natural document height instead of 100vh. */
	.hero-scroll-section {
		min-height: 0 !important;
		height: auto !important;
		padding-block: var(--sonipat-section-y) !important;
		display: block !important;
		overflow: visible !important;
	}

	.hero-scroll-section::before {
		display: none;
	}

	/* 8.7 Never leave a reveal hidden if it was mid-tween when JS stopped. */
	.gsap-reveal,
	html:not(.gsap-ready) .gsap-reveal,
	[data-gsap-reveal] {
		opacity: 1 !important;
		transform: none !important;
		visibility: visible !important;
	}

	/* 8.7b Hero decorations go back into the document flow. */
	.hero-backdrop,
	.hero-scroll-cue {
		position: static !important;
		inset: auto !important;
		display: block !important;
		margin-top: 2rem !important;
	}

	/* 8.8 Hover "lift" is motion too - swap it for a static affordance so
	   interactive elements still communicate state. */
	.wp-block-button__link:hover,
	.is-card:hover,
	.sonipat-card:hover {
		transform: none !important;
	}

	.service-tile:hover .service-tile-mark,
	.service-tile-link a:hover::after,
	.service-tile-link a:focus-visible::after {
		transform: none !important;
		filter: none !important;
	}

	.service-detail:hover .service-detail-mark,
	.enquiry-actions .wp-element-button:hover {
		transform: none !important;
		filter: none !important;
	}

	.service-card:hover {
		transform: none !important;
	}

	/* The ticker band and the meter sweep are the two looping motions on the
	   front page; both have a usable static state. */
	.home-ticker-section .home-ticker-track {
		animation: none !important;
	}

	.home-skills-section .skill-ring.is-ringing {
		animation: none !important;
	}

	.home-team-section .team-card:hover,
	.home-insights-section .insight-card:hover {
		transform: none !important;
	}

	.wp-block-button__link:hover {
		background: var(--sonipat-primary-hover);
		border-color: var(--sonipat-primary-hover);
	}

	.is-card:hover,
	.sonipat-card:hover {
		border-color: var(--sonipat-primary);
	}

	/* 8.9 Class-based kill switch the JS adds when the preference is already
	   set (mirrors the media query for browsers that report it late). */
	html.reduced-motion .pin-spacer {
		display: contents !important;
	}

	html.reduced-motion .stacking-card,
	html.reduced-motion .hero-scroll-section .hero-visual {
		transform: none !important;
		opacity: 1 !important;
	}
}

/* Windows: honour the OS "show animations" toggle the same way. */
@media (prefers-reduced-motion: no-preference) {
	.stacking-card {
		transition: border-color var(--sonipat-duration) var(--sonipat-ease);
	}
}


/* ==========================================================================
   9. PATTERN COMPONENTS
   --------------------------------------------------------------------------
   Styles for the classes used inside /patterns and /parts. These are pure
   presentation: removing any of them leaves the content perfectly readable,
   which is the point of a block theme.
   ========================================================================== */

/* 9.1 Header internals -----------------------------------------------------
   The header and footer are laid out by the theme-mod builder; every rule for
   its rows, slots and elements lives in assets/css/header-builder.css, which
   loads after this sheet. Only the dark band itself (section 3) is styled here. */

/* 9.2 Hero ---------------------------------------------------------------- */
.hero-lede {
	max-width: 62ch;
	margin-inline: auto;
	color: var(--sonipat-text-muted);
}

.hero-proof {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: clamp(1rem, 4vw, 2.5rem);
	margin-top: clamp(2.5rem, 6vw, 4rem);
	padding-top: 1.75rem;
	border-top: 1px solid var(--sonipat-border);
}

.hero-proof p {
	margin: 0;
	color: var(--sonipat-text-faint);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.hero-scroll-cue {
	position: absolute;
	inset-inline: 0;
	bottom: clamp(1.5rem, 5vh, 3rem);
	color: var(--sonipat-text-faint);
	letter-spacing: 0.22em;
	text-transform: uppercase;
}

.hero-scroll-cue p {
	margin: 0;
}

.hero-backdrop {
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
}

/* 9.3 Section intros ------------------------------------------------------ */
.section-intro {
	margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
}

.section-intro h2 {
	margin-block: 1rem 1.25rem;
}

/* 9.4 Card internals ------------------------------------------------------ */
.card-bullets {
	padding-left: 1.15rem;
	margin-block: 1.5rem 2rem;
	color: var(--sonipat-text-muted);
}

.card-bullets li {
	margin-bottom: 0.5rem;
}

.card-bullets li::marker {
	color: var(--sonipat-primary);
}

.stacking-card h3 {
	margin-block: 0.75rem 1rem;
}

/* 9.5 Story --------------------------------------------------------------- */
.story-columns {
	gap: clamp(2rem, 6vw, 5rem);
}

.story-copy h2 {
	margin-block: 1.25rem 1.75rem;
}

.story-stats-card {
	padding: clamp(1.5rem, 4vw, 2.5rem);
}

.stats-title {
	color: var(--sonipat-text-faint);
	margin-bottom: 1.5rem;
}

.stats-grid {
	gap: 1rem;
}

.stat-number {
	margin: 0;
}

.stats-note {
	color: var(--sonipat-text-faint);
	margin: 1.25rem 0 0;
}

/* 9.6 Booking CTA --------------------------------------------------------- */
.booking-cta-inner {
	padding: clamp(2.5rem, 7vw, 5rem) clamp(1.5rem, 5vw, 4rem);
	text-align: center;
}

.booking-cta h2 {
	margin-block: 1.25rem 1.5rem;
}

.booking-cta .wp-block-buttons {
	justify-content: center;
	margin-top: 2.25rem;
}

.booking-assurances {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.65rem 1.75rem;
	margin-top: 2.5rem;
}

.booking-assurances p {
	margin: 0;
	color: var(--sonipat-text-muted);
}

.booking-assurances p::before {
	content: "✓";
	margin-right: 0.45rem;
	color: var(--sonipat-primary);
	font-weight: 700;
}

.booking-address {
	margin-top: 2.5rem;
	/* The band's faint tone measures 4.1:1 at this size; muted clears AA
	   without lifting the line above the checklist above it. */
	color: var(--sonipat-text-muted);
	letter-spacing: 0.05em;
}

/* 9.7 Archive / content templates ---------------------------------------- */
.sonipat-card-grid {
	gap: var(--sonipat-gap);
	padding: 0;
	list-style: none;
}

.post-card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.post-card .wp-block-post-featured-image {
	margin: 0;
}

.post-card-body {
	padding: clamp(1.25rem, 3vw, 1.75rem);
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	flex-grow: 1;
}

.post-card-body h3 {
	margin: 0;
}

.post-card-body .wp-block-post-excerpt {
	margin: 0;
	color: var(--sonipat-text-muted);
}

.post-card-kicker,
.single-kicker {
	font-size: 0.75rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.post-card-meta,
.single-meta {
	gap: 1rem;
	margin-top: auto;
	color: var(--sonipat-text-faint);
	font-size: 0.85rem;
}

.page-title-band,
.archive-title-band,
.search-title-band,
.single-title-band {
	background: var(--sonipat-bg-elevated);
	border-bottom: 1px solid var(--sonipat-border);
	padding-block: clamp(3rem, 8vw, 6rem);
}

.sonipat-pagination .wp-block-query-pagination-numbers a,
.sonipat-pagination .page-numbers.current {
	padding: 0.4rem 0.8rem;
	border: 1px solid var(--sonipat-border-strong);
	border-radius: 8px;
}

.sonipat-pagination .page-numbers.current {
	background: var(--sonipat-primary);
	border-color: var(--sonipat-primary);
	color: #fff;
}

.single-body .entry-content,
.single-body .wp-block-post-content {
	max-width: 74ch;
	margin-inline: auto;
}

.error-404 {
	text-align: center;
	min-height: 50vh;
}

/* 9.8 Footer --------------------------------------------------------------
   The columns, strips and elements are laid out by the builder, in
   assets/css/header-builder.css. Only this band typography stays here, so a
   footer rebuilt from blocks still looks right. */
.sonipat-footer h4 {
	margin-block: 0 1.25rem;
}

/* 9.9 Comments (single post) ---------------------------------------------- */
.sonipat-comments {
	margin-block: clamp(2.5rem, 6vw, 4rem);
	padding-block: clamp(2rem, 5vw, 3rem);
	border-top: 1px solid var(--sonipat-border);
}

.comment-row {
	gap: 1.1rem;
	padding-block: 1.25rem;
	border-bottom: 1px solid var(--sonipat-border);
}

.comment-row .wp-block-avatar img {
	border-radius: 999px;
	border: 1px solid var(--sonipat-border-strong);
}

.sonipat-comments .wp-block-comment-author-name,
.sonipat-comments .wp-block-comment-date {
	margin: 0;
	font-size: 0.85rem;
	color: var(--sonipat-text-faint);
}

.sonipat-comments .wp-block-post-comments-form input:not([type="submit"]),
.sonipat-comments .wp-block-post-comments-form textarea {
	background: var(--sonipat-surface);
	border: 1px solid var(--sonipat-border-strong);
	color: var(--sonipat-text);
	border-radius: var(--sonipat-radius-sm);
	padding: 0.7rem 0.9rem;
}

/* 9.10 Chrome-free templates --------------------------------------------- */
.sonipat-blank,
.sonipat-fullwidth {
	padding-inline: 0;
}

.sonipat-page-heading {
	padding-inline: clamp(1rem, 4vw, 2rem);
	margin-block: clamp(2.5rem, 6vw, 4rem) 0;
}

.booking-cta-wrap > .booking-cta {
	margin-inline: auto;
	max-width: var(--wp--style--global--wide-size, 1400px);
}

/* 9.11 Grow-traffic service tiles -----------------------------------------
   Four hairline-topped tiles. The marks are inline SVG data URIs applied as a
   mask rather than a background image, so the glyph takes the accent token
   (and its hover glow) instead of a hard-coded fill, and no image file ships
   with the pattern. */
.grow-traffic-intro {
	/* The eyebrow pill is an inline-flex box, so `has-text-align-center` on the
	   <p> itself only centres its text — the parent has to centre the box. */
	text-align: center;
}

.service-tiles {
	align-items: stretch;
}

.service-tile {
	position: relative;
	border-top: 1px solid var(--sonipat-border-strong);
	padding-top: clamp(1.5rem, 3vw, 2.25rem);
}

.service-tile h3 {
	margin-block: 0 0.6rem;
	font-weight: 600;
	letter-spacing: -0.01em;
}

.service-tile p:not(.service-tile-link) {
	color: var(--sonipat-text-muted);
	line-height: 1.65;
}

.service-tile-mark {
	width: 44px;
	height: 44px;
	margin-bottom: clamp(1rem, 2vw, 1.4rem);
	background-color: var(--sonipat-primary);
	-webkit-mask: var(--tile-icon) center / contain no-repeat;
	mask: var(--tile-icon) center / contain no-repeat;
	transition: filter var(--sonipat-duration) var(--sonipat-ease),
		transform var(--sonipat-duration) var(--sonipat-ease);
}

.service-tile:hover .service-tile-mark {
	transform: translateY(-3px);
	filter: drop-shadow(0 0 14px var(--sonipat-glow));
}

.service-tile-link {
	margin-block: 1rem 0;
	font-size: 0.78rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.service-tile-link a {
	color: var(--sonipat-primary);
	text-decoration: none;
}

.service-tile-link a::after {
	content: "\2192";   /* → */
	display: inline-block;
	margin-left: 0.5em;
	transition: transform var(--sonipat-duration) var(--sonipat-ease);
}

.service-tile-link a:hover,
.service-tile-link a:focus-visible {
	color: var(--sonipat-primary-hover);
	text-decoration: none;
}

.service-tile-link a:hover::after,
.service-tile-link a:focus-visible::after {
	transform: translateX(5px);
}

/* Four across is right on a desktop; a tablet gets an even 2x2 instead of
   four squeezed columns. Core only stacks below 782px.
   NB: core ships `.wp-block-columns:not(.is-not-stacked-on-mobile){flex-wrap:nowrap}
   > .wp-block-column{flex-grow:1;flex-basis:0}` with `!important` from 782px up,
   so overriding the row size means matching that selector and re-wrapping the
   container — a plain, non-important rule loses on both counts. */
@media only screen and (min-width: 782px) and (max-width: 1120px) {

	.wp-block-columns.service-tiles:not(.is-not-stacked-on-mobile) {
		flex-wrap: wrap !important;
	}

	.wp-block-columns.service-tiles:not(.is-not-stacked-on-mobile) > .wp-block-column {
		flex-grow: 0 !important;
		flex-basis: calc(50% - ( var(--sonipat-gap) / 2 )) !important;
	}
}

/* Any eyebrow label plus its tracking is wider than a phone's content column,
   so it tracks tighter rather than breaking onto two lines. */
@media only screen and (max-width: 600px) {

	.sonipat-eyebrow {
		font-size: 0.72rem;
		letter-spacing: 0.1em;
		padding-inline: 0.7rem;
	}
}


