/* ==========================================================================
   ch/drawer — frontend styles
   --------------------------------------------------------------------------
   Trigger row + native <dialog> sliding panel + ::backdrop scrim.
   - Width comes from the `--width-*` modifier (sm/md/lg/xl); panel itself
     reads `--ch-drawer-width` so individual instances can override via the
     wrapper's inline style.
   - Side modifier controls slide direction.
   - Visibility modifier (mobile / desktop) flips the dialog to inline
     `display: contents` outside its active breakpoint so InnerBlocks render
     in normal flow and the trigger button is hidden.
   - Single-at-a-time + ESC + focus trap handled by view.js. <dialog> in
     showModal() mode also handles top-layer + ESC for free; view.js
     coordinates the rest.
   ========================================================================== */

.ch-drawer {
	/* Per-instance width default (overridden by --width-*). */
	--ch-drawer-width: 480px;
	--ch-drawer-slide-distance: calc(var(--ch-drawer-width) + 40px);
	--ch-drawer-transition: 280ms cubic-bezier(0.32, 0.72, 0, 1);
}

.ch-drawer--width-sm { --ch-drawer-width: 380px; }
.ch-drawer--width-md { --ch-drawer-width: 480px; }
.ch-drawer--width-lg { --ch-drawer-width: 620px; }
.ch-drawer--width-xl { --ch-drawer-width: 760px; }

/* Trigger row — utility-button style. Inherits typography from the
   surrounding block group; consumers can recolor via CSS variables. */
.ch-drawer__trigger {
	display: inline-flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	width: 100%;
	padding: 1rem 0;
	background: transparent;
	border: 0;
	border-top: 1px solid var(--ch-drawer-divider, rgba(0, 0, 0, 0.12));
	font: inherit;
	font-weight: 600;
	color: inherit;
	text-align: left;
	cursor: pointer;
	appearance: none;
}

.ch-drawer:last-of-type .ch-drawer__trigger {
	border-bottom: 1px solid var(--ch-drawer-divider, rgba(0, 0, 0, 0.12));
}

.ch-drawer__trigger:hover,
.ch-drawer__trigger:focus-visible {
	color: var(--ch-drawer-trigger-hover, currentColor);
}

.ch-drawer__trigger:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
}

.ch-drawer__icon {
	flex: 0 0 auto;
	transition: transform 0.2s ease;
}

/* Trigger reflects open state — icon points up while drawer is open. */
.ch-drawer[data-drawer-open] .ch-drawer__icon {
	transform: rotate(180deg);
}

/* Dialog — native <dialog> styled as a side panel. The browser puts it
   in the top layer, so z-index of the rest of the page can't interfere. */
.ch-drawer__dialog {
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	color: inherit;
	max-width: 100vw;
	max-height: 100dvh;
	height: 100dvh;
	width: min(var(--ch-drawer-width), 100vw);
	overflow: visible;
	/* Anchor to one edge — `top: 0; right: 0` for right-side. */
	position: fixed;
	top: 0;
	inset-inline-end: 0;
	inset-inline-start: auto;
	/* Discrete `display` transition so the dialog can fade in via
	   @starting-style. Combined with the panel's own transform for slide. */
	transition: display var(--ch-drawer-transition) allow-discrete,
	            overlay var(--ch-drawer-transition) allow-discrete;
}

.ch-drawer--side-left .ch-drawer__dialog {
	inset-inline-start: 0;
	inset-inline-end: auto;
}

.ch-drawer__dialog::backdrop {
	background: rgba(0, 0, 0, 0.4);
	opacity: 0;
	transition: opacity var(--ch-drawer-transition),
	            display var(--ch-drawer-transition) allow-discrete,
	            overlay var(--ch-drawer-transition) allow-discrete;
}

.ch-drawer__dialog[open]::backdrop {
	opacity: 1;
}

