/**
 * Online ordering modal — structure and entrance animation.
 *
 * The provider LOGOS deliberately live in the theme: `.cp-oo-logo--ubereats`
 * and friends are left empty here, so third-party brand marks stay out of the
 * plugin and can change without an FTP deploy. Hooks are listed at the end.
 *
 * ANIMATION NOTES — why this does not reuse the theme's classes directly:
 *
 *   `.animated` sets `animation-play-state: paused !important`, and the theme's
 *   IntersectionObserver removes it when an element scrolls into view. That
 *   observer scans at DOMContentLoaded; these tiles are built when the modal
 *   opens, long after. Nothing would ever unpause them, and because `.rise`
 *   starts at `opacity: 0` the tiles would sit permanently invisible.
 *
 *   `.wave-text` needs the theme's JS to inject `.wave-outer`/`.wave-inner`
 *   spans and toggle `.in-view`. That splitter is module-scoped — not reachable
 *   from here — so the class alone would leave the headline at `opacity: 0`.
 *   The mask reveal below reproduces it with the same 0.4s ease-out.
 *
 *   `.a2`–`.a5` only cover four steps, and Savage shows eight tiles. The
 *   stagger is done with :nth-child so it works for any count.
 *
 *   `rise` and `appear` are re-declared under a cp-oo- prefix rather than
 *   borrowed. They are three lines each, and depending on a globally-named
 *   keyframe means a theme rename leaves every tile at `opacity: 0` with
 *   nothing to indicate why.
 */

@keyframes cp-oo-rise {
	from { transform: translateY( 1rem ); }
	to   { transform: translateY( 0 ); }
}

@keyframes cp-oo-appear {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes cp-oo-panel-in {
	from { opacity: 0; transform: translateY( -1rem ); }
	to   { opacity: 1; transform: translateY( 0 ); }
}

@keyframes cp-oo-wave-in {
	from { transform: translateY( 100% ); }
	to   { transform: translateY( 0 ); }
}

/* --------------------------------------------------------------------------
   Modal shell
   -------------------------------------------------------------------------- */

.cp-oo-modal {
	position: fixed;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;

	/* Above Pro's Locations modal, which this opens on top of. The dialog is
	   appended to <body> by script precisely so this value is not trapped
	   inside another stacking context. */
	z-index: 100000;

	/* CLOSING is a single fade of the whole modal — backdrop, panel, headline
	   and tiles together. Nothing reverses.
	
	   That is why every entrance effect below is an ANIMATION with
	   `fill-mode: both`, not a transition. An animation only exists while
	   `.is-open` is on the element; when the class comes off, the rule vanishes
	   and each part reverts to its natural resting state — which is already the
	   animation's end state, so nothing jumps. Transitions would instead play
	   backwards on close, and the panel would visibly slide up while fading.
	
	   visibility rather than display, so the fade can play at all. `display:
	   none` would cut it off, which is exactly what the `hidden` attribute
	   implies — hence the script toggling a class. */
	opacity: 0;
	visibility: hidden;
	transition:
		opacity 0.3s ease-in,
		visibility 0s linear 0.3s;
}

.cp-oo-modal.is-open {
	opacity: 1;
	visibility: visible;

	/* ease-in both ways, as specified for the backdrop. The container carries
	   the backdrop's fade now, so this is where that easing lives; the panel
	   keeps its own ease-out. */
	transition:
		opacity 0.3s ease-in,
		visibility 0s linear 0s;
}

.cp-oo-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 0, 0, 0, 0.7 );
}

.cp-oo-modal__panel {
	position: relative;
	width: min( 40rem, 100% );
	max-height: 90vh;
	overflow-y: auto;
	padding: 2.5rem 2rem;
	background: #000;
	color: #fff;
	text-align: center;
}

.cp-oo-modal.is-open .cp-oo-modal__panel {
	animation: cp-oo-panel-in 0.3s ease-out 0.1s both;
}

.cp-oo-modal__close {
	position: absolute;
	top: 0.5rem;
	right: 0.5rem;
	padding: 0.5rem 0.75rem;
	font-size: 1.5rem;
	line-height: 1;
	color: inherit;
	background: none;
	border: 0;
	cursor: pointer;
}

/* --------------------------------------------------------------------------
   Headline — masked slide-up, mirroring the theme's wave-text
   -------------------------------------------------------------------------- */

.cp-oo-modal__title {
	margin: 0 0 1.75rem;
}

.cp-oo-wave-outer {
	display: inline-block;
	overflow: hidden;
	vertical-align: baseline;
}

.cp-oo-wave-inner {
	display: inline-block;
	line-height: 1.15;
	will-change: transform;
}

.cp-oo-modal.is-open .cp-oo-wave-inner {
	animation: cp-oo-wave-in 0.4s ease-out 0.25s both;
}

