/* Printeez Navigation Menu block (printeez/navigation-menu) — read-only
 * WordPress surface for the authored Phoenix Navigation CMS.
 *
 * Deliberately INDEPENDENT of the legacy custom menu block's stylesheet
 * (menu.css, `.pcb-*` selectors): distinct root class (`.ps-nav-menu`) so
 * both blocks can render on the same page without collision. Also
 * independent of the catalog embed's Printeez_CSS skin-token system. Primary
 * and secondary colors are set inline per instance; the badge tokens below
 * mirror the app's shared beige `pill--alt` treatment.
 *
 * Compatible with `printeez/header`'s mobile off-canvas nav container
 * (`.ps-header-nav`, see header.css) without depending on its internals:
 * this block shrink-wraps on desktop like any inline nav child and stacks
 * full-width on mobile: the same generic contract header.css already
 * applies to whatever it finds inside `.ps-header-nav`.
 */

.ps-nav-menu {
	--ps-nav-primary: #020912;
	--ps-nav-secondary: #6a7280;
	--ps-nav-badge-background: color-mix(in srgb, rgb(205 177 140) 15%, #ffffff);
	--ps-nav-badge-border: rgb(205 177 140);
	--ps-nav-badge-text: #020912;

	position: relative;
	display: block;
	width: 100%;
	box-sizing: border-box;
	color: var(--ps-nav-primary);
}

.ps-nav-menu *,
.ps-nav-menu *::before,
.ps-nav-menu *::after {
	box-sizing: border-box;
}

.ps-nav-menu a {
	color: inherit;
	text-decoration: none;
}

.ps-nav-menu img {
	max-width: 100%;
	height: auto;
	display: block;
}

/* Dimensionally-stable hidden shell (PRD §14: no wrong-menu flash) — the
   shell reserves height so the surrounding header doesn't jump when the
   corrective fetch swaps real content in. */
.ps-nav-menu--shell {
	min-height: 2.5rem;
}

/* Root row — the app header lays items out with gap-8 (2rem). */
.ps-nav-menu__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 3rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ps-nav-menu__item {
	position: relative;
}

.ps-nav-menu__link,
.ps-nav-menu__trigger {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.5rem 0;
	background: none;
	border: 0;
	font-size: 1rem;
	color: inherit;
	cursor: pointer;
	white-space: nowrap;
	/* Pre-set the underline color so the client-side active-trail mark only
	   toggles the (discrete) decoration line — a theme transition covering
	   anchors would otherwise animate the color from currentColor (near-black
	   primary) to secondary, flashing a black underline. */
	text-decoration-color: var(--wp--preset--color--accent-2);
}

.ps-nav-menu__link--inert {
	cursor: default;
	opacity: 0.6;
}

/* TwentyTwentyFive-family themes paint their dark button treatment onto any
   <button>/<a> on :hover/:focus/:active. The app's top-level items stay
   bare text in every state (helper ps_button), so declare each state
   explicitly — the theme must never win one. */
.ps-nav-menu .ps-nav-menu__link:hover,
.ps-nav-menu .ps-nav-menu__link:focus,
.ps-nav-menu .ps-nav-menu__link:active,
.ps-nav-menu .ps-nav-menu__trigger:hover,
.ps-nav-menu .ps-nav-menu__trigger:focus,
.ps-nav-menu .ps-nav-menu__trigger:active {
	background: transparent;
	color: var(--ps-nav-primary);
	text-decoration-line: none;
	box-shadow: none;
}

/* The one non-bare state, app parity: while its dropdown is open the
   trigger gets the quiet tan wash (aria-expanded:!bg-skin-alt/10 in
   public_site_helpers.ex). Padding is margin-compensated so the pill has
   room without shifting the row layout. */
.ps-nav-menu .ps-nav-menu__trigger {
	padding: 0.5rem;
	margin: 0 -0.5rem;
	border-radius: 0.375rem;
}


.ps-nav-menu .ps-nav-menu__trigger[aria-expanded='true'],
.ps-nav-menu .ps-nav-menu__trigger[aria-expanded='true']:hover,
.ps-nav-menu .ps-nav-menu__trigger[aria-expanded='true']:focus {
	background: color-mix(in srgb, rgb(205 177 140) 10%, transparent);
}

/* TwentyTwentyFive-family themes outline every :focus (not just
   :focus-visible) via the zero-specificity `:where(.wp-site-blocks :focus)`,
   which paints a box on every mouse click. Suppress the plain-focus outline
   here; keyboard focus keeps the :focus-visible ring below. */
.ps-nav-menu :focus:not(:focus-visible) {
	outline: none;
}

.ps-nav-menu__trigger:focus-visible,
.ps-nav-menu__link:focus-visible {
	outline: 2px solid var(--ps-nav-secondary);
	outline-offset: 2px;
}

/* Active menu trail — aria-current="page" and the ancestor classes are set
   client-side by navigation-menu-view.js via navigation-active-trail.mjs. */


.ps-nav-menu [aria-current='page'] .ps-nav-menu__label-text,
.ps-nav-menu .ps-nav-menu__link--current-ancestor .ps-nav-menu__label-text,
.ps-nav-menu .ps-nav-menu__trigger--current-ancestor > .ps-nav-menu__label-text {
	font-weight: inherit !important;
	text-decoration-line: underline;
	text-underline-offset: 6px;
	text-decoration-thickness: 2px !important;
	text-decoration-color: var(--wp--preset--color--accent-2);
}

.ps-nav-menu__icon {
	display: inline-flex;
	width: 1em;
	height: 1em;
	flex: 0 0 auto;
}

.ps-nav-menu__icon svg {
	width: 100%;
	height: 100%;
}

/* Dropdown-trigger chevron — app parity ("down" icon, size-3): points down
   on desktop, right in the mobile stacked list. */
.ps-nav-menu__chevron {
	width: 0.75em;
	height: 0.75em;
	flex: 0 0 auto;
}

/* --- Dropdown panel -------------------------------------------------------- */

/* The panel itself carries no padding — cards, dropdown link, and footer
   own their spacing, matching the app's tippy panel (tippy-p-0). overflow
   clips the footer band and card hover washes to the radius. */
.ps-nav-menu__item--dropdown > .ps-nav-menu__panel {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 20;
	width: max-content;
	max-width: calc(100vw - 2rem);
	min-width: 220px;
	margin-top: 0.5rem;
	padding: 0;
	overflow: hidden;
	background: #ffffff;
	border: 1px solid #e5e5e5;
	border-radius: 0.5rem;
	box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
}

.ps-nav-menu__item--dropdown > .ps-nav-menu__panel[hidden] {
	display: none;
}

/* Open/close animation — the app's tippy `shift-toward-extreme` for a
   bottom placement, values copied from tippy.js/animations/
   shift-toward-extreme.css and tippy's defaults (300ms show / 250ms hide,
   ease): the panel fades while sliding 20px up toward the trigger.
   `allow-discrete` + @starting-style animate across the [hidden]
   display:none toggle natively; a browser without them drops the whole
   transition shorthand and simply shows/hides instantly — exactly the
   previous behavior. Horizontal position rides the --ps-nav-shift-x
   custom property (the JS viewport clamp), so the entry/exit slide and
   the clamp compose instead of overwriting each other. Desktop only: the
   mobile stacked list renders panels statically. */
@media (min-width: 820px) {
	.ps-nav-menu__item--dropdown > .ps-nav-menu__panel {
		opacity: 1;
		transform: translateX(var(--ps-nav-shift-x, 0px));
		transition:
			opacity 0.3s ease,
			transform 0.3s ease,
			display 0.3s allow-discrete;
	}

	@starting-style {
		.ps-nav-menu__item--dropdown > .ps-nav-menu__panel {
			opacity: 0;
			transform: translateX(var(--ps-nav-shift-x, 0px)) translateY(20px);
		}
	}

	.ps-nav-menu__item--dropdown > .ps-nav-menu__panel[hidden] {
		opacity: 0;
		transform: translateX(var(--ps-nav-shift-x, 0px)) translateY(20px);
		transition-duration: 0.25s;
	}
}

.ps-nav-menu__dropdown-link {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 1rem 1rem 0.5rem;
	font-weight: 600;
}

/* Content-sized row, not a grid: the panel above has no fixed width (it
   sizes to `max-content`), so a grid's minmax() columns have nothing to
   divide — flex-row lets the row grow to fit however many cards are
   present, the same mechanism the LiveView header uses
   (dropdown_items_container_class/1 in public_site_helpers.ex: flex-col on
   mobile, sm:flex-row on desktop, each card capped at a max-width). */
.ps-nav-menu__cards {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	gap: 0;
}

/* Card row — app parity: each card max-w-64 with p-4, separated by a
   border-right instead of a gap, quiet wash on hover. */
.ps-nav-menu__card {
	display: flex;
	flex-direction: column;
	max-width: 16rem;
	padding: 1rem;
	border-right: 1px solid #e5e5e5;
	transition: background-color 0.15s ease;
}

.ps-nav-menu__card:last-child {
	border-right: 0;
}

.ps-nav-menu__card:hover,
.ps-nav-menu__card:focus {
	background: color-mix(in srgb, var(--ps-nav-secondary) 6%, transparent);
}

/* The quiet wash doubles as the loading placeholder: card images are lazy
   and only start downloading when the panel first opens, so the box shows
   this tint until the pixels arrive. */
.ps-nav-menu__card-media {
	display: block;
	overflow: hidden;
	border-radius: 0.375rem;
	margin-bottom: 1rem;
	background: color-mix(in srgb, var(--ps-nav-secondary) 8%, transparent);
}

/* App parity: card images crop to the header's max-h-64 (16rem) — with the
   16rem card and its padding, that lands the same portrait crop as the app.
   Doubled selector on purpose: it must BEAT `.ps-nav-menu img { height:
   auto }` (0,1,1), or the box has no height until the lazy image loads and
   the open panel visibly stretches when the pixels arrive. */
.ps-nav-menu .ps-nav-menu__card-image {
	width: 100%;
	height: 16rem;
	object-fit: cover;
	transition: transform 0.2s ease;
}

.ps-nav-menu__card:hover .ps-nav-menu__card-image {
	transform: scale(1.05);
}

.ps-nav-menu__card-body {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	min-width: 0;
}

.ps-nav-menu__card-title {
	font-weight: 700;
}

.ps-nav-menu__card-description {
	font-size: 0.75rem;
	color: var(--ps-nav-secondary);
}

/* "list" layout — app parity: a stacked column of plain text links
   (dropdown_card_link_class/1 for "list": muted text, no card chrome, no
   images, hover recolors and underlines). */
.ps-nav-menu__cards--list {
	flex-direction: column;
	padding: 0.25rem 0 0.75rem;
}

.ps-nav-menu__cards--list .ps-nav-menu__card {
	max-width: none;
	padding: 0.5rem 1rem;
	border-right: 0;
	border-bottom: 0;
}

.ps-nav-menu__cards--list .ps-nav-menu__card:hover,
.ps-nav-menu__cards--list .ps-nav-menu__card:focus {
	background: transparent;
	text-decoration: underline;
}

.ps-nav-menu__cards--list .ps-nav-menu__card-title {
	font-weight: 400;
	color: var(--ps-nav-secondary);
}

.ps-nav-menu__cards--list .ps-nav-menu__card:hover .ps-nav-menu__card-title,
.ps-nav-menu__cards--list .ps-nav-menu__card:focus .ps-nav-menu__card-title {
	color: var(--ps-nav-primary);
}

.ps-nav-menu__badge {
	display: inline-flex;
	align-items: center;
	margin-left: 0.375rem;
	padding: 0 0.4375rem;
	border: 1px solid var(--ps-nav-badge-border);
	border-radius: 0.25rem;
	background: var(--ps-nav-badge-background);
	color: var(--ps-nav-badge-text);
	font-size: 0.625rem;
	font-weight: 700;
	line-height: 1.125rem;
	text-transform: uppercase;
	letter-spacing: 0.025em;
	text-decoration: none;
}

/* Footer band — app parity: quiet off-white strip with its own padding
   (bg-skin-base-50 in the header). */
.ps-nav-menu__footer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem;
	padding: 1rem;
	background: #fafafa;
	border-top: 1px solid #e5e5e5;
}

