/*
 * photoinbox — one stylesheet, vendored, no build step and no external requests.
 *
 * Mobile first: most guests arrive on a phone from a link in a message. Every rule here
 * is written for 390px and widened at 640px, not the other way round.
 */

:root {
	--ink: #241f1c;
	--ink-soft: #5c534d;
	--paper: #fbf7f2;
	--card: #ffffff;
	--accent: #8c2f39;
	--accent-ink: #ffffff;
	--ok: #2f6b4f;
	--error: #a12c2c;
	--line: #e6ded4;
	--radius: 14px;
}

* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
	padding: 0;
}

body.page {
	background: var(--paper);
	color: var(--ink);
	font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	min-height: 100vh;
	padding: 24px 16px 48px;
	overflow-x: hidden;
}

.card {
	background: var(--card);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	margin: 0 auto;
	max-width: 34rem;
	padding: 24px 20px;
}

.card__title {
	font-size: 1.6rem;
	line-height: 1.2;
	margin: 0 0 8px;
}

.card__lead {
	color: var(--ink-soft);
	margin: 0 0 16px;
}

.card__date {
	color: var(--ink-soft);
	font-variant-numeric: tabular-nums;
	margin: 0 0 16px;
}

.notice {
	background: #f6f1ea;
	border-left: 4px solid var(--line);
	border-radius: 6px;
	margin: 0 0 20px;
	padding: 12px 14px;
}

.notice--error {
	background: #fbeceb;
	border-left-color: var(--error);
	color: var(--error);
}

.notice--ok {
	background: #eef5f0;
	border-left-color: var(--ok);
	color: var(--ok);
}

.gate-form {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.gate-form__label {
	font-weight: 600;
}

.gate-form__input {
	border: 1px solid var(--line);
	border-radius: 8px;
	font: inherit;
	/* 16px keeps iOS from zooming the viewport when the field is focused. */
	font-size: 16px;
	min-height: 48px;
	padding: 10px 12px;
	width: 100%;
}

.gate-form__input:focus-visible,
.button:focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: 2px;
}

.button {
	background: var(--accent);
	border: 0;
	border-radius: 8px;
	color: var(--accent-ink);
	cursor: pointer;
	font: inherit;
	font-weight: 600;
	/* 44px is the smallest comfortable touch target; this clears it. */
	min-height: 48px;
	padding: 12px 18px;
	width: 100%;
}

.button--ghost {
	background: transparent;
	border: 1px solid var(--accent);
	color: var(--accent);
}

/*
 * The uploader (B2). Mobile first, and every row is a flex line whose text child carries
 * `min-width: 0` — without it a 300-character filename makes the whole page scroll
 * sideways on a phone, which is the classic way this layout breaks.
 */