/* --------------------------------------------------------------------------
   Brands and tiles
   -------------------------------------------------------------------------- */

.cp-oo-brand + .cp-oo-brand {
	margin-top: 2rem;
}

.cp-oo-brand__name {
	margin: 0 0 1rem;
	font-size: 1rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.75;
}

.cp-oo-tiles {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 8.5rem, 1fr ) );
	gap: 1rem;
}

/* Four or more providers wrap to a second row rather than shrinking: Savage's
   Green Mill has four, and Maplewood's Crooked Pint has four. */
.cp-oo-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
	padding: 1.5rem 1rem;
	color: inherit;
	text-decoration: none;
	border: 1px solid rgba( 255, 255, 255, 0.25 );
}

.cp-oo-tile:hover,
.cp-oo-tile:focus-visible {
	border-color: rgba( 255, 255, 255, 0.8 );
}

.cp-oo-tile__label {
	font-weight: 700;
}

/* Reserve the logo box before the theme fills it, so tiles do not change
   height once artwork is supplied. */
.cp-oo-tile__logo {
	display: block;
	width: 100%;
	height: 3.5rem;
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
}

/* Tiles rise in once the panel has arrived. `both` supplies the hidden
   from-state during the delay, so it is never declared on the element itself —
   which means a tile reverts to fully visible the moment .is-open comes off,
   and a browser that ignores the animation shows tiles rather than blanks. */
.cp-oo-modal.is-open .cp-oo-tile {
	animation:
		cp-oo-rise 1s both,
		cp-oo-appear 0.8s both;
}

/* Stagger. Base 0.3s clears the panel's 0.1s delay plus its 0.3s travel;
   0.06s steps stay brisk across eight tiles. Counting restarts per brand
   section, so Savage's Green Mill row does not begin half a second late. */
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 1 )  { animation-delay: 0.30s, 0.30s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 2 )  { animation-delay: 0.36s, 0.36s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 3 )  { animation-delay: 0.42s, 0.42s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 4 )  { animation-delay: 0.48s, 0.48s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 5 )  { animation-delay: 0.54s, 0.54s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 6 )  { animation-delay: 0.60s, 0.60s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 7 )  { animation-delay: 0.66s, 0.66s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( 8 )  { animation-delay: 0.72s, 0.72s; }
.cp-oo-modal.is-open .cp-oo-tile:nth-child( n + 9 ) { animation-delay: 0.78s, 0.78s; }

/* Stop the page behind scrolling while the modal is open. */
.cp-oo-open,
.cp-oo-open body {
	overflow: hidden;
}

/* Honour a reduced-motion preference: everything still appears, it just
   appears rather than travels. */
@media ( prefers-reduced-motion: reduce ) {
	.cp-oo-modal.is-open .cp-oo-modal__panel,
	.cp-oo-modal.is-open .cp-oo-wave-inner,
	.cp-oo-modal.is-open .cp-oo-tile {
		animation: none;
	}

	/* The container fade stays, shortened. Cutting it entirely would make the
	   modal blink out, and a hard cut reads as a glitch rather than as calm. */
	.cp-oo-modal,
	.cp-oo-modal.is-open {
		transition:
			opacity 0.1s linear,
			visibility 0s linear 0.1s;
	}

	.cp-oo-modal.is-open {
		transition-delay: 0s, 0s;
	}
}

/* --------------------------------------------------------------------------
   Trigger button
   -------------------------------------------------------------------------- */

.cp-oo-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	cursor: pointer;
}

/* Sized in em and filled with currentColor, so the cart inherits whatever the
   theme's button rule sets for font-size and colour rather than needing a
   matching rule per button variant. */
.cp-oo-btn__icon {
	width: 1em;
	height: 1em;
	flex: 0 0 auto;
	fill: currentColor;
}

.cp-oo-btn--small .cp-oo-btn__icon {
	width: 0.9em;
	height: 0.9em;
}

/* .cp-oo-btn--normal and .cp-oo-btn--small are left to the theme: the button
   already exists in the design system (the yellow "Order Online" on a location
   card, the outlined one in the header), and restating it here would fork it. */

/* --------------------------------------------------------------------------
   THEME HOOKS — implement these in the child theme.

   .cp-oo-logo--takeout     Crooked Pint roundel
   .cp-oo-logo--ubereats    Uber wordmark
   .cp-oo-logo--doordash    DoorDash logo
   .cp-oo-logo--grubhub     Grubhub logo
   .cp-oo-logo--fooddudes   Food Dudes logo

   e.g.  .cp-oo-logo--doordash { background-image: url( … ); }

   A provider with no rule still renders a labelled tile that works — the logo
   box is simply empty. That is the intended failure mode: a missing image must
   never cost someone the ability to order.
   -------------------------------------------------------------------------- */