.ps-nav-menu__footer-link {
	font-size: 0.8125rem;
}

/* App parity: the CTA is a helper ps_button — text-xs, tan (text-skin-alt),
   font-medium, underlined with offset-4, right-arrow icon at size-4
   (public_site_helpers.ex). Every state declared so the theme's link
   hover/focus colors never win. */
.ps-nav-menu__cta,
.ps-nav-menu .ps-nav-menu__cta:hover,
.ps-nav-menu .ps-nav-menu__cta:focus,
.ps-nav-menu .ps-nav-menu__cta:active {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
	font-size: 0.75rem;
	font-weight: 500;
	color: rgb(205 177 140);
	background: transparent;
	text-decoration-line: underline;
	text-underline-offset: 4px;
	text-decoration-color: currentColor;
}

.ps-nav-menu__cta-arrow {
	width: 1rem;
	height: 1rem;
	flex: 0 0 auto;
}

.ps-nav-menu__editor-notice {
	margin: 0;
	padding: 0.5rem 0.75rem;
	background: #fef3c7;
	border: 1px solid #f59e0b;
	border-radius: 0.375rem;
	font-size: 0.8125rem;
}

/* --- Mobile stacking (matches printeez/header's off-canvas breakpoint) --- */

@media (max-width: 819px) {
	.ps-nav-menu__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}

	/* App parity: the chevron points right in the stacked mobile list. */
	.ps-nav-menu__chevron {
		transform: rotate(-90deg);
	}

	/* The desktop pill uses margin-compensated padding; stacked full-width
	   rows must not carry the negative margins into the off-canvas panel. */
	.ps-nav-menu .ps-nav-menu__trigger {
		margin: 0;
		padding: 0.5rem 0;
	}

	.ps-nav-menu__item--dropdown > .ps-nav-menu__panel {
		position: static;
		box-shadow: none;
		border: 0;
		margin-top: 0;
		padding: 0.5rem 0 0.5rem 1rem;
		width: 100%;
		max-width: none;
		overflow: visible;
	}

	.ps-nav-menu__cards {
		flex-direction: column;
	}

	/* App parity: mobile cards are thumbnail rows — a 3.5rem image beside
	   the title — divided by a border-bottom instead of the desktop
	   border-right. */
	.ps-nav-menu__card {
		flex-direction: row;
		align-items: center;
		gap: 0.75rem;
		max-width: none;
		padding: 0.75rem;
		border-right: 0;
		border-bottom: 1px solid #e5e5e5;
	}

	.ps-nav-menu__card:last-child {
		border-bottom: 0;
	}

	.ps-nav-menu__card-media {
		width: 3.5rem;
		height: 3.5rem;
		flex: 0 0 auto;
		margin-bottom: 0;
	}

	/* Same doubled-selector reason as the desktop rule. */
	.ps-nav-menu .ps-nav-menu__card-image {
		width: 100%;
		height: 100%;
	}
}
