.heraldly-bar {
	width: 100%;
	box-sizing: border-box;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
	font-size: 14px;
}

.heraldly-position-top {
	position: relative;
	top: 0;
}

.heraldly-position-bottom {
	position: fixed;
	bottom: 0;
	left: 0;
	z-index: 99999;
}

/* Layout: three zones (left / center / right) laid out on a grid. Each
   element - the message, the countdown, the button or the signup form - is
   placed into one of the zones by its *_align setting, so any element can be
   moved without affecting the others. With everything in the center zone
   (the default) the two outer zones are empty and the content is simply
   centered, exactly as before 1.1.0. */
.heraldly-bar-inner {
	max-width: 1200px;
	margin: 0 auto;
	padding: 10px 40px;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 16px;
	position: relative;
}

.heraldly-zone {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 16px;
	min-width: 0;
}

/* Each zone is pinned to its own column, so an empty outer zone still
   holds its half of the row and a lone center zone stays centered. */
.heraldly-zone-left {
	grid-column: 1;
	justify-content: flex-start;
}

.heraldly-zone-center {
	grid-column: 2;
	justify-content: center;
}

.heraldly-zone-right {
	grid-column: 3;
	justify-content: flex-end;
}

/* Zones with nothing visible in them are marked by render_bar_html() (and
   kept up to date by the builder preview). Hiding them costs nothing on
   desktop - each zone is pinned to its column above, so the track stays -
   and on phones it avoids an empty stacked row. */
.heraldly-zone-empty {
	display: none;
}

/* When nothing sits in the center, let the outer zones share the whole
   row instead of each being capped at half of it, so a left-aligned
   message can run the full width up to a right-aligned button. */
.heraldly-bar-inner.heraldly-center-empty {
	grid-template-columns: 1fr 0 auto;
	column-gap: 8px;
}

.heraldly-bar-text {
	text-align: center;
	font-size: var(--heraldly-text-size, inherit);
}

.heraldly-zone-left .heraldly-bar-text {
	text-align: left;
}

.heraldly-zone-right .heraldly-bar-text {
	text-align: right;
}

.heraldly-text-bold {
	font-weight: 700;
}

/* Content box size - scales padding + font size together. Default is 3. */
.heraldly-box-size-1 .heraldly-bar-inner { padding-top: 4px; padding-bottom: 4px; font-size: 12px; }
.heraldly-box-size-2 .heraldly-bar-inner { padding-top: 7px; padding-bottom: 7px; font-size: 13px; }
.heraldly-box-size-3 .heraldly-bar-inner { padding-top: 10px; padding-bottom: 10px; font-size: 14px; }
.heraldly-box-size-4 .heraldly-bar-inner { padding-top: 15px; padding-bottom: 15px; font-size: 16px; }
.heraldly-box-size-5 .heraldly-bar-inner { padding-top: 22px; padding-bottom: 22px; font-size: 18px; }

/* Text box - an optional colored "chip" behind the message, independent of
   the bar's own background. */
.heraldly-text-box {
	padding: 4px 12px;
	border-radius: 4px;
	display: inline-block;
}

/* Background image style: the bar's background-image is set inline; this
   pseudo-element lays a darkening overlay on top so text stays legible
   regardless of the photo, at a strength the user controls.
   No position declaration here on purpose: .heraldly-position-top/-bottom (and
   .heraldly-bar-sticky.heraldly-position-top) already establish a positioned ancestor
   for the ::before overlay below in every case. An earlier `position:
   relative` here had the same specificity as .heraldly-position-bottom's
   `position: fixed` but came later in the cascade, so it silently won and
   broke fixed positioning on any bottom bar with an image background. */
.heraldly-has-bg-image {
	background-size: cover;
	background-position: center;
}

.heraldly-has-bg-image > .heraldly-bar-inner {
	position: relative;
	z-index: 1;
}

.heraldly-has-bg-image::before {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, var(--heraldly-overlay-opacity, 0.4));
	pointer-events: none;
}

.heraldly-slide-item {
	display: none;
}

.heraldly-slide-item.heraldly-slide-active {
	display: inline;
}

/* Rotating message styles */
.heraldly-slider-text {
	position: relative;
	overflow: hidden;
}

/* Fade (default): handled purely by the show/hide of .heraldly-slide-active above,
   with a quick opacity transition for a soft cross-fade feel. */
.heraldly-slider-style-fade .heraldly-slide-item {
	transition: opacity 0.3s ease;
}

/* Slide: the active line animates upward into place. */
.heraldly-slider-style-slide .heraldly-slide-item.heraldly-slide-active {
	animation: heraldly-slide-item-up 0.35s ease;
}

@keyframes heraldly-slide-item-up {
	from {
		transform: translateY(12px);
		opacity: 0;
	}
	to {
		transform: translateY(0);
		opacity: 1;
	}
}

