/* ---------------------------------------------------------------------------
 * Keyboard access for the site chrome.
 *
 * This file exists because of load order, not tidiness. Every one of the
 * fifteen page stylesheets carries its own copy of the .dropdown-menu rules and
 * is enqueued after style.css, so the same rule written in style.css is
 * overridden on every page of the site. This one is enqueued last, after the
 * page stylesheet and after mobile.css, so it is the final word.
 *
 * Paired with assets/js/a11y.js, which adds the Escape behaviour.
 * ------------------------------------------------------------------------ */

/*
 * Hover opens the dropdown for a mouse; :focus-within does the same job for a
 * keyboard. Without it the submenu stays visibility:hidden, which takes its
 * links out of the tab order entirely -- and "News" is href="#", so Blog and
 * Recent Updates had no keyboard route into them at all.
 */
.desktop-nav > li:focus-within .dropdown-menu {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) translateY(0);
	/*
	 * .dropdown-menu transitions `all`, which includes visibility, and Chromium
	 * does not flip it until ~120ms in. A submenu that is still
	 * visibility:hidden cannot take focus, so a quick Tab lands past it. Taking
	 * visibility out of the transition list makes it flip at once; opacity and
	 * transform still animate exactly as they do on hover, so this looks
	 * identical.
	 */
	transition: opacity 0.3s cubic-bezier(0.165, 0.84, 0.44, 1),
		transform 0.3s cubic-bezier(0.165, 0.84, 0.44, 1);
}

/*
 * The submenu becoming visible is not enough on its own: every `a` on the site
 * is given `transition: all 0.4s`, so a link inside it transitions its
 * *inherited* visibility as well and computes `hidden` for the first frame or
 * two. A link that is visibility:hidden cannot take focus, so a Tab pressed
 * straight after focusing the parent lands past the whole submenu. Measured:
 * with the menu already reading `visible`, the link still read `hidden`.
 *
 * Restricting the property list makes visibility apply at once. The hover fade
 * is unchanged: these four are the only properties .dropdown-menu a:hover
 * actually changes, and the duration and easing still come from the `a` rule.
 */
.desktop-nav .dropdown-menu a {
	transition-property: color, background-color, border-left-color, padding-left;
}

/*
 * Escape dismisses an open dropdown while focus is still inside it
 * (WCAG 1.4.13 Dismissible). Must come after the rule above to win at equal
 * specificity. a11y.js removes the class as soon as focus leaves the item.
 */
.desktop-nav > li.nav-dropdown-dismissed .dropdown-menu {
	opacity: 0;
	visibility: hidden;
	transform: translateX(-50%) translateY(15px);
}

/* ---------------------------------------------------------------------------
 * Pause/resume control for motion that starts on its own (THR-004, THR-006).
 *
 * One button, three placements. Deliberately quiet: it sits at low opacity
 * over the component it controls and comes to full strength on hover, focus
 * or once paused, so it reads as part of the furniture rather than a new
 * design element on pages the client has already approved.
 *
 * Sizing: 40px. WCAG 2.2 Target Size (Minimum) asks for 24x24, so this clears
 * it with room to spare and is comfortable on a phone without being large
 * enough to compete with the content.
 *
 * Colours come from the theme tokens rather than new values, and the control
 * carries its own contrast: white glyph on a dark translucent disc, which
 * holds up over both the video and the photography behind the sliders.
 * ------------------------------------------------------------------------ */
.th-motion-toggle {
	position: absolute;
	z-index: 5;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.45);
	border-radius: 50%;
	background: rgba(44, 62, 80, 0.55);	/* --primary-blue, translucent */
	color: var(--white, #fff);
	cursor: pointer;
	opacity: 0.55;
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
	transition: opacity 0.25s ease, background-color 0.25s ease,
		border-color 0.25s ease;
}

.th-motion-toggle svg {
	display: block;
	fill: currentColor;
	pointer-events: none;	/* clicks always land on the button itself */
}

.th-motion-toggle:hover,
.th-motion-toggle:focus-visible {
	opacity: 1;
	background: rgba(44, 62, 80, 0.85);
	border-color: rgba(255, 255, 255, 0.85);
}