@starting-style {
	.ch-drawer__dialog[open]::backdrop {
		opacity: 0;
	}
}

/* Panel — the actual visible card inside the dialog. Slide animation
   targets this so the dialog's positioning stays clean. */
.ch-drawer__panel {
	display: flex;
	flex-direction: column;
	height: 100%;
	background: #fff;
	color: #111;
	box-shadow: -16px 0 48px rgba(0, 0, 0, 0.18);
	transform: translateX(var(--ch-drawer-slide-distance));
	transition: transform var(--ch-drawer-transition);
	will-change: transform;
}

.ch-drawer--side-left .ch-drawer__panel {
	box-shadow: 16px 0 48px rgba(0, 0, 0, 0.18);
	transform: translateX(calc(var(--ch-drawer-slide-distance) * -1));
}

.ch-drawer__dialog[open] .ch-drawer__panel {
	transform: translateX(0);
}

@starting-style {
	.ch-drawer__dialog[open] .ch-drawer__panel {
		transform: translateX(var(--ch-drawer-slide-distance));
	}
	.ch-drawer--side-left .ch-drawer__dialog[open] .ch-drawer__panel {
		transform: translateX(calc(var(--ch-drawer-slide-distance) * -1));
	}
}

/* Header — title + close button. Sticky inside the scrollable content
   so it stays visible while users scroll long content. */
.ch-drawer__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.25rem 1.5rem;
	border-bottom: 1px solid rgba(0, 0, 0, 0.08);
	position: sticky;
	top: 0;
	background: #fff;
	z-index: 1;
}

.ch-drawer__title {
	margin: 0;
	font-size: 1.125rem;
	font-weight: 700;
	line-height: 1.3;
}

.ch-drawer__close {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	background: transparent;
	border: 0;
	border-radius: 50%;
	color: inherit;
	cursor: pointer;
	appearance: none;
}

.ch-drawer__close:hover,
.ch-drawer__close:focus-visible {
	background: rgba(0, 0, 0, 0.06);
}

.ch-drawer__close:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.ch-drawer__content {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 1.5rem;
}

/* Visibility modes — when the drawer is NOT active for the current
   breakpoint, unwrap it: hide the trigger, render the dialog as an
   inline flow container (display: contents drops <dialog> from layout,
   the panel + content drop their drawer chrome, content stacks
   normally). The native modal/escape semantics don't run because we
   never call showModal() outside the active breakpoint (view.js
   checks the matching media query). */
@media (min-width: 768px) {
	.ch-drawer--visibility-mobile .ch-drawer__trigger {
		display: none;
	}
	.ch-drawer--visibility-mobile .ch-drawer__dialog {
		display: contents;
		position: static;
		transition: none;
	}
	.ch-drawer--visibility-mobile .ch-drawer__panel {
		display: contents;
		transform: none;
		box-shadow: none;
		transition: none;
		background: transparent;
	}
	.ch-drawer--visibility-mobile .ch-drawer__header,
	.ch-drawer--visibility-mobile .ch-drawer__close {
		display: none;
	}
}

@media (max-width: 767px) {
	.ch-drawer--visibility-desktop .ch-drawer__trigger {
		display: none;
	}
	.ch-drawer--visibility-desktop .ch-drawer__dialog {
		display: contents;
		position: static;
		transition: none;
	}
	.ch-drawer--visibility-desktop .ch-drawer__panel {
		display: contents;
		transform: none;
		box-shadow: none;
		transition: none;
		background: transparent;
	}
	.ch-drawer--visibility-desktop .ch-drawer__header,
	.ch-drawer--visibility-desktop .ch-drawer__close {
		display: none;
	}
}

/* ==========================================================================
   Popup mode — centred modal instead of side-slide drawer.
   Activated by `.ch-drawer--mode-popup`. Reuses the same dialog + trigger
   + close + view.js state machine — only positioning and open animation
   differ. Width tokens (sm/md/lg/xl) are reinterpreted as MAX width.
   ========================================================================== */