/* Typewriter: characters are typed in / deleted by JS; a blinking caret gives
   the effect while it's mid-animation. */
.heraldly-slider-style-typewriter .heraldly-slide-item.heraldly-slide-active {
	display: inline;
}

.heraldly-slider-style-typewriter .heraldly-slide-item.heraldly-slide-active::after {
	content: "";
	display: inline-block;
	width: 2px;
	height: 1em;
	margin-left: 2px;
	vertical-align: -0.15em;
	background: currentColor;
	animation: heraldly-caret-blink 0.9s step-end infinite;
}

@keyframes heraldly-caret-blink {
	0%,
	100% {
		opacity: 1;
	}
	50% {
		opacity: 0;
	}
}

/* Entrance animations - play once when the bar is mounted on the page. */
@keyframes heraldly-enter-slide-down-anim {
	from {
		transform: translateY(-100%);
	}
	to {
		transform: translateY(0);
	}
}

@keyframes heraldly-enter-slide-up-anim {
	from {
		transform: translateY(100%);
	}
	to {
		transform: translateY(0);
	}
}

@keyframes heraldly-enter-fade-anim {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes heraldly-enter-bounce-anim {
	0% {
		transform: translateY(-30px);
		opacity: 0;
	}
	60% {
		transform: translateY(6px);
		opacity: 1;
	}
	100% {
		transform: translateY(0);
	}
}

.heraldly-enter-slide-down {
	animation: heraldly-enter-slide-down-anim 0.4s ease;
}

.heraldly-enter-slide-up {
	animation: heraldly-enter-slide-up-anim 0.4s ease;
}

.heraldly-enter-fade {
	animation: heraldly-enter-fade-anim 0.4s ease;
}

.heraldly-enter-bounce {
	animation: heraldly-enter-bounce-anim 0.6s ease;
}

/* Attention grabbers - loop gently, with a pause built into the keyframe so
   it doesn't distract constantly. Applied to the button so the bar itself
   stays readable. */
@keyframes heraldly-attn-pulse-anim {
	0%,
	70%,
	100% {
		transform: scale(1);
	}
	80% {
		transform: scale(1.12);
	}
	90% {
		transform: scale(0.98);
	}
}

@keyframes heraldly-attn-shake-anim {
	0%,
	100% {
		transform: translateX(0);
	}
	2% {
		transform: translateX(-4px);
	}
	4% {
		transform: translateX(4px);
	}
	6% {
		transform: translateX(-4px);
	}
	8% {
		transform: translateX(4px);
	}
	10% {
		transform: translateX(0);
	}
}

.heraldly-attn-pulse .heraldly-bar-button,
.heraldly-attn-pulse .heraldly-lead-submit {
	animation: heraldly-attn-pulse-anim 2.5s ease-in-out infinite;
	/* Needed so transform applies to <button> and <a> alike in every theme. */
	display: inline-block;
	will-change: transform;
}

.heraldly-attn-shake .heraldly-bar-button,
.heraldly-attn-shake .heraldly-lead-submit {
	animation: heraldly-attn-shake-anim 4s ease-in-out infinite;
	display: inline-block;
	will-change: transform;
}

.heraldly-bar-button {
	display: inline-block;
	padding: var(--heraldly-btn-pad-v, 8px) var(--heraldly-btn-pad-h, 18px);
	font-size: var(--heraldly-btn-size, inherit);
	border-radius: 4px;
	background: rgba(255, 255, 255, 0.18);
	text-decoration: none;
	color: inherit;
	font-weight: 600;
	white-space: nowrap;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.heraldly-bar-close {
	position: absolute;
	right: 10px;
	top: 50%;
	transform: translateY(-50%);
	background: transparent;
	border: none;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	color: inherit;
	opacity: 0.75;
}

.heraldly-bar-close:hover {
	opacity: 1;
}

.heraldly-lead-form {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
}

/* Fields + button stay on one line wherever there's room: each input grows/
   shrinks to share the available space instead of using the browser's
   default ~20-character width, which is what used to force early wrapping. */
.heraldly-lead-form input {
	padding: 6px 10px;
	border-radius: var(--heraldly-lead-radius, 4px);
	border: none;
	font-size: var(--heraldly-lead-size, 13px);
	flex: 1 1 130px;
	min-width: 90px;
	max-width: 220px;
	width: auto;
	box-sizing: border-box;
}

.heraldly-lead-form .heraldly-lead-email {
	flex-basis: 170px;
	max-width: 260px;
}

.heraldly-lead-submit {
	padding: var(--heraldly-btn-pad-v, 7px) var(--heraldly-btn-pad-h, 16px);
	border-radius: var(--heraldly-lead-radius, 4px);
	font-size: var(--heraldly-lead-size, inherit);
	border: none;
	background: rgba(255, 255, 255, 0.25);
	color: inherit;
	font-weight: 600;
	cursor: pointer;
	white-space: nowrap;
	flex: 0 0 auto;
	transition: background-color 0.15s ease, color 0.15s ease;
}

/* Hover colors (opt-in per bar, "Customize colors on hover" under Button).
   Set as CSS custom properties inline on the bar wrapper by
   Heraldly_Helpers::render_bar_html() - same technique as --heraldly-overlay-opacity
   above - so one rule covers both the button and the signup button, only one
   of which is ever actually on screen at a time. */
.heraldly-btn-hover-on .heraldly-bar-button:hover,
.heraldly-btn-hover-on .heraldly-lead-submit:hover {
	background: var(--heraldly-btn-hover-bg);
	color: var(--heraldly-btn-hover-color);
}

@media (max-width: 560px) {
	.heraldly-lead-form input {
		flex-basis: 100%;
		max-width: 100%;
	}

	/* On narrow screens the three zones stack, each keeping its own
	   alignment, instead of fighting for one row. */
	.heraldly-bar-inner,
	.heraldly-bar-inner.heraldly-center-empty {
		grid-template-columns: 1fr;
		gap: 10px;
	}

	.heraldly-zone-left,
	.heraldly-zone-center,
	.heraldly-zone-right {
		grid-column: 1;
	}
}

.heraldly-lead-success {
	font-weight: 600;
}

/* Countdown timer. The digit size is a custom property so the user can
   scale the whole countdown (labels follow in em) without touching the
   bar; it defaults to 16px, the pre-1.1.0 size. */
.heraldly-countdown {
	display: flex;
	gap: 10px;
	font-size: var(--heraldly-cd-size, 16px);
}

.heraldly-cd-block {
	display: flex;
	flex-direction: column;
	align-items: center;
	line-height: 1.1;
	min-width: 2.1em;
}

.heraldly-cd-num {
	font-size: 1em;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.heraldly-cd-label {
	font-size: 0.6em;
	text-transform: uppercase;
	opacity: 0.75;
}

.heraldly-cd-labels-none .heraldly-cd-label {
	display: none;
}

.heraldly-cd-labels-long .heraldly-cd-label {
	font-size: 0.5em;
	letter-spacing: 0.04em;
}

/* Countdown boxes: each unit in its own colored, rounded box. Colors,
   radius and border color come from custom properties set inline on the
   bar wrapper by Heraldly_Helpers::layout_css_vars(). */
.heraldly-cd-box-on .heraldly-cd-block {
	background: var(--heraldly-cd-bg, #fff);
	color: var(--heraldly-cd-color, #222);
	border-radius: var(--heraldly-cd-radius, 6px);
	padding: 0.3em 0.45em;
	min-width: 2.6em;
	box-sizing: border-box;
}

.heraldly-cd-box-on .heraldly-cd-label {
	opacity: 0.85;
}

.heraldly-cd-box-on.heraldly-cd-border-on .heraldly-cd-block {
	border: 2px solid var(--heraldly-cd-border-color, #fff);
}

/* Sticky notification bar - when the sticky option is on, top bars stay
   pinned to the top of the viewport instead of scrolling away. Bottom bars
   are already fixed to the bottom edge, so they need nothing here.
   frontend.js pads <body> by the combined height of all sticky bars so page
   content doesn't slide underneath them.
   The `top` values below are only a pre-JS fallback for the brief moment
   before updateStickyBarOffset() runs (or if JS fails to load). Once it
   runs, each .heraldly-bar-sticky gets its own inline `top` - the sum of the
   sticky bars above it - so multiple sticky top bars stack instead of
   overlapping; that inline style always wins over these rules regardless of
   admin-bar state. Do not treat `top: 0` here as authoritative. */
.heraldly-bar-sticky.heraldly-position-top {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 99999;
}

/* When the WP admin toolbar is present (logged-in visitor) it's already fixed
   to the very top of the viewport - without this offset the sticky bar would
   tuck underneath it and look broken while testing. Pre-JS fallback only -
   see the comment above. */
body.admin-bar .heraldly-bar-sticky.heraldly-position-top {
	top: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar .heraldly-bar-sticky.heraldly-position-top {
		top: 46px;
	}
}

@media (max-width: 782px) {
	.heraldly-bar-inner {
		padding: 10px 16px;
	}

	.heraldly-hide-mobile {
		display: none !important;
	}
}

@media (min-width: 783px) {
	.heraldly-hide-desktop {
		display: none !important;
	}
}

/* Lead-form honeypot: kept in the DOM for bots, hidden from people and
   assistive tech. Positioned off-screen rather than display:none, since some
   bots skip display:none fields. */
.heraldly-lead-form .heraldly-lead-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px !important;
	height: 1px !important;
	opacity: 0 !important;
	pointer-events: none !important;
}
