/* ==========================================================================
   Brandroot Motion — animation support styles
   --------------------------------------------------------------------------
   Only three kinds of rule live here:
     1. Pre-intro states for the hero while html.br-motion-pending is set.
        That class is added by a tiny head script and ALWAYS removed — by the
        engine as soon as GSAP has taken over, or by a 2.5 s failsafe — so
        content can never stay hidden. It is never added in the Elementor
        editor, with reduced motion, or when JavaScript is off.
     2. Visual layers created by JavaScript (cursor, project preview).
     3. Reduced-motion overrides.
   Everything else is animated by GSAP with transform/opacity only.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · Hero pre-intro (prevents a flash of un-animated headline on load)
   -------------------------------------------------------------------------- */
html.br-motion-pending .br-hero-media {
	transform: scale(1.12);
}

html.br-motion-pending :is(.br-hero-title, .br-hero-eyebrow, .br-hero-copy, .br-hero-cta, .br-hero-cue),
html.br-motion-pending body:has(.br-hero) .br-header {
	opacity: 0;
}

/* --------------------------------------------------------------------------
   SplitText helpers
   -------------------------------------------------------------------------- */
.br-split-line {
	/* Masked lines keep descenders (g, y, p) inside the mask. */
	padding-bottom: 0.08em;
	margin-bottom: -0.08em;
}

.br-split-word,
.br-split-char {
	display: inline-block;
}

/* Scroll-brightening statements: GSAP sets word opacity; keep wrapping natural. */
.br-word-reveal .br-split-word {
	will-change: auto;
}

/* --------------------------------------------------------------------------
   2 · Custom cursor (fine pointers only; created by cursor.js)
   -------------------------------------------------------------------------- */
.br-cursor {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 9999;
	width: 0;
	height: 0;
	pointer-events: none;
	opacity: 0;
	color: var(--br-on-dark, #eeede8);
}

.br-cursor__ring {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	transform: translate(-50%, -50%);
	/* Invert against whatever sits beneath, so the dot reads on light and dark sections. */
	mix-blend-mode: difference;
	background-color: #fff;
	transition:
		width 0.35s var(--br-ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
		height 0.35s var(--br-ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
		background-color 0.35s ease,
		opacity 0.25s ease;
}

.br-cursor__label {
	position: absolute;
	top: 0;
	left: 0;
	transform: translate(-50%, -50%) scale(0.6);
	opacity: 0;
	font-family: var(--br-font-body, inherit);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--br-on-dark, #eeede8);
	transition:
		opacity 0.25s ease,
		transform 0.4s var(--br-ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Links and buttons: the dot grows into a soft outline. Native cursor stays. */
.br-cursor.is-link .br-cursor__ring {
	width: 44px;
	height: 44px;
	background-color: rgba(255, 255, 255, 0.18);
}

/* View / Drag zones: labelled disc. */
.br-cursor.is-label .br-cursor__ring {
	width: 88px;
	height: 88px;
	mix-blend-mode: normal;
	background-color: var(--br-accent, #34514a);
}

.br-cursor.is-label .br-cursor__label {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.br-cursor.is-pressed .br-cursor__ring {
	width: 8px;
	height: 8px;
}

.br-cursor.is-label.is-pressed .br-cursor__ring {
	width: 76px;
	height: 76px;
}

.br-cursor.is-hidden .br-cursor__ring,
.br-cursor.is-hidden .br-cursor__label {
	opacity: 0;
}

/* The native cursor is only replaced where the labelled disc is shown (or site-wide if opted in).
   Text fields, iframes and form controls always keep the native cursor. */
html.br-has-cursor :is([data-cursor], .br-compare, .br-project-card, .br-service-card, .br-hover-image),
html.br-has-cursor :is([data-cursor], .br-compare, .br-project-card, .br-service-card, .br-hover-image) :is(a, button, .elementor-button),
html.br-hide-native-cursor,
html.br-hide-native-cursor :is(a, button, .elementor-button, [role="button"]) {
	cursor: none;
}

html.br-has-cursor :is(input, textarea, select, iframe, [contenteditable="true"]) {
	cursor: auto;
}

/* --------------------------------------------------------------------------
   Project category preview (created by cursor.js for .br-project-link rows)
   -------------------------------------------------------------------------- */
.br-project-preview {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 950;
	width: clamp(240px, 22vw, 360px);
	aspect-ratio: 4 / 5;
	pointer-events: none;
	visibility: hidden;
	opacity: 0;
}

.br-project-preview__frame {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	border-radius: var(--br-radius-sm, 2px);
	background: var(--br-surface, #f6f5f2);
	box-shadow: 0 30px 60px -30px rgba(21, 24, 22, 0.45);
}

.br-project-preview__frame img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	opacity: 0;
}

/* While a preview is active, dim the rows that are not hovered. */
.br-project-list.has-preview:hover .br-project-link {
	opacity: 0.38;
}

.br-project-list.has-preview:hover .br-project-link:hover,
.br-project-list.has-preview:hover .br-project-link:focus-within {
	opacity: 1;
}

.br-project-list .br-project-link {
	transition: opacity 0.4s ease;
}

/* --------------------------------------------------------------------------
   Magnetic buttons: GSAP owns transform, so CSS must not transition it.
   -------------------------------------------------------------------------- */
.br-magnetic .elementor-button,
.elementor-button.br-magnetic {
	transition-property: background-color, color, border-color, box-shadow, opacity;
}

.br-magnetic .elementor-button-content-wrapper {
	display: inline-flex;
}

/* --------------------------------------------------------------------------
   Pinned sections: avoid a flash of mis-sized pin spacers during refresh.
   -------------------------------------------------------------------------- */
/* Elementor containers are flex columns: a shrinkable spacer would swallow the pin distance. */
.pin-spacer {
	flex-shrink: 0 !important;
}

.pin-spacer:has(> .br-services),
.pin-spacer:has(> .br-story),
.pin-spacer:has(> .br-expand) {
	overflow: visible;
}

/* --------------------------------------------------------------------------
   Debug (BR_MOTION_DEBUG): ScrollTrigger markers above the header.
   -------------------------------------------------------------------------- */
html.br-debug [class^="gsap-marker"],
html.br-debug [class*=" gsap-marker"] {
	z-index: 100000 !important;
}

/* --------------------------------------------------------------------------
   3 · Reduced motion: nothing moves, nothing waits, nothing is hidden.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	html.br-motion-pending .br-hero-media {
		transform: none;
	}

	html.br-motion-pending :is(.br-hero-title, .br-hero-eyebrow, .br-hero-copy, .br-hero-cta, .br-hero-cue),
	html.br-motion-pending body:has(.br-hero) .br-header {
		opacity: 1;
	}

	.br-cursor,
	.br-project-preview {
		display: none !important;
	}

	html.br-has-cursor *,
	html.br-hide-native-cursor * {
		cursor: revert !important;
	}

	.br-hero-cue .elementor-button-icon,
	.br-hero-cue .elementor-icon {
		animation: none !important;
	}

	.br-project-list .br-project-link,
	.br-cursor__ring,
	.br-cursor__label {
		transition: none !important;
	}
}

html.br-reduced .br-hero-cue .elementor-button-icon,
html.br-reduced .br-hero-cue .elementor-icon {
	animation: none;
}

/* Touch / coarse pointers never get cursor layers, even on hybrid devices. */
@media (hover: none), (pointer: coarse) {
	.br-cursor,
	.br-project-preview {
		display: none !important;
	}
}