.visually-hidden {
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

.uploader {
	margin-top: 8px;
}

.uploader__heading {
	font-size: 1.1rem;
	margin: 0 0 12px;
}

.uploader__zone {
	background: #fdfbf8;
	border: 2px dashed var(--line);
	border-radius: var(--radius);
	padding: 20px 16px;
	text-align: center;
	transition: border-color 120ms ease, background-color 120ms ease;
}

.uploader__zone.is-dragging {
	background: #f4ece3;
	border-color: var(--accent);
}

.uploader__hint {
	color: var(--ink-soft);
	margin: 0 0 14px;
}

.uploader__actions {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.uploader__types {
	color: var(--ink-soft);
	font-size: 0.85rem;
	margin: 14px 0 0;
}

.queue {
	margin-top: 10px;
}

.queue-dock {
	position: sticky;
	bottom: 16px;
	background: var(--card);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 16px;
	margin-top: 20px;
	box-shadow: 0 4px 12px rgba(0,0,0,0.08);
	z-index: 10;
}

.queue-dock__progress {
	display: flex;
	align-items: center;
	gap: 12px;
}

.queue-dock__toggle {
	flex: none;
	min-height: 24px;
	min-width: 24px;
	padding: 4px 8px;
	font-size: 0.85rem;
}

.queue-dock__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-top: 12px;
}

.queue-dock__chip {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: #ece5dc;
}

.queue-dock__chip[data-state="uploading"] {
	background: var(--accent);
}

.queue-dock__chip[data-state="processing"] {
	background: var(--accent);
	opacity: 0.7;
}

.queue-dock__chip[data-state="done"] {
	background: var(--ok);
}

.queue-dock__chip[data-state="failed"] {
	background: var(--error);
}

.queue__summary-text {
	font-weight: 600;
	margin: 0 0 8px;
	overflow-wrap: anywhere;
}

.progress {
	background: #ece5dc;
	border-radius: 999px;
	height: 8px;
	overflow: hidden;
	width: 100%;
}

.progress--total {
	height: 12px;
}

.progress__fill {
	background: var(--accent);
	display: block;
	height: 100%;
	transition: width 120ms linear;
	width: 0;
}

/* No width to animate, so the movement has to come from the background. */
.progress--indeterminate .progress__fill {
	background-image: linear-gradient(90deg, var(--line) 25%, var(--accent) 50%, var(--line) 75%);
	background-size: 200% 100%;
	animation: pi-indeterminate 1.2s linear infinite;
}

@keyframes pi-indeterminate {
	from {
		background-position: 100% 0;
	}

	to {
		background-position: -100% 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.progress__fill {
		transition: none;
	}

	.progress--indeterminate .progress__fill {
		animation: none;
	}
}

.queue__list {
	list-style: none;
	margin: 16px 0 0;
	padding: 0;
}

.queue-item {
	border-top: 1px solid var(--line);
	padding: 12px 0;
}

.queue-item__head,
.queue-item__foot {
	align-items: baseline;
	display: flex;
	gap: 10px;
	justify-content: space-between;
}

.queue-item__foot {
	margin-top: 6px;
}

.queue-item__name {
	/* The three rules that keep a guest-chosen filename from widening the page. */
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.queue-item__size {
	color: var(--ink-soft);
	flex: none;
	font-size: 0.85rem;
	font-variant-numeric: tabular-nums;
}

.queue-item__state {
	color: var(--ink-soft);
	font-size: 0.85rem;
	min-width: 0;
	overflow-wrap: anywhere;
}

.queue-item[data-state="done"] .queue-item__state {
	color: var(--ok);
}

.queue-item[data-state="failed"] .queue-item__state {
	color: var(--error);
}

.queue-item[data-state="done"] .progress__fill {
	background: var(--ok);
}

.queue-item[data-state="failed"] .progress__fill {
	background: var(--error);
}

.queue-item__actions {
	display: flex;
	flex: none;
	gap: 4px;
}

.link-button {
	background: none;
	border: 0;
	border-radius: 8px;
	color: var(--accent);
	cursor: pointer;
	font: inherit;
	font-weight: 600;
	/* 44px is the smallest comfortable touch target — these sit next to each other. */
	min-height: 44px;
	min-width: 44px;
	padding: 4px 10px;
}

.link-button:focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: 2px;
}

@media (min-width: 640px) {
	body.page {
		padding: 48px 24px;
	}

	.card {
		padding: 32px;
	}

	.card__title {
		font-size: 2rem;
	}

	.gate-form {
		align-items: flex-end;
		flex-direction: row;
	}

	.button {
		width: auto;
	}

	.uploader__zone {
		padding: 28px 24px;
	}

	.uploader__actions {
		flex-direction: row;
		justify-content: center;
	}
}
.hero {
	background: #fdfbf8;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 16px;
	margin: 0 0 20px;
}

.hero p {
	margin: 0 0 8px;
}

.hero p:last-child {
	margin: 0;
}

.queue__thank-you {
	background: #eef5f0;
	border-left: 4px solid var(--ok);
	border-radius: 6px;
	color: var(--ok);
	margin: 20px 0 0;
	padding: 12px 14px;
}

.uploads {
	margin-top: 32px;
	border-top: 1px solid var(--line);
	padding-top: 24px;
}

.uploads__heading {
	font-size: 1.1rem;
	margin: 0 0 16px;
}

.uploads__heading-count {
	background: var(--accent);
	border-radius: 999px;
	color: var(--accent-ink);
	display: inline-block;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 2px 8px;
	text-transform: uppercase;
	vertical-align: middle;
}

.uploads__grid {
	display: grid;
	gap: 16px;
	/*
	 * `auto-fill`, so a wider card buys more thumbnails rather than bigger ones. 150px is
	 * the track floor: the card is still 34rem at 768px, which leaves 480px of content, and
	 * anything above 159px would resolve to two columns there instead of three.
	 */
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

.grid-item {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/*
 * The whole tile is the control that opens the viewer (F2), so the button is the tile:
 * a bigger target than any icon on it could be, and one tab stop per photo rather than
 * three.
 */
.grid-item__open {
	background: none;
	border: 0;
	border-radius: 8px;
	color: inherit;
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font: inherit;
	gap: 8px;
	padding: 0;
	position: relative;
	text-align: left;
	width: 100%;
}

.grid-item__open:focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: 2px;
}

.grid-item__thumb {
	aspect-ratio: 1;
	border-radius: 8px;
	object-fit: cover;
	width: 100%;
	background: var(--line);
}

.grid-item__unread-dot {
	background: var(--accent);
	border: 2px solid var(--card);
	border-radius: 50%;
	height: 12px;
	position: absolute;
	right: 6px;
	top: 6px;
	width: 12px;
}

.grid-item__name {
	display: block;
	font-size: 0.85rem;
	margin: 0;
	/* The three rules that keep a guest-chosen filename from widening the page. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

@media (max-width: 639px) {
	.uploads__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* Metadata panel (C2) */
.metadata-panel {
	background: #fdfbf8;
	border: 1px solid var(--line);
	border-radius: 8px;
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.metadata-panel label {
	display: flex;
	flex-direction: column;
	font-size: 0.85rem;
	font-weight: 600;
	gap: 4px;
}

.metadata-panel input[type="text"] {
	border: 1px solid var(--line);
	border-radius: 4px;
	font: inherit;
	/* 16px keeps iOS from zooming the viewport when the field is focused. */
	font-size: 16px;
	/* 44px is the smallest comfortable touch target, and these are typed into on a phone. */
	min-height: 44px;
	padding: 8px 10px;
	width: 100%;
}

.metadata-panel input[type="checkbox"] {
	accent-color: var(--accent);
	flex: none;
	/*
	 * A checkbox is a 13px square by default, which is a quarter of the smallest target a
	 * thumb can reliably hit. The label is clickable too, but the box itself has to be
	 * hittable on its own — so it is sized to the target rather than to the glyph.
	 */
	height: 44px;
	margin: 0;
	width: 44px;
}

.metadata-panel__checkbox-label {
	flex-direction: row !important;
	align-items: center;
	font-weight: normal !important;
	gap: 8px;
	min-height: 44px;
}

/*
 * Where a refused save is reported. It is inside the panel, next to the fields that were
 * refused: `window.alert()` on a phone covers the very field the guest was typing into,
 * and cannot be asserted on.
 */
.metadata-panel__error {
	background: #fbeceb;
	border-left: 4px solid var(--error);
	border-radius: 6px;
	color: var(--error);
	margin: 0;
	padding: 10px 12px;
}

/*
 * The autosave dot (F10).
 *
 * There is no Save button any more, so this is the whole visible answer to "did that
 * stick?". It has to be ignorable by someone uploading photos who does not care, and
 * findable by someone who is wondering — which is a dot, not a toast, a banner or an
 * overlay.
 *
 * Fixed to the top-left: above the dialog's overlay (`z-index: 100`) so it is visible while
 * the viewer is open, and at the opposite end of the page from the upload dock, which is
 * sticky at the bottom. `pointer-events: none` because it is a readout, never a target.
 *
 * Idle is invisible and silent. Its accessible text lives in a visually-hidden line inside
 * a `role="status"` region — a colour is not a message.
 */
.save-dot {
	background: transparent;
	border-radius: 50%;
	/*
	 * A pale ring, so the dot reads on both backgrounds it can land on: the cream page, and
	 * the near-black overlay behind the open viewer. A dark red dot on that overlay is a dot
	 * nobody finds, which is the whole job gone.
	 */
	box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
	height: 12px;
	left: 12px;
	opacity: 0;
	pointer-events: none;
	position: fixed;
	top: 12px;
	transition: opacity 200ms ease, background-color 200ms ease;
	width: 12px;
	z-index: 200;
}

.save-dot--saving {
	/* `alternate`, so it breathes rather than snapping back to full at every cycle. */
	animation: pi-save-pulse 1.2s ease-in-out infinite alternate;
	background: var(--accent);
	opacity: 1;
}

.save-dot--saved {
	background: var(--ok);
	opacity: 1;
}

.save-dot--failed {
	background: var(--error);
	opacity: 1;
}

@keyframes pi-save-pulse {
	from {
		opacity: 1;
	}

	to {
		opacity: 0.3;
	}
}

/*
 * Asked for no animation: no pulse and no fade, but still four distinguishable states —
 * "saving" is a paler, hollow ring, and the other two are their own colours. Reduced motion
 * means less movement, not less information.
 */
@media (prefers-reduced-motion: reduce) {
	.save-dot {
		transition: none;
	}

	.save-dot--saving {
		animation: none;
		background: transparent;
		box-shadow: inset 0 0 0 3px var(--accent), 0 0 0 2px rgba(255, 255, 255, 0.9);
		opacity: 1;
	}
}

.metadata-panel__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-top: 4px;
}

.chip {
	background: #ece5dc;
	border-radius: 22px;
	font-size: 0.85rem;
	padding: 0 0 0 14px;
	display: inline-flex;
	align-items: center;
	gap: 2px;
	min-height: 44px;
}

/*
 * The remove control is a real touch target, not a 9px glyph. A chip is added by typing a
 * name and removed only here, so on a 390px screen this is the difference between a
 * mistyped name being fixable and being permanent (C1's 44px rule, C2's chips).
 */
.chip__remove {
	align-items: center;
	background: none;
	border: none;
	border-radius: 22px;
	color: var(--ink-soft);
	cursor: pointer;
	display: inline-flex;
	font-size: 1.2rem;
	justify-content: center;
	line-height: 1;
	min-height: 44px;
	min-width: 44px;
	padding: 0;
}

.chip__remove:focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: -3px;
}

.metadata-panel__autocomplete {
	position: relative;
}

.metadata-panel__autocomplete-list {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	background: var(--card);
	border: 1px solid var(--line);
	border-radius: 4px;
	max-height: 150px;
	overflow-y: auto;
	z-index: 10;
	margin: 0;
	padding: 0;
	list-style: none;
}

.metadata-panel__autocomplete-item {
	padding: 6px 8px;
	cursor: pointer;
	font-size: 0.85rem;
}

.metadata-panel__autocomplete-item:hover,
.metadata-panel__autocomplete-item.is-selected {
	background: #f4ece3;
}

.gentle-prompt {
	background: #f4ece3;
	border-left: 4px solid var(--accent);
	border-radius: 6px;
	margin: 20px 0 0;
	margin-bottom: 1.25rem;
	padding: 12px 14px;
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.gentle-prompt button {
	flex: none;
	margin-left: 10px;
}

/*
 * Wider windows (F1). Still one layout — the same page, with a wider card — because the
 * grid is the only part that benefits from the room (DESIGN §6). Prose does not: a line
 * that grew with the window would only get harder to read, so every block of running text
 * is held to about 62 characters whatever the card does.
 *
 * These rules come last so they win over the block-level `margin` shorthands above without
 * needing extra specificity.
 */

.card__lead,
.hero p,
.uploader__hint,
.uploader__types {
	max-width: 62ch;
}

/* Both of these sit in a centre-aligned drop zone, so the capped box stays centred too. */
.uploader__hint,
.uploader__types {
	margin-left: auto;
	margin-right: auto;
}

/*
 * The guest page only. The gate is the same card with nothing in it but a short form, and
 * a 1216px-wide box for a six-character code reads as a mistake; it keeps its 34rem column
 * at every width, the way `/admin/` keeps its own.
 */

@media (min-width: 900px) {
	.page--home .card {
		max-width: 52rem;
	}
}

@media (min-width: 1400px) {
	.page--home .card {
		max-width: 76rem;
	}
}

/*
 * The detail viewer (F2), docked (F9).
 *
 * The dialog is three bands: `.lightbox__head`, `.lightbox__body` — the one thing that
 * scrolls — and `.lightbox__actions` docked at the bottom. The panel is given the
 * viewport's height rather than its content's, so Previous and Next sit in the same place
 * under a tall portrait scan as under a wide landscape one, and the photo stays on screen
 * while a guest navigates it.
 *
 * `overflow: hidden` on the page (set by lightbox.js while the viewer is open) is what
 * keeps the grid still behind it; `overscroll-behavior: contain` on both the overlay and
 * the body stops a flick at the end of either handing the scroll on to the page underneath.
 * The overlay keeps its own `overflow-y: auto` purely as a floor: on a viewport too short
 * even for the head and the docked bar, something has to scroll.
 */

.lightbox {
	align-items: center;
	background: rgba(36, 31, 28, 0.78);
	bottom: 0;
	display: flex;
	justify-content: center;
	left: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 16px;
	position: fixed;
	right: 0;
	/* The four longhands rather than `inset`, which Safari only understood from 14.1. */
	top: 0;
	z-index: 100;
}

/* After the display rule, so the hidden attribute still wins. */
.lightbox[hidden] {
	display: none;
}

/*
 * The height is the viewport's, not the content's — a panel that grows with its photo is
 * a panel whose Previous and Next move between every press.
 *
 * `dvh` with a `vh` fallback beneath it, in that order, because on iOS Safari `100vh` is
 * the *tall* viewport: sized in `vh`, the docked bar spends its life behind the browser's
 * own toolbar, on exactly the phones this app is used from. The subtraction is the
 * overlay's own padding, doubled.
 *
 * `max-height` caps it on a tall desktop window, where the viewport is far taller than the
 * 512px rendition has anything to fill it with. It is a *constant*, not the content's
 * height, so the docked bar still lands in one place whatever the photo's shape.
 */
.lightbox__panel {
	background: var(--card);
	border-radius: var(--radius);
	display: flex;
	flex-direction: column;
	gap: 12px;
	height: calc(100vh - 32px);
	height: calc(100dvh - 32px);
	margin: auto;
	max-height: 50rem;
	max-width: 34rem;
	padding: 16px;
	width: 100%;
}

.lightbox__head {
	align-items: center;
	display: flex;
	flex: none;
	gap: 8px;
}

/*
 * The scrolling band. `min-height: 0` is not decoration: without it a flex child refuses
 * to shrink below its content, the panel grows past the viewport again and the docked bar
 * goes with it.
 */
.lightbox__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 12px;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.lightbox__name {
	font-weight: 600;
	margin: 0;
	/* The three rules that keep a guest-chosen filename from widening the dialog. */
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.lightbox__badge {
	background: #ece5dc;
	border-radius: 999px;
	color: var(--ink-soft);
	flex: none;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 2px 10px;
	text-transform: uppercase;
}

.lightbox__close {
	flex: none;
	margin-left: auto;
}

.lightbox__stage {
	align-items: center;
	background: #241f1c;
	border-radius: 8px;
	display: flex;
	/* Never squashed to make the body fit: a short body scrolls, it does not crop the photo. */
	flex: none;
	justify-content: center;
	margin: 0 auto;
	/* 512 for the rendition plus this box's own padding: never wider than what we serve. */
	max-width: 528px;
	min-height: 160px;
	overflow: hidden;
	padding: 8px;
	width: 100%;
}

/*
 * 512px is the rendition we serve (`/api/thumb`), and `width: auto` means the image is
 * never asked to be bigger than it is — an upscaled thumbnail is softer than the same one
 * shown honestly.
 */
.lightbox__image {
	display: block;
	height: auto;
	max-height: 52vh;
	/* `dvh` for the same reason the panel uses it: iOS measures `vh` against the tall viewport. */
	max-height: 52dvh;
	max-width: 100%;
	object-fit: contain;
	width: auto;
}

/*
 * The readout docks with the navigation it describes, and carries the line that separates
 * the docked bar from the content scrolling behind it.
 */
.lightbox__position {
	border-top: 1px solid var(--line);
	color: var(--ink-soft);
	flex: none;
	font-size: 0.85rem;
	font-variant-numeric: tabular-nums;
	margin: 0;
	padding-top: 12px;
}

.lightbox__remove-zone {
	border-top: 1px solid var(--line);
	margin-top: 12px;
	padding-top: 24px;
}

.lightbox__confirm {
	background: #fbeceb;
	border-radius: var(--radius);
	margin-top: 12px;
	padding: 16px;
	text-align: center;
}

.lightbox__confirm-prompt {
	color: var(--error);
	font-weight: 600;
	margin: 0 0 12px;
}

.lightbox__confirm-actions {
	display: flex;
	gap: 8px;
}

.lightbox__confirm-actions .button {
	flex: 1 1 8rem;
	width: auto;
}

.lightbox__confirm-do {
	background: var(--error);
	border-color: var(--error);
	color: #fff;
}

.lightbox__confirm-cancel {
	border-color: var(--error);
	color: var(--error);
}

/*
 * Docked, and last in the DOM so document order still matches what a guest sees. Inside the
 * panel's flex column rather than `position: fixed`: a fixed bar is what the iOS keyboard
 * covers the moment the caption field takes focus (F4 chose `sticky` over `fixed` for the
 * upload dock for the same reason).
 */
.lightbox__actions {
	display: flex;
	flex: none;
	flex-wrap: wrap;
	gap: 8px;
}

.lightbox__actions .button {
	flex: 1 1 8rem;
	width: auto;
}

.lightbox__delete {
	/* Destructive: it asks first (F7), and it scrolls away with the body while the
	   navigation a guest presses twenty times in a row never moves (F9). */
	border-color: var(--error);
	color: var(--error);
}

.lightbox__actions .button[disabled] {
	cursor: default;
	opacity: 0.45;
}

@media (min-width: 640px) {
	.lightbox {
		padding: 32px;
	}

	.lightbox__panel {
		/* The overlay's padding doubled, as above — it grew with the breakpoint. */
		height: calc(100vh - 64px);
		height: calc(100dvh - 64px);
		padding: 24px;
	}
}

/*
 * Wider windows: the details go beside the photo rather than under it, so a guest can see
 * the photo while typing its caption instead of scrolling between the two.
 *
 * The grid describes the *body* only. The head and the docked bar are the panel's own flex
 * column and stay out of it — putting them in the grid is what used to make the whole
 * dialog one tall block with the navigation at the foot of it.
 */

@media (min-width: 900px) {
	.lightbox__panel {
		max-width: 56rem;
	}

	.lightbox__body {
		align-items: start;
		display: grid;
		gap: 12px 16px;
		grid-template-areas:
			"stage details"
			"stage remove";
		grid-template-columns: minmax(0, 1fr) minmax(16rem, 20rem);
		grid-template-rows: auto 1fr;
	}

	.lightbox__stage {
		grid-area: stage;
	}

	.lightbox__details {
		grid-area: details;
	}

	.lightbox__remove-zone {
		grid-area: remove;
	}
}