/* Paused is a state worth seeing at a glance, not only hearing. */
.th-motion-toggle[data-state="paused"] {
	opacity: 1;
	background: rgba(44, 62, 80, 0.9);
	border-color: var(--accent-blue-warm, #9CB6D5);
}

/*
 * A visible focus ring that survives the dark translucent background. The
 * theme's default outline is the same blue as the disc, which disappears
 * against it, so this one is white with an outer ring for contrast either way.
 */
.th-motion-toggle:focus-visible {
	outline: 2px solid var(--white, #fff);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px rgba(44, 62, 80, 0.75);
}

/* Placements. Each parent is already positioned by its own page stylesheet. */
.th-motion-toggle--hero {
	right: 24px;
	bottom: 24px;
}

.th-motion-toggle--carousel {
	right: 16px;
	bottom: 16px;
}

/*
 * The slider control goes top-right, not bottom-right. Its three neighbours
 * occupy the other corners: `.slide .caption` is a full-width gradient with
 * text along the bottom edge, `.slider-dots` is centred on the bottom, and
 * `.slider-btn` prev/next are vertically centred at the left and right edges.
 * Top-right is the only corner where a 40px disc collides with none of them.
 */
.th-motion-toggle--slider {
	right: 16px;
	top: 16px;
}

/*
 * The Experience slider already has two round controls of its own -- the
 * prev/next arrows are white discs with a dark glyph -- so the pause control
 * borrows that treatment rather than introducing a second button language on
 * the same component. It stays smaller and quieter than the arrows (40px
 * against 48px, and translucent until hovered) because it is the secondary
 * control of the three.
 */
.th-motion-toggle--slider {
	background: rgba(255, 255, 255, 0.82);
	border-color: rgba(255, 255, 255, 0.9);
	color: var(--primary-blue, #2C3E50);
}

.th-motion-toggle--slider:hover,
.th-motion-toggle--slider:focus-visible,
.th-motion-toggle--slider[data-state="paused"] {
	background: #fff;
	border-color: #fff;
	color: var(--primary-blue, #2C3E50);
}

.th-motion-toggle--slider:focus-visible {
	outline-color: var(--primary-blue, #2C3E50);
	box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.9);
}

@media (max-width: 767px) {
	.th-motion-toggle {
		width: 38px;
		height: 38px;
	}

	.th-motion-toggle--hero {
		right: 14px;
		bottom: 76px;	/* clear of the fixed call bar on phones */
	}

	.th-motion-toggle--carousel {
		right: 10px;
		bottom: 10px;
	}

	.th-motion-toggle--slider {
		right: 10px;
		top: 10px;
	}
}

/*
 * No control is rendered under reduced motion -- motionToggle() returns before
 * creating it, because nothing auto-starts. This rule is a backstop for a
 * control left in the markup by some future change.
 */
@media (prefers-reduced-motion: reduce) {
	.th-motion-toggle {
		transition: none;
	}
}

/* ---------------------------------------------------------------------------
 * THR-015 — decorative animation that never stopped.
 *
 * WCAG 2.2.2 Pause, Stop, Hide: motion that starts automatically, lasts more
 * than five seconds and runs alongside other content needs a way to stop it.
 * Two decorative animations ran `infinite`, so they never stopped at all:
 *
 *   .scroll-down-indicator svg   bounceArrow 2.2s infinite  — on FIVE page
 *     stylesheets (home-tharros, contact-us, locations, about-us, teras-house),
 *     not the one the review named.
 *   .loc-hero .badge .pulse      pulse 2s infinite          — nashville.
 *
 * `prefers-reduced-motion` is the right thing to honour but does not satisfy
 * 2.2.2 on its own: it only helps people who have found and set that setting.
 *
 * Fixed by letting the animation finish rather than by adding a third pause
 * button. Two buttons for genuinely useful motion is reasonable; a button to
 * stop a 20px arrow is clutter, and the brief asked not to add more.
 *
 * THE APPEARANCE DOES NOT CHANGE. That is not an assumption, it is a property
 * of these two keyframe sets:
 *
 *   bounceArrow  0%,100% { translateY(0) }  50% { translateY(-12px) }
 *   pulse        0% { 0 0 0 0 } 70% { spread 10px, alpha 0 } 100% { 0 0 0 0 }
 *
 * Both end exactly where the un-animated element sits — the arrow at
 * translateY(0), the dot with a zero-offset zero-spread shadow that paints
 * nothing. So once the animation stops, every pixel is identical to the
 * static styling. The only difference is that the motion ends.
 *
 * Timing, all finishing inside five seconds measured from page load:
 *
 *   arrow  the parent fades in with `fadeInScroll 1s 2.5s forwards`, so the
 *          bounce is matched to that delay and runs ONE cycle, 2.5s → 4.7s.
 *          Without the delay a capped bounce would be mostly over before the
 *          arrow became visible, which would change what a visitor sees far
 *          more than stopping it does.
 *   dot    visible from load, so two cycles, 0s → 4.0s.
 *
 * These selectors are written here rather than in the six page stylesheets
 * because a11y.css is enqueued last precisely so it wins at equal specificity,
 * and one rule is easier to keep true than six copies.
 * ------------------------------------------------------------------------ */
.scroll-down-indicator svg {
	animation-delay: 2.5s;
	animation-iteration-count: 1;
}

.loc-hero .badge .pulse {
	animation-iteration-count: 2;
}

/*
 * And no decorative motion at all for anyone who has asked for reduced
 * motion. nashville.css already did this for the pulse; the scroll indicator
 * had no reduced-motion handling on any of its five pages.
 */
@media (prefers-reduced-motion: reduce) {
	.scroll-down-indicator svg,
	.loc-hero .badge .pulse {
		animation: none;
	}
}