.ch-drawer--mode-popup .ch-drawer__dialog {
	position: fixed;
	top: 50%;
	left: 50%;
	right: auto;
	bottom: auto;
	inset-inline-start: 50%;
	inset-inline-end: auto;
	transform-origin: center center;
	width: min(var(--ch-drawer-width), calc(100vw - 2rem));
	height: auto;
	max-height: calc(100dvh - 2rem);
	max-width: calc(100vw - 2rem);
	border-radius: var(--ch-drawer-popup-radius, 16px);
	overflow: hidden;
	background: transparent;
	/* Base = closed state. `[open]` (rule below) flips to the visible
	   state; @starting-style re-asserts the closed state for entry so
	   the first paint after showModal() animates IN. The exit direction
	   transitions naturally back to this base. */
	opacity: 0;
	transform: translate(-50%, -50%) scale(0.97);
	transition: opacity var(--ch-drawer-transition),
	            transform var(--ch-drawer-transition),
	            display var(--ch-drawer-transition) allow-discrete,
	            overlay var(--ch-drawer-transition) allow-discrete;
}

.ch-drawer--mode-popup .ch-drawer__dialog[open] {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.ch-drawer--mode-popup .ch-drawer__panel {
	/* Cancel the side-slide transform; popup animates with scale+fade
	   on the dialog itself via @starting-style below. */
	transform: none;
	transition: none;
	height: auto;
	max-height: calc(100dvh - 2rem);
	border-radius: var(--ch-drawer-popup-radius, 16px);
	box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.5);
	background: #fff;
}

@starting-style {
	.ch-drawer--mode-popup .ch-drawer__dialog[open] {
		opacity: 0;
		transform: translate(-50%, -50%) scale(0.97);
	}
}

/* Popup mode header — when hidden, the close button still needs to sit
   in the top-right corner of the panel. Use absolute positioning for
   that case so content stretches edge-to-edge below it. */
.ch-drawer--hide-header .ch-drawer__header {
	position: absolute;
	top: 0;
	right: 0;
	left: auto;
	padding: 12px;
	background: transparent;
	border-bottom: 0;
	z-index: 2;
}

.ch-drawer--hide-header .ch-drawer__content {
	padding-top: 0;
}

/* In popup mode the close button gets a subtle background so it's
   readable against any content (image, dark hero, etc.). */
.ch-drawer--mode-popup .ch-drawer__close {
	background: rgba(255, 255, 255, 0.94);
	border: 1px solid rgba(0, 0, 0, 0.08);
	width: 40px;
	height: 40px;
}

.ch-drawer--mode-popup .ch-drawer__close:hover,
.ch-drawer--mode-popup .ch-drawer__close:focus-visible {
	background: #fff;
	border-color: rgba(0, 0, 0, 0.2);
}

/* Popup ignores visibility-mobile/desktop unwrap — it's a modal in both
   modes. Restore the dialog positioning in case a visibility class is
   also present. */
@media (min-width: 768px) {
	.ch-drawer--mode-popup.ch-drawer--visibility-mobile .ch-drawer__dialog,
	.ch-drawer--mode-popup.ch-drawer--visibility-mobile .ch-drawer__panel {
		display: flex;
		position: fixed;
		transition: opacity var(--ch-drawer-transition);
		transform: none;
		background: #fff;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ch-drawer__dialog,
	.ch-drawer__panel,
	.ch-drawer__dialog::backdrop {
		transition: none;
	}
	@starting-style {
		.ch-drawer__dialog[open] .ch-drawer__panel,
		.ch-drawer__dialog[open]::backdrop {
			/* No initial-state offset — straight in. */
		}
	}
	@starting-style {
		.ch-drawer--mode-popup .ch-drawer__dialog[open] {
			opacity: 1;
			transform: none;
		}
	}
}
