/* =============================================================================
   Memoricol — Create my book modal
   Slick 4-step popup. Vanilla JS owned; this file is style only.
   Palette + typography mirror the printed cover so the on-screen experience
   matches the book the customer receives.
   ========================================================================== */

/* Self-host the same TTFs we ship to the print renderer so the modal,
   landing page and printed cover all share one type system. */
@font-face {
	font-family: "MemoricolFraunces";
	src: url("../fonts/Fraunces-VF.ttf") format("truetype-variations"),
	     url("../fonts/Fraunces-VF.ttf") format("truetype");
	font-weight: 100 900;
	font-display: swap;
}
@font-face {
	font-family: "MemoricolNunito";
	src: url("../fonts/NunitoSans-VF.ttf") format("truetype-variations"),
	     url("../fonts/NunitoSans-VF.ttf") format("truetype");
	font-weight: 200 1000;
	font-display: swap;
}
@font-face {
	font-family: "MemoricolScript";
	src: url("../fonts/Sacramento-Regular.ttf") format("truetype");
	font-weight: 400;
	font-display: swap;
}

:root {
	/* Palette — verbatim from the print spec 2026-05-23 (exact hex values). */
	--mqm-navy:        #10233D;
	--mqm-coral:       #F25B76;
	--mqm-cream:       #FFF6ED;
	--mqm-peach:       #FBE1D0;
	--mqm-peach-soft:  #F9D8C5;
	--mqm-teal:        #4CC8BF;
	--mqm-orange:      #F3AE2E;
	--mqm-purple:      #B984D4;
	--mqm-muted:       #5B6577;
	--mqm-line:        rgba(16, 35, 61, 0.10);
	--mqm-success:     var(--mqm-teal);

	/* Legacy aliases — kept so existing selectors don't need a parallel
	   rename pass. Every "rose" in the modal now resolves to the new coral. */
	--mqm-rose:        var(--mqm-coral);
	--mqm-rose-deep:   var(--mqm-coral);
	--mqm-rose-soft:   var(--mqm-peach);
	--mqm-ink:         var(--mqm-navy);
	--mqm-ink-soft:    var(--mqm-muted);
	--mqm-turquoise:   var(--mqm-teal);

	/* Fonts. Inter remains the system fallback for performance — the bundled
	   Nunito/Fraunces load asynchronously and take over once available. */
	--mqm-font-body:   "MemoricolNunito", "Inter", system-ui, sans-serif;
	--mqm-font-serif:  "MemoricolFraunces", "Fraunces", Georgia, serif;
	--mqm-font-script: "MemoricolScript", "Sacramento", "Brush Script MT", cursive;
}

/* ---------- Overlay + shell ---------- */
.mqm-overlay {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(15, 27, 45, 0.62);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	opacity: 0;
	pointer-events: none;
	transition: opacity 220ms ease;
	padding: 24px;
}
/* Predictable widths everywhere inside the modal — padding/border don't
   inflate computed widths. Was the root cause of the form bleed: inputs
   with content-box + width:100% + 32px H-padding overflowed their column
   by 32px. */
.mqm-overlay,
.mqm-overlay *,
.mqm-overlay *::before,
.mqm-overlay *::after { box-sizing: border-box; }
.mqm-overlay.is-open {
	opacity: 1;
	pointer-events: auto;
}
.mqm-shell {
	position: relative;
	width: min(880px, 100%);
	max-height: calc(100vh - 48px);
	background: #fff;
	border-radius: 24px;
	box-shadow: 0 40px 90px rgba(15, 27, 45, 0.45), 0 12px 28px rgba(15, 27, 45, 0.18);
	display: flex;
	flex-direction: column;
	overflow: hidden;
	transform: translateY(16px) scale(0.985);
	opacity: 0;
	transition: transform 280ms cubic-bezier(.2,.9,.3,1.2), opacity 240ms ease;
}
.mqm-overlay.is-open .mqm-shell {
	transform: translateY(0) scale(1);
	opacity: 1;
}
body.mqm-locked { overflow: hidden; }

/* ---------- Header (progress + close) ---------- */
.mqm-head {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px 22px 12px;
	border-bottom: 1px solid var(--mqm-line);
	background: linear-gradient(180deg, var(--mqm-cream) 0%, #fff 100%);
	font-family: var(--mqm-font-body);
}
.mqm-steps {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 1;
	min-width: 0;
}
.mqm-step {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--mqm-muted);
	font: 600 13px var(--mqm-font-body);
	letter-spacing: 0.02em;
	white-space: nowrap;
}
.mqm-step-dot {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--mqm-peach-soft);
	color: var(--mqm-muted);
	font: 700 12px var(--mqm-font-body);
	transition: background 200ms ease, color 200ms ease, transform 200ms ease;
}
.mqm-step.is-active .mqm-step-dot {
	background: var(--mqm-coral);
	color: #fff;
	transform: scale(1.05);
	box-shadow: 0 6px 16px rgba(243, 92, 120, 0.35);
}
.mqm-step.is-done .mqm-step-dot {
	background: var(--mqm-teal);
	color: #fff;
}
.mqm-step.is-active .mqm-step-label,
.mqm-step.is-done .mqm-step-label { color: var(--mqm-ink); }
.mqm-step-rule {
	flex: 1;
	height: 2px;
	background: repeating-linear-gradient(90deg, var(--mqm-line) 0 4px, transparent 4px 8px);
	border-radius: 1px;
	min-width: 12px;
}
.mqm-close {
	appearance: none;
	background: rgba(15, 27, 45, 0.05);
	border: 0;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	color: var(--mqm-ink);
	transition: background 150ms ease, transform 150ms ease;
}
.mqm-close:hover { background: rgba(15, 27, 45, 0.10); transform: rotate(90deg); }
.mqm-close svg { width: 18px; height: 18px; stroke: currentColor; }

/* ---------- Body scroll area ---------- */
.mqm-body {
	flex: 1;
	overflow-y: auto;
	padding: 20px 32px 10px;
	scroll-behavior: smooth;
}
.mqm-panel { display: none; position: relative; animation: mqm-fade 260ms ease both; }
.mqm-panel.is-active { display: block; }

/* Slick privacy pill — sits in the top-right of step 1 */
.mqm-privacy-pill {
	position: absolute;
	top: 0;
	right: 0;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 7px 14px 7px 11px;
	background: linear-gradient(135deg, rgba(63, 193, 184, 0.14) 0%, rgba(63, 193, 184, 0.05) 100%);
	border: 1px solid rgba(63, 193, 184, 0.32);
	border-radius: 999px;
	font: 500 12px "Inter", sans-serif;
	color: var(--mqm-ink);
	letter-spacing: 0.01em;
	white-space: nowrap;
	box-shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 2px 8px rgba(15, 27, 45, 0.04);
	cursor: help;
}
.mqm-privacy-pill svg {
	flex-shrink: 0;
	width: 15px;
	height: 15px;
	color: var(--mqm-turquoise);
}
.mqm-privacy-pill strong { font-weight: 700; }
@keyframes mqm-fade {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: translateY(0); }
}

/* Eyebrow now matches the cover's filled peach pill rather than the older
   rose-outlined pill. Same intent (step label) but on-brand with the print. */
.mqm-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	background: var(--mqm-peach);
	border-radius: 999px;
	color: var(--mqm-navy);
	font: 700 11px var(--mqm-font-body);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}
.mqm-title {
	font-family: var(--mqm-font-serif);
	font-weight: 700;
	font-size: clamp(24px, 2vw + 16px, 32px);
	color: var(--mqm-navy);
	letter-spacing: -0.015em;
	margin: 12px 0 6px;
	line-height: 1.15;
}
.mqm-title em {
	font-style: italic;
	color: var(--mqm-coral);
	font-family: var(--mqm-font-serif);
}
.mqm-sub {
	color: var(--mqm-muted);
	font: 400 15px/1.55 var(--mqm-font-body);
	margin: 0 0 20px;
	max-width: 56ch;
}

/* ---------- Step 1: drop zone + grid ---------- */
.mqm-drop {
	display: block;
	position: relative;
	border: 2px dashed rgba(243, 92, 120, 0.45);
	border-radius: 18px;
	background: linear-gradient(180deg, #FFFCF6 0%, var(--mqm-cream) 100%);
	padding: 22px 24px;            /* vertical padding trimmed from 36 → 22 */
	text-align: center;
	transition: border-color 200ms ease, background 200ms ease, transform 200ms ease, padding 220ms ease;
	cursor: pointer;
}
/* Condensed drop — collapses to a compact "Upload more" pill once the
   customer has the minimum 6 photos. Frees vertical space for the
   carousel below without removing the affordance to add more photos. */
.mqm-drop.is-condensed {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 8px 14px 8px 10px;
	border-radius: 999px;
	border-style: solid;
	border-width: 1.5px;
	background: #fff;
	box-shadow: 0 4px 12px rgba(243, 92, 120, 0.14);
}
.mqm-drop.is-condensed .mqm-drop-icon {
	width: 28px;
	height: 28px;
	margin: 0;
	box-shadow: none;
}
.mqm-drop.is-condensed .mqm-drop-icon svg { width: 14px; height: 14px; }
.mqm-drop.is-condensed .mqm-drop-headline {
	font: 600 14px var(--mqm-font-body);
	margin: 0;
	white-space: nowrap;
}
.mqm-drop.is-condensed .mqm-drop-sub { display: none; }
.mqm-drop:hover { border-color: var(--mqm-coral); background: #FFF8ED; }
.mqm-drop.is-dragover {
	border-color: var(--mqm-coral);
	background: var(--mqm-peach);
	transform: scale(1.005);
}
.mqm-drop-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;                   /* slimmer affordance — saves ~12 px vertical */
	height: 52px;
	margin: 0 auto 10px;
	background: #fff;
	border-radius: 50%;
	color: var(--mqm-rose);
	box-shadow: 0 6px 18px rgba(255, 84, 112, 0.22);
}
.mqm-drop-icon svg { width: 24px; height: 24px; }
.mqm-drop-headline {
	font: 600 16px var(--mqm-font-body);
	color: var(--mqm-navy);
	margin: 0 0 3px;
}
.mqm-drop-sub {
	font: 400 13px var(--mqm-font-body);
	color: var(--mqm-muted);
	margin: 0;
}
.mqm-drop-sub strong { color: var(--mqm-rose-deep); font-weight: 700; }
.mqm-file-input { position: absolute; opacity: 0; pointer-events: none; }

.mqm-counter {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin: 12px 0 10px;          /* trimmed from 22/14 → 12/10 */
	font: 500 13px var(--mqm-font-body);
	color: var(--mqm-muted);
}
.mqm-counter strong { color: var(--mqm-ink); font-weight: 700; }
.mqm-counter-bar {
	flex: 1;
	height: 6px;
	background: #F1ECDF;
	border-radius: 3px;
	overflow: hidden;
}
.mqm-counter-fill {
	height: 100%;
	background: linear-gradient(90deg, var(--mqm-rose) 0%, var(--mqm-rose-deep) 100%);
	border-radius: 3px;
	width: 0;
	transition: width 280ms cubic-bezier(.2,.9,.3,1.2);
}
.mqm-counter-fill.is-full {
	background: linear-gradient(90deg, var(--mqm-success) 0%, var(--mqm-turquoise) 100%);
}

.mqm-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
	gap: 10px;
	margin: 0 0 8px;
}
.mqm-tile {
	position: relative;
	aspect-ratio: 1 / 1;
	border-radius: 12px;
	overflow: hidden;
	background: #f3eedf;
	box-shadow: 0 4px 10px rgba(15, 27, 45, 0.10);
	animation: mqm-pop 240ms cubic-bezier(.2,.9,.3,1.4) both;
	/* `grab` cursor signals draggability on Step 1. The cover-grid (Step 2)
	   overrides this to a pointer below — those tiles are click-to-select. */
	cursor: grab;
	/* Snappier drag — only transform/box-shadow transition; opacity is
	   instant so the lift reads as immediate feedback. */
	transition: transform 120ms ease, box-shadow 120ms ease;
	touch-action: pan-y;            /* let vertical page scroll pass through; horizontal stays for our drag */
	user-select: none;
}
.mqm-tile:active { cursor: grabbing; }
.mqm-tile:hover {
	transform: translateY(-1px);
	box-shadow: 0 6px 14px rgba(15, 27, 45, 0.14);
}
/* A subtle grip glyph in the bottom-right corner — appears on hover. Tells
   the user the tile is draggable without permanently cluttering the UI. */
.mqm-tile::after {
	content: "";
	position: absolute;
	bottom: 6px;
	right: 6px;
	width: 18px;
	height: 18px;
	border-radius: 6px;
	background:
		linear-gradient(currentColor, currentColor) center / 10px 1.5px no-repeat,
		linear-gradient(currentColor, currentColor) center/ 10px 1.5px no-repeat,
		linear-gradient(currentColor, currentColor) center / 10px 1.5px no-repeat;
	background-position: center 5px, center 9px, center 13px;
	background-color: rgba(15, 27, 45, 0.55);
	color: #fff;
	opacity: 0;
	transition: opacity 140ms ease;
	pointer-events: none;
}
.mqm-tile:hover::after { opacity: 0.85; }
/* Lifted state — instant opacity, immediate scale, deeper shadow. */
.mqm-tile.is-dragging {
	opacity: 0.35;
	transform: scale(0.92);
	box-shadow: 0 16px 36px rgba(15, 27, 45, 0.26);
}
/* The tile currently under the pointer — the photo will land before it. */
.mqm-tile.is-drop-target {
	outline: 3px dashed var(--mqm-coral, #F25B76);
	outline-offset: 3px;
	transform: scale(1.02);
}
/* ===== Reorder mode — applied to the carousel + modal root while a drag
   is in progress. Kills the most common accidental click targets: the
   carousel prev/next arrows that float at z-index 3 over the tiles, and
   the scroll-snap that fights drop targeting. */
.mqm-carousel.is-reordering .mqm-carousel-arrow {
	opacity: 0;
	pointer-events: none;
}
.mqm-carousel.is-reordering [data-mqm-grid] {
	scroll-snap-type: none;
}
.mqm-overlay.is-reordering .mqm-foot {
	/* The Next / Back buttons in the modal foot also become click hazards
	   if the user releases their drag down there. Dim + disable during
	   reorder so a wayward drop can't accidentally advance the step. */
	opacity: 0.4;
	pointer-events: none;
}
@keyframes mqm-pop {
	from { transform: scale(0.85); opacity: 0; }
	to   { transform: scale(1);    opacity: 1; }
}
.mqm-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mqm-tile-remove {
	position: absolute;
	top: 6px; right: 6px;
	width: 22px; height: 22px;
	border: 0;
	border-radius: 50%;
	background: rgba(15, 27, 45, 0.78);
	color: #fff;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	transition: opacity 160ms ease, background 160ms ease;
}
.mqm-tile:hover .mqm-tile-remove { opacity: 1; }
.mqm-tile-remove:hover { background: var(--mqm-rose-deep); }
.mqm-tile-remove svg { width: 12px; height: 12px; }

/* Page number badge — tells the customer this tile's position in the printed
   book at a glance. Updates as they drag. Step 2's cover grid hides it
   below (a cover preview doesn't need page numbers). */
.mqm-tile-pageno {
	position: absolute;
	top: 6px;
	left: 6px;
	min-width: 22px;
	height: 22px;
	padding: 0 6px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 999px;
	background: rgba(15, 27, 45, 0.78);
	color: #fff;
	font: 700 11px/1 "Inter", sans-serif;
	letter-spacing: 0.02em;
	pointer-events: none;
}
/* Hide page numbers on the Step 2 cover-selector grid — those tiles are
   click-to-pick, not part of the print sequence. */
.mqm-grid.is-selectable .mqm-tile-pageno { display: none; }
.mqm-grid.is-selectable .mqm-tile { cursor: pointer; touch-action: auto; }

.mqm-tile.is-cover {
	box-shadow: 0 0 0 3px var(--mqm-rose), 0 12px 24px rgba(255, 84, 112, 0.28);
}

/* ---------- Quality badges (step 1 tiles) ----------
   Moved to the BOTTOM of the tile so they don't cover faces. Sits on a
   subtle dark gradient strip so the badge stays legible over any photo.
   Shrunk to a thin pill that hugs the bottom-left corner rather than the
   chunky banner it used to be. */
.mqm-tile-quality {
	position: absolute;
	left: 6px;
	bottom: 6px;
	font: 700 9px "Inter", sans-serif;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	padding: 3px 7px;
	border-radius: 999px;
	color: #fff;
	background: rgba(15, 27, 45, 0.78);
	max-width: calc(100% - 12px);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	pointer-events: auto;
	cursor: help;
	z-index: 2;
}
.mqm-tile-quality--good     { background: rgba(46, 134, 67, 0.92); }
.mqm-tile-quality--warn     { background: rgba(232, 154, 42, 0.92); }
.mqm-tile-quality--info     { background: rgba(76, 143, 203, 0.92); }
.mqm-tile-quality--checking { background: rgba(15, 27, 45, 0.55); }

/* Subtle gradient at the bottom of each tile so the quality badge is
   readable even on bright photos. Sits behind the badge but above the
   image. Only visible on Step 1 (the reorder grid) — Step 2's cover
   selector hides it because tiles there don't show a quality badge. */
.mqm-tile::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 36px;
	background: linear-gradient(180deg, rgba(15, 27, 45, 0) 0%, rgba(15, 27, 45, 0.55) 100%);
	pointer-events: none;
	z-index: 1;
	border-radius: 0 0 var(--mqm-radius-sm) var(--mqm-radius-sm);
}
.mqm-grid.is-selectable .mqm-tile::before { display: none; }

.mqm-quality-summary {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 4px 0 12px;
	padding: 10px 14px;
	background: rgba(255, 246, 233, 0.7);
	border: 1px dashed var(--mqm-line);
	border-radius: 10px;
	font: 500 13px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
}
.mqm-quality-summary strong { color: var(--mqm-ink); font-weight: 700; }
.mqm-quality-summary-text { flex: 1; min-width: 0; }

/* Gentle review prompt when one or more photos could be replaced */
.mqm-quality-summary.is-warn {
	background: linear-gradient(135deg, #FFF8EE 0%, #FFEFE3 100%);
	border: 1px solid rgba(255, 84, 112, 0.30);
	color: var(--mqm-ink);
	box-shadow: 0 2px 8px rgba(15, 27, 45, 0.04);
}
.mqm-quality-summary.is-warn .mqm-quality-summary-text strong { color: var(--mqm-rose-deep); }

.mqm-quality-summary-pulse {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	flex-shrink: 0;
	color: var(--mqm-rose);
}
.mqm-quality-summary-pulse svg {
	width: 18px;
	height: 18px;
}

/* ---------- Step 3: Age cards + previews ---------- */
.mqm-style-cards {
	display: grid;
	gap: 8px;
	margin: 4px 0 10px;
}
.mqm-style-cards--row { grid-template-columns: repeat(3, 1fr); }

.mqm-style-card {
	appearance: none;
	display: grid;
	grid-template-columns: 64px 1fr auto;        /* slimmer age tile column */
	gap: 10px;
	align-items: center;
	width: 100%;
	min-height: 74px;                             /* down from 96 — tighter row */
	padding: 8px 12px 8px 8px;
	border: 1.5px solid rgba(243, 92, 120, 0.15);
	border-radius: 12px;
	background: #fff;
	cursor: pointer;
	text-align: left;
	transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease, background 160ms ease;
}
.mqm-style-card:hover {
	border-color: var(--mqm-rose);
	transform: translateY(-1px);
}
.mqm-style-card.is-active {
	border-color: var(--mqm-rose);
	box-shadow: 0 0 0 3px rgba(255, 84, 112, 0.18), 0 8px 22px rgba(255, 84, 112, 0.14);
}

/* AGE BLOCK — big rose display type on a cream tile, stacked into two lines. */
.mqm-style-card-age {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1px;
	width: 64px;
	height: 58px;
	padding: 4px 4px;
	background: #FCEAD0;
	border-radius: 8px;
	font-family: var(--mqm-font-serif);
	font-weight: 800;
	color: var(--mqm-rose-deep);
	letter-spacing: 0.02em;
	line-height: 1.0;
	text-align: center;
}
.mqm-style-card-age-top { font-size: 13px; opacity: 0.95; }
.mqm-style-card-age-bot { font-size: 18px; }
/* Connector words (TO / AND) sit between the numbers as small caps so the
   digits read as the dominant rhythm — "6 TO 8" rather than "6 TO 8". */
.mqm-style-card-age-bot small {
	font-size: 0.55em;
	font-weight: 700;
	letter-spacing: 0.06em;
	opacity: 0.75;
	vertical-align: 0.18em;
	margin: 0 0.1em;
}

/* BODY — bold ink name + muted description. Compact so it fits the locked card height without wrapping into many lines. */
.mqm-style-card-body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}
.mqm-style-card-name {
	font: 700 13px/1.2 "Inter", sans-serif;
	color: var(--mqm-ink);
}
.mqm-style-card-desc {
	font: 400 11px/1.38 "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	/* Copy is now short enough to never need clamping. Removing the
	   -webkit-line-clamp lets the card grow a touch when needed so no
	   description ever truncates with an ellipsis. */
}

/* TICK — neutral circle, fills rose when card is active. */
.mqm-style-card-tick {
	width: 22px; height: 22px;
	border-radius: 50%;
	background: #F1ECDF;
	color: transparent;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 160ms ease, color 160ms ease, transform 160ms ease;
}
.mqm-style-card-tick svg { width: 13px; height: 13px; }
.mqm-style-card.is-active .mqm-style-card-tick {
	background: var(--mqm-rose);
	color: #fff;
	transform: scale(1.05);
}

/* Cover + open book spread side by side */
/* Step 3 open-book spread. Cover preview was removed 2026-05-23 — Step 2
   already shows the front + back cover preview, so Step 3 just shows what
   the AGE-tuned interior looks like. */
.mqm-preview-stage {
	display: grid;
	grid-template-columns: 1fr;
	gap: 14px;
	align-items: center;
	justify-items: center;
	margin: 0 0 8px;
}
/* Step 3 mini-card — trimmed to match the new compact Step 3 layout. */
.mqm-cover-card--step3 {
	max-width: 220px;
	padding: 12px 12px 14px;
}
.mqm-cover-card--step3 .mqm-cover-card-wordmark        { font-size: 13px; margin-bottom: 8px; }
.mqm-cover-card--step3 .mqm-cover-card-title           { font-size: 14px; line-height: 1.02; }
.mqm-cover-card--step3 .mqm-cover-card-subtitle        { font-size: 8px; padding: 4px 10px; }
.mqm-cover-card--step3 .mqm-cover-card-personal-label  { font-size: 9px; }
.mqm-cover-card--step3 .mqm-cover-card-personal-name   { font-size: 26px; }
.mqm-cover-card--step3 .mqm-cover-card-personal-family { font-size: 11px; }

.mqm-preview-frame {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
}

/* Inside-spread preview — two A4 portrait pages laid open. Aspect 420:297
   (two A4 panels side-by-side, the real geometry of an open A4 booklet).
   The pages are slightly inset from the spread edges so the centre gutter +
   outer drop shadow read as a real book lying flat. */
.mqm-book-spread {
	position: relative;
	display: grid;
	grid-template-columns: 1fr 1fr;
	width: 100%;
	/* Shrunk from 560 → 440px so the spread fits above the fold on a
	   standard laptop without internal modal scrolling. Aspect ratio
	   (A3-spread = two A4 portraits) is preserved. */
	max-width: 440px;
	aspect-ratio: 420 / 297;
	margin: 0 auto;
	background: #fff;
	border-radius: 6px;
	box-shadow:
		0 22px 50px rgba(15, 27, 45, 0.20),
		0 6px 14px rgba(15, 27, 45, 0.09);
	overflow: hidden;
}
/* Centre binding shadow — gives the open-book illusion. */
.mqm-book-spread::after {
	content: "";
	position: absolute;
	top: 0; bottom: 0;
	left: 50%;
	width: 22px;
	transform: translateX(-50%);
	background:
		linear-gradient(90deg,
			rgba(15, 27, 45, 0)    0%,
			rgba(15, 27, 45, 0.20) 30%,
			rgba(15, 27, 45, 0.32) 50%,
			rgba(15, 27, 45, 0.20) 70%,
			rgba(15, 27, 45, 0)    100%);
	pointer-events: none;
}
/* Tag retired — preview heading lives above the spread now. */
.mqm-book-spread-tag { display: none; }
.mqm-book-page {
	position: relative;
	background: #fff;
	overflow: hidden;
	padding: 14px 12px;
	display: flex;
	align-items: center;
	justify-content: center;
}
.mqm-book-page--left  { border-radius: 4px 0 0 4px; box-shadow: inset -3px 0 6px rgba(15, 27, 45, 0.08); background: #FFFCF8; }
.mqm-book-page--right { border-radius: 0 4px 4px 0; box-shadow: inset  3px 0 6px rgba(15, 27, 45, 0.08); background: #FFFFFF; }
/* Contain fit so phone-portrait photos display fully — no aggressive face
   crops, no chopped limbs. The canvas drawing path uses renderContainedPhoto
   which already letterboxes to the page background. */
.mqm-book-page-canvas,
.mqm-book-page-img {
	display: block;
	/* width:100%/height:100% (not auto) so the canvas fills its parent
	   predictably. `auto` made the canvas size depend on its intrinsic
	   backing-store dimensions, which created a feedback loop: changing the
	   backing for DPR shifted clientWidth, breaking the DPR calculation. */
	width: 100%;
	height: 100%;
	object-fit: contain;
	/* `image-rendering` REMOVED 2026-05-25 — the previous stack
	   (auto → -webkit-optimize-contrast → high-quality) was the cause of the
	   pixelation. Browsers that didn't understand `high-quality` fell back to
	   `-webkit-optimize-contrast`, which Chrome and Safari interpret as
	   nearest-neighbor scaling ("crisp pixel art"). Default `auto` is
	   smooth bilinear/lanczos depending on the browser — correct for photos
	   AND line-art at any scale. */
}
.mqm-book-page.is-empty::before {
	content: "Reference coming";
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--mqm-ink-soft);
	font: 500 11px "Inter", sans-serif;
	background: repeating-linear-gradient(45deg, #f7f0df 0 8px, #fff8e9 8px 16px);
}
/* AI preview loading state — soft rose wash with a "Generating…" caption. */
.mqm-book-page.is-loading::before {
	content: "Generating…";
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--mqm-rose-deep, #C62853);
	font: 700 11px/1 "Inter", sans-serif;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	background: linear-gradient(180deg, #FFF5F7 0%, #FFE0E9 100%);
}
.mqm-book-page.is-loading::after {
	content: "";
	position: absolute;
	left: 50%; top: calc(50% + 18px);
	transform: translateX(-50%);
	width: 22px; height: 22px;
	border-radius: 50%;
	border: 2px solid rgba(198, 40, 83, 0.18);
	border-top-color: var(--mqm-rose-deep, #C62853);
	animation: mqm-spin 0.8s linear infinite;
}
@keyframes mqm-spin { to { transform: translateX(-50%) rotate(360deg); } }

/* AI preview error state — uses the data-error attribute set from JS. */
.mqm-book-page.is-error::before {
	content: "Couldn't generate the preview";
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	color: var(--mqm-rose-deep, #C62853);
	font: 600 11px/1.4 "Inter", sans-serif;
	text-align: center;
	background: #FFF5F7;
}
.mqm-book-page.is-error::after {
	content: attr(data-error);
	position: absolute;
	left: 12px; right: 12px; bottom: 12px;
	color: var(--mqm-ink-soft);
	font: 400 10px/1.4 "Inter", sans-serif;
	text-align: center;
	opacity: 0.85;
}
.mqm-preview-book {
	position: relative;
	width: 100%;
	max-width: 360px;
	aspect-ratio: 3 / 4;
	border-radius: 10px 14px 14px 10px;
	overflow: hidden;
	background: #FFF6E9;
	box-shadow:
		0 30px 60px rgba(15, 27, 45, 0.28),
		0 10px 22px rgba(15, 27, 45, 0.10),
		inset 6px 0 0 rgba(15, 27, 45, 0.10);
	transform: rotate(-1.5deg);
}
.mqm-preview-canvas {
	display: block;
	width: 100%;
	height: 100%;
}
/* Premium book-cover treatment — top portion of the cover gets a white wash
   that fades into the photo, with a large serif title, a heart-flanked rose
   divider, and a rose italic dedication beneath. Reads like a proper book cover. */
.mqm-preview-overlay {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	padding: 32px 26px 56px;
	background: linear-gradient(180deg,
		rgba(255, 255, 255, 0.92) 0%,
		rgba(255, 255, 255, 0.82) 40%,
		rgba(255, 255, 255, 0.45) 75%,
		rgba(255, 255, 255, 0) 100%);
	border-radius: 0;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	box-shadow: none;
	border-bottom: none;
	text-align: center;
}
.mqm-preview-overlay-label {
	display: block;
	font: 700 9.5px "Inter", sans-serif;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--mqm-rose-deep);
	margin: 0 0 6px;
}
.mqm-preview-overlay-title {
	font: 700 27px/1.12 "Fraunces", serif;
	color: var(--mqm-ink);
	margin: 0;
	letter-spacing: -0.018em;
}
.mqm-preview-overlay-divider {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	margin: 14px auto 10px;
	max-width: 78%;
	color: var(--mqm-rose);
}
.mqm-preview-overlay-divider i {
	flex: 1 1 auto;
	height: 1px;
	background: linear-gradient(90deg, transparent, currentColor 35%, currentColor 65%, transparent);
	opacity: 0.7;
}
.mqm-preview-overlay-divider svg {
	width: 12px;
	height: 12px;
	flex-shrink: 0;
}
/* Dedication line ("For Emma, with love") — anchored to the BOTTOM of the
   cover, centred. Sits over the photo with a soft white-to-transparent wash
   so it reads cleanly without obscuring the image. */
.mqm-preview-credit {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	margin: 0;
	padding: 26px 20px 16px;
	text-align: center;
	font: 500 italic 14px/1.3 "Fraunces", serif;
	color: var(--mqm-rose-deep);
	z-index: 2;
	background: linear-gradient(0deg,
		rgba(255, 255, 255, 0.85) 0%,
		rgba(255, 255, 255, 0.55) 55%,
		rgba(255, 255, 255, 0) 100%);
	pointer-events: none;
}
.mqm-preview-credit:empty { display: none; }
/* When no dedication is set, also hide the top-overlay heart divider so the
   title can sit on its own without an orphan ornament under it. */
.mqm-preview-book:has(.mqm-preview-credit:empty) .mqm-preview-overlay-divider {
	display: none;
}
.mqm-preview-overlay-sub:empty { display: none; }
.mqm-preview-disclaimer {
	display: flex;
	align-items: center;
	gap: 6px;
	font: 500 12px/1.35 var(--mqm-font-body);
	color: var(--mqm-muted);
	margin: 2px 0 0;
	text-align: center;
	max-width: 420px;
}
.mqm-preview-disclaimer svg {
	flex-shrink: 0;
	width: 14px;
	height: 14px;
	color: var(--mqm-rose);
}

/* Section heading above the inside-spread preview on Step 3. Mirrors the
   small-caps editorial style used for input labels — keeps the page calm
   and reads as a section divider, not another title. */
.mqm-preview-heading {
	font: 600 11px/1 var(--mqm-font-serif);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--mqm-navy);
	text-align: center;
	margin: 14px 0 10px;
}
.mqm-cover-badge {
	position: absolute;
	left: 6px; bottom: 6px;
	background: var(--mqm-rose);
	color: #fff;
	font: 700 10px "Inter", sans-serif;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	padding: 3px 8px;
	border-radius: 999px;
	opacity: 0;
	transition: opacity 160ms ease;
}
.mqm-tile.is-cover .mqm-cover-badge { opacity: 1; }

/* Selectable mode for step 2 — horizontal film-strip with snap. Always one
   clean row regardless of how many photos, every tile uniformly sized. */
.mqm-grid.is-selectable {
	display: flex;
	grid-template-columns: none;
	gap: 10px;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	padding-bottom: 10px;
	margin-bottom: 4px;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
	scrollbar-color: var(--mqm-line) transparent;
}
.mqm-grid.is-selectable::-webkit-scrollbar { height: 6px; }
.mqm-grid.is-selectable::-webkit-scrollbar-thumb { background: var(--mqm-line); border-radius: 3px; }
.mqm-grid.is-selectable::-webkit-scrollbar-track { background: transparent; }
.mqm-grid.is-selectable .mqm-tile {
	flex: 1 0 116px;            /* grow to fill row when few photos; never shrink below 116px */
	aspect-ratio: 1 / 1;
	height: auto;
	scroll-snap-align: start;
	cursor: pointer;
	transition: transform 160ms ease;
}
.mqm-grid.is-selectable .mqm-tile:hover { transform: translateY(-2px); }
.mqm-grid.is-selectable .mqm-tile-remove { display: none; }

/* Replace pill — appears only on low-resolution tiles in step 1 */
.mqm-tile-replace {
	position: absolute;
	left: 50%;
	bottom: 8px;
	transform: translateX(-50%);
	appearance: none;
	background: #fff;
	color: var(--mqm-rose-deep);
	border: 1.5px solid var(--mqm-rose);
	border-radius: 999px;
	padding: 4px 12px;
	font: 700 11px "Inter", sans-serif;
	letter-spacing: 0.04em;
	cursor: pointer;
	box-shadow: 0 4px 10px rgba(15, 27, 45, 0.18);
	transition: background 140ms ease, color 140ms ease, transform 140ms ease;
	z-index: 2;
}
.mqm-tile-replace:hover {
	background: var(--mqm-rose);
	color: #fff;
	transform: translateX(-50%) translateY(-1px);
}

/* Every step — squeeze the chrome so each fits without scrolling. The
   step header at the top already shows the active step name, so the
   in-panel eyebrow is redundant. Hiding it buys us ~36px per step. */
[data-step="1"] .mqm-eyebrow,
[data-step="2"] .mqm-eyebrow,
[data-step="3"] .mqm-eyebrow,
[data-step="4"] .mqm-eyebrow { display: none !important; }
[data-step="1"] .mqm-title { margin-top: 0; margin-bottom: 4px; font-size: clamp(20px, 1.3vw + 13px, 26px); }
[data-step="2"] .mqm-title { margin-top: 0; margin-bottom: 14px; font-size: clamp(18px, 1.2vw + 12px, 22px); }
[data-step="3"] .mqm-title { margin-top: 0; margin-bottom: 2px;  font-size: clamp(18px, 1.2vw + 12px, 22px); }
[data-step="4"] .mqm-title { margin-top: 0; margin-bottom: 2px;  font-size: clamp(16px, 0.9vw + 11px, 19px); }
[data-step="1"] .mqm-sub   { margin-bottom: 10px; font-size: 13.5px; }
[data-step="3"] .mqm-sub   { margin-bottom: 6px; font-size: 13px; }
[data-step="4"] .mqm-sub   { margin-bottom: 6px; font-size: 12px; }

/* Compact Step 4 — every pixel of vertical space matters here. The whole
   checkout should fit on a standard desktop viewport without scrolling. */
/* Checkout heading — shrink the big "Almost there" title on step 4 so the
   form + total fit without scrolling on a standard laptop. */
[data-step="4"] .mqm-title {
	font-size: clamp(19px, 1.3vw + 13px, 25px);
	margin: 0 0 8px;
}

[data-step="4"] .mqm-checkout-grid {
	padding: 14px 18px;
	gap: 20px;
	margin-bottom: 0;
}
[data-step="4"] .mqm-checkout-aside { gap: 8px; }
[data-step="4"] .mqm-checkout-aside .mqm-cover-card--step4 {
	max-width: 160px;   /* down from 220px — preview at side scale */
}
[data-step="4"] .mqm-fields { gap: 9px; }
[data-step="4"] .mqm-field  { gap: 4px; }
[data-step="4"] .mqm-row    { gap: 10px; }
[data-step="4"] .mqm-label  { font-size: 10px; letter-spacing: 0.10em; }
[data-step="4"] .mqm-input,
[data-step="4"] .mqm-textarea { padding: 8px 11px; font-size: 13.5px; }
[data-step="4"] .mqm-textarea { min-height: 44px; }
[data-step="4"] .mqm-field-hint { font-size: 11px; margin-top: 2px; }
[data-step="4"] .mqm-pay {
	padding-bottom: 6px;
	margin-bottom: 2px;
	gap: 4px;
}
[data-step="4"] .mqm-stripe-mount { padding: 9px 11px; min-height: 38px; }
[data-step="4"] .mqm-pay-testnote { font-size: 10.5px; }
[data-step="4"] .mqm-summary-info h4 { font-size: 13.5px; margin-bottom: 1px; }
[data-step="4"] .mqm-summary-kicker { font-size: 9px; margin-bottom: 1px; }
[data-step="4"] .mqm-summary-meta { font-size: 11.5px; line-height: 1.3; }
/* Final vertical-rhythm trims so the consent tick clears the fold on a
   standard laptop. The live total is already pinned to the Pay button, so
   these only need to claw back the consent + trust + divider whitespace. */
[data-step="4"] .mqm-pay-divider { margin: 4px 0; }
[data-step="4"] .mqm-pay-trust { margin-top: 3px; font-size: 10.5px; }
[data-step="4"] .mqm-pay-trust-icon { width: 14px; height: 14px; }
[data-step="4"] .mqm-promo-field { margin-top: 0; }
[data-step="4"] .mqm-consent {
	margin-top: 2px;
	font-size: 11.5px;
	line-height: 1.4;
}
[data-step="4"] .mqm-consent input { margin-top: 2px; width: 15px; height: 15px; }
/* Buy-now hero (left column) sits lower in the visual hierarchy now the price
   lives on the button — shrink it so the stacked mobile layout scrolls less. */
[data-step="4"] .mqm-buynow-headline { font-size: 15px; margin-top: 2px; }
[data-step="4"] .mqm-buynow-copy { font-size: 11.5px; }
[data-step="4"] .mqm-buynow-steps { gap: 4px; }
[data-step="4"] .mqm-buynow-step { padding: 4px 10px; font-size: 11px; }
/* Step 1 photo carousel — fixed-width tiles in a horizontal-scroll strip.
   Tiles keep a consistent size (so quality labels never truncate to "LO...")
   and the row stays single-line regardless of count. Arrows appear on the
   sides when there are more tiles than fit. */
.mqm-carousel {
	position: relative;
	margin: 0 0 8px;
}
[data-step="1"] .mqm-grid {
	display: flex;
	flex-wrap: nowrap;
	gap: 10px;
	overflow-x: auto;
	scroll-behavior: smooth;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	/* L/R padding keeps first/last tile clear of the floating arrow buttons. */
	padding: 4px 28px 12px;
	scroll-padding: 0 28px;
	scrollbar-width: thin;
}
[data-step="1"] .mqm-grid::-webkit-scrollbar { height: 6px; }
[data-step="1"] .mqm-grid::-webkit-scrollbar-thumb { background: rgba(243, 92, 120, 0.30); border-radius: 3px; }
[data-step="1"] .mqm-grid::-webkit-scrollbar-track { background: transparent; }
[data-step="1"] .mqm-grid .mqm-tile {
	flex: 0 0 132px;                 /* fixed tile width — no shrinking, labels stay full */
	width: 132px;
	aspect-ratio: 1 / 1;
	height: auto;
	scroll-snap-align: start;
}

/* Carousel arrows — hidden by default. JS adds `.has-overflow` to the
   parent when there are more tiles than fit in the visible width. */
.mqm-carousel-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	display: none;                   /* shown only when .has-overflow */
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 0;
	border-radius: 50%;
	background: #fff;
	color: var(--mqm-navy);
	cursor: pointer;
	box-shadow: 0 6px 16px rgba(14, 41, 71, 0.18);
	transition: opacity 160ms ease, transform 160ms ease;
}
.mqm-carousel-arrow:hover { transform: translateY(-50%) scale(1.05); }
.mqm-carousel-arrow:disabled {
	opacity: 0.35;
	cursor: default;
}
.mqm-carousel-arrow svg { width: 18px; height: 18px; }
.mqm-carousel-arrow--prev { left: -10px; }
.mqm-carousel-arrow--next { right: -10px; }
.mqm-carousel.has-overflow .mqm-carousel-arrow { display: inline-flex; }

/* Step 2 cover-photo grid — capped tile size; centred row. Step 2 uses
   .is-selectable so its tiles already get the existing flex treatment from
   the base ruleset (line 816). This block just centres + tightens. */
[data-step="2"] .mqm-grid.is-selectable {
	padding-bottom: 6px;
	margin-bottom: 0;
	/* `safe center` keeps tiles centred when they all fit, but falls back to
	   flex-start once they overflow — otherwise the leftmost tile gets pushed
	   into negative scroll space and the left arrow can't reach it. */
	justify-content: safe center;
	gap: 8px;
	/* Extra horizontal padding so the first/last tiles aren't masked by the
	   round arrow buttons that float over the edges. */
	padding-left: 28px;
	padding-right: 28px;
	scroll-padding-left: 28px;
	scroll-padding-right: 28px;
}
/* Step 2 cover-preview overrides retired 2026-05-23 — they were sized for
   an older 128px mini-card and were winning the cascade because of
   [data-step="2"] specificity (0,2,0). The new layout's grid + gap live
   on `.mqm-cover-preview` and `.mqm-cover-preview--inline` below. */
[data-step="3"] .mqm-preview-book { max-width: 180px; margin: 0; }
[data-step="3"] .mqm-preview-overlay-title { font-size: 13px; line-height: 1.15; }
[data-step="3"] .mqm-preview-overlay-sub   { font-size: 9.5px; margin-top: 3px; }
[data-step="3"] .mqm-preview-overlay       { left: 8px; right: 8px; top: 8px; padding: 8px 10px 9px; border-radius: 8px; }
[data-step="3"] .mqm-preview-disclaimer    { max-width: 520px; margin: 12px auto 0; justify-content: center; }

/* ---------- Step 2: cover preview ---------- */
/* ============================================================================
   Cover preview — miniature of the printed front cover.
   Used by BOTH Step 2 (personalisation) and Step 3 (age + interior preview).
   One source of truth — same HTML structure, same CSS, same fonts.

   Layout rules (after several iterations):
     - Normal block flow inside the card, NOT grid. Aspect-ratio fights
       1fr rows and produces overlapping content; we instead let the card
       size to its content with a width-driven min-height.
     - Padding expressed in px (not %) so element heights are predictable
       regardless of card width.
     - Photo has a fixed aspect ratio (105:62) and its own width %, so the
       title that follows is always below it in flow.
   ========================================================================== */

/* Outer container — mini-cover on the left, personalisation inputs on the
   right in the same row so the whole step fits without scrolling. The
   card's drop shadow extends ~36 px past its trim, so the gap needs to
   be ≥ 40 px or the shadow + first character of the right column collide. */
.mqm-cover-preview {
	position: relative;
	display: grid;
	/* Desktop: preview 60% / form 40% with a 48px gap, per the latest spec.
	   The form column is hard-capped so inputs never reach for the edge of
	   the peach container — there's always ≥32px clear space between the
	   rightmost input pixel and the container's inner edge. */
	grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
	gap: 48px;
	margin: 10px 0 6px;
	padding: 24px 32px;
	border-radius: 18px;
	align-items: center;
	background: linear-gradient(180deg, var(--mqm-cream) 0%, #FFF1E3 100%);
	border: 1px solid rgba(243, 92, 120, 0.12);
}
@media (max-width: 960px) {
	.mqm-cover-preview { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 28px; padding: 20px 24px; }
}
/* Stack at tablet width — squeezing into two columns below ~820px makes
   the inputs feel cramped and the spread shrinks below its natural feel. */
@media (max-width: 820px) {
	.mqm-cover-preview { grid-template-columns: 1fr; gap: 22px; padding: 20px 22px; }
	.mqm-cover-side    { max-width: 420px; margin: 0 auto; }
}

/* Book-style spread — back cover + front cover sit edge-to-edge with a
   visible centre binding line, so they read as a real open book rather
   than two unrelated cards. The whole spread gets a single drop shadow.
   Soft peach blob shapes in each corner echo the approved print design. */
.mqm-cover-spread {
	position: relative;
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* Spread is the hero on Step 2 — bigger so it reads as a real book
	   open in the customer's hands, not a thumbnail. Keeps the 2:1 ratio
	   matching the A3 spread (420×297 ≈ 1.41:1, two A4 panels stacked). */
	max-width: 480px;
	width: 100%;
	margin: 0 auto;
	border-radius: 12px;
	overflow: hidden;
	background: var(--mqm-cream);
	box-shadow:
		0 18px 42px rgba(14, 41, 71, 0.20),
		0 4px 10px rgba(14, 41, 71, 0.10);
}
/* Corner blob decorations — large soft peach shapes in all four corners.
   Painted via radial-gradients on the spread itself so they sit behind
   the card content but inside the rounded clip. */
.mqm-cover-spread::before,
.mqm-cover-spread::after,
.mqm-cover-card--back::before,
.mqm-cover-card--front::before { content: ""; position: absolute; pointer-events: none; }
.mqm-cover-card--back::before {
	top: -20px; left: -30px;
	width: 75%; height: 38%;
	background: var(--mqm-peach);
	opacity: 0.65;
	border-radius: 60% 40% 50% 50% / 50% 60% 40% 50%;
	z-index: 0;
}
.mqm-cover-card--front::before {
	top: -25px; right: -30px;
	width: 70%; height: 35%;
	background: var(--mqm-peach);
	opacity: 0.65;
	border-radius: 50% 50% 40% 60% / 50% 50% 60% 40%;
	z-index: 0;
}
/* Bottom corner blobs — rendered as additional pseudo on each panel. */
.mqm-cover-card--back  > * { position: relative; z-index: 1; }
.mqm-cover-card--front > * { position: relative; z-index: 1; }
/* Centre binding — thin shadow stripe down the fold line. */
.mqm-cover-spread::before {
	content: "";
	position: absolute;
	top: 6%;
	bottom: 6%;
	left: 50%;
	width: 1px;
	background: linear-gradient(180deg,
		rgba(14,41,71,0) 0%,
		rgba(14,41,71,0.18) 20%,
		rgba(14,41,71,0.18) 80%,
		rgba(14,41,71,0) 100%);
	transform: translateX(-0.5px);
	pointer-events: none;
	z-index: 5;
}
/* Subtle dark inner-shadow on both pages either side of the fold so the
   book feels physically open. */
.mqm-cover-spread::after {
	content: "";
	position: absolute;
	top: 0; bottom: 0;
	left: calc(50% - 12px);
	width: 24px;
	background: radial-gradient(ellipse at center, rgba(14,41,71,0.12) 0%, rgba(14,41,71,0) 70%);
	pointer-events: none;
	z-index: 4;
}
@media (max-width: 720px) {
	.mqm-cover-preview { grid-template-columns: 1fr; gap: 18px; padding: 16px; }
}
/* Right column — inputs + a short caption. Inputs are CAPPED at 200px so
   they're proportionate to the card height. Breathing room from the cover
   spread comes from the parent grid's gap; `padding-left` is defensive
   against shadow bleed from the spread on the left. */
.mqm-cover-side {
	display: flex;
	flex-direction: column;
	gap: 14px;
	min-width: 0;
	/* Hard cap so the form doesn't grow unbounded when the modal is wide.
	   With the 48px grid gap + 32px container padding, this keeps ≥32px
	   between the rightmost input pixel and the peach container's edge. */
	max-width: 400px;
	width: 100%;
	padding: 0;
	justify-content: center;
}
.mqm-cover-side .mqm-input { width: 100%; max-width: 100%; }
.mqm-cover-side .mqm-fields    { margin: 0; gap: 16px; }
.mqm-cover-side .mqm-row       { display: flex; flex-direction: column; gap: 16px; }
.mqm-cover-side .mqm-field     { width: 100%; min-width: 0; gap: 6px; }
.mqm-cover-side .mqm-meta-sub  { margin: 0 0 4px; }

/* Stacked inputs on Step 2 — child name + family surname each on their own
   row (per user preference). The right column ends up matching the card's
   height naturally, filling vertical space that would otherwise be empty. */
.mqm-fields--stack {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

/* The card itself — sizes to content (no fixed height). Both panels match
   the back-panel min-height so the spread has a clean rectangle aspect. */
.mqm-cover-card {
	position: relative;
	width: 100%;
	max-width: none;
	margin: 0;
	background: var(--mqm-cream);
	border-radius: 0;             /* outer corners handled by .mqm-cover-spread */
	overflow: hidden;
	box-shadow: none;             /* spread has one shared shadow */
	font-family: var(--mqm-font-body);
	color: var(--mqm-navy);
	padding: 18px 14px 18px;
	text-align: center;
	min-height: 280px;
	display: flex;
	flex-direction: column;
}
/* Step 3 + Step 4 card variants — standalone (not in a spread), so they
   need their own shadow + corner radii. Both use the front-cover template.
   STRICT A4 portrait aspect (210 : 297 ≈ 1 : 1.414) — overflow: hidden
   prevents internal content from pushing the card taller, and the photo
   + title + subtitle sizes below are compressed so everything actually
   fits inside the A4 box. */
.mqm-cover-card--step3,
/* When the buy-now flow hides the blank cover card (JS sets [hidden]), the
   card's own display rule would otherwise keep it visible. Force it off. */
.mqm-cover-card[hidden] { display: none !important; }

.mqm-cover-card--step4 {
	max-width: 220px;
	width: 100%;
	aspect-ratio: 210 / 297;
	min-height: 0 !important;
	height: auto;
	margin: 0 auto;
	padding: 10px 10px 12px;
	border-radius: 12px;
	overflow: hidden;
	box-shadow:
		0 16px 36px rgba(185, 132, 212, 0.18),   /* lavender lift */
		0 6px 14px rgba(14, 41, 71, 0.14),
		0 1px 3px rgba(14, 41, 71, 0.06);
}

/* Compact internal sizing for step3/step4 — photo, title and subtitle
   are scaled down so the whole cover fits inside the A4 aspect box. */
.mqm-cover-card--step3 .mqm-cover-card-photo,
.mqm-cover-card--step4 .mqm-cover-card-photo {
	width: 44%;
	margin: 4px auto 6px;
}
.mqm-cover-card--step4 .mqm-cover-card-title {
	font-size: 13px;
	line-height: 1.02;
	margin: 4px 0 3px;
	padding: 0 4px;
}
.mqm-cover-card--step4 .mqm-cover-card-title.is-long {
	font-size: 11.5px;
	line-height: 1.05;
}
.mqm-cover-card--step4 .mqm-cover-card-subtitle {
	font-size: 7px;
	padding: 3px 8px;
	margin: 2px auto 4px;
}
.mqm-cover-card--step3 .mqm-cover-card-personal,
.mqm-cover-card--step4 .mqm-cover-card-personal {
	padding-top: 6px;
	margin: auto 0 2px;
}
.mqm-cover-card--step3 .mqm-cover-card-personal-label,
.mqm-cover-card--step4 .mqm-cover-card-personal-label {
	font-size: 7px;
	letter-spacing: 0.08em;
}

/* Sparkle accent — tiny 4-point lavender star in the top-left corner.
   Counterbalances the peach blob in the top-right so the card has visual
   weight on both shoulders. Lives as a real DOM element (added by the JS
   alongside the photo + title) so we don't trample the card's existing
   ::after, which paints the bottom peach wave. */
.mqm-cover-card-sparkle {
	position: absolute;
	top: 10px;
	left: 12px;
	width: 14px;
	height: 14px;
	color: var(--mqm-purple);
	opacity: 0.85;
	z-index: 2;
	pointer-events: none;
	animation: mqm-card-twinkle 4.5s ease-in-out infinite;
}
.mqm-cover-card-sparkle svg { width: 100%; height: 100%; display: block; }
@keyframes mqm-card-twinkle {
	0%, 100% { opacity: 0.85; transform: scale(1)      rotate(0deg);  }
	50%      { opacity: 1;    transform: scale(1.12)   rotate(8deg);  }
}
@media (prefers-reduced-motion: reduce) {
	.mqm-cover-card-sparkle { animation: none; }
}

/* Subtle entrance — card scales up gently when it lands. The first time a
   step renders this happens organically; we re-trigger by removing/adding
   the `is-fresh` class via JS when the preview is updated, so changing
   the preset feels like the cover is "re-arriving" rather than swapping
   silently. */
.mqm-cover-card--front.is-fresh .mqm-cover-card-title,
.mqm-cover-card--front.is-fresh .mqm-cover-card-photo {
	animation: mqm-card-pop 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes mqm-card-pop {
	0%   { opacity: 0; transform: translateY(6px) scale(0.985); }
	100% { opacity: 1; transform: translateY(0)   scale(1);      }
}
@media (prefers-reduced-motion: reduce) {
	.mqm-cover-card--front.is-fresh .mqm-cover-card-title,
	.mqm-cover-card--front.is-fresh .mqm-cover-card-photo { animation: none; }
}

/* ===== Back-cover mini-preview =====
   Layout per print spec 2026-05-23:
     - Logo: y=55–65 mm — centred, top
     - Tagline "Made to cherish family moments" + one small coral heart:
       y=125–140 (middle, centred, ONE line)
     - QR cluster (lower, aligned with front "Created for" block):
         - "Scan to create / your next book" handwritten LEFT of QR
         - QR centred horizontally on the panel, 28–32mm in print
         - URL "memoricol.com.au" centred directly under QR */
.mqm-cover-card--back {
	display: flex;
	flex-direction: column;
	text-align: center;
	padding: 18px 14px 18px;
	min-height: 280px;
}
.mqm-cover-card--back .mqm-cover-card-wordmark {
	align-self: center;
	margin: 6px 0 28px;
	font-size: 14px;
}
/* Tagline — two centred lines (line break at the comma), ONE small coral
   heart to the right of the trailing word. white-space removed so the
   <br> in the markup can do its job; previously this was nowrap because
   the old tagline ("Made to cherish family moments") was a single line. */
.mqm-cover-card-back-tagline {
	margin: 0 0 auto;
	font: 500 9px/1.3 var(--mqm-font-serif);
	color: var(--mqm-navy);
	letter-spacing: 0.005em;
	text-align: center;
	padding: 0 6px;
}
.mqm-cover-card-back-tagline::after {
	content: " ♥";
	color: var(--mqm-coral);
	font-size: 9px;
	vertical-align: 1px;
}
/* QR cluster — grid: script left, QR centred, blank right (mirror of left
   for visual balance). URL spans full width below. */
.mqm-cover-card-back-foot {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	grid-template-rows: auto auto;
	align-items: center;
	gap: 6px 8px;
	margin-top: 28px;
	padding: 0 4px;
}
.mqm-cover-card-back-scan {
	grid-column: 1;
	grid-row: 1;
	font-family: var(--mqm-font-script);
	font-weight: 400;
	color: var(--mqm-coral);
	font-size: 13px;
	line-height: 1.05;
	text-align: right;
	padding-right: 2px;
	position: relative;
	align-self: end;
	padding-bottom: 4px;
}
/* Curved dashed arrow from script to QR (small inline flourish). */
.mqm-cover-card-back-scan::after {
	content: "";
	position: absolute;
	right: -6px;
	bottom: -4px;
	width: 14px;
	height: 12px;
	border-bottom: 1.2px dashed var(--mqm-coral);
	border-right: 1.2px dashed var(--mqm-coral);
	border-bottom-right-radius: 80%;
	transform: rotate(-20deg);
}
/* QR — inline SVG, navy on white. Sits in grid column 2 (centred). */
.mqm-cover-card-back-qr {
	grid-column: 2;
	grid-row: 1;
	width: 44px;
	height: 44px;
	background-color: #fff;
	border: 1px solid rgba(16, 35, 61, 0.10);
	border-radius: 4px;
	padding: 3px;
	box-sizing: border-box;
	color: var(--mqm-navy);
	box-shadow: 0 2px 6px rgba(16, 35, 61, 0.08);
}
.mqm-cover-card-back-qr svg {
	display: block;
	width: 100%;
	height: 100%;
}
.mqm-cover-card-back-url {
	grid-column: 1 / span 3;
	grid-row: 2;
	font: 600 9px var(--mqm-font-body);
	color: var(--mqm-navy);
	letter-spacing: 0.03em;
	text-align: center;
	margin-top: 6px;
}
/* Top-right peach blob — same energy as the printed cover. */
.mqm-cover-card::before {
	content: "";
	position: absolute;
	right: -28%;
	top: -14%;
	width: 70%;
	height: 42%;
	background: var(--mqm-peach);
	opacity: 0.7;
	border-radius: 50%;
	z-index: 0;
	pointer-events: none;
}
/* Bottom peach wave. */
.mqm-cover-card::after {
	content: "";
	position: absolute;
	left: -20%;
	right: -20%;
	bottom: -14%;
	height: 32%;
	background: var(--mqm-peach-soft);
	border-radius: 50%;
	z-index: 0;
	pointer-events: none;
}
.mqm-cover-card > * { position: relative; z-index: 1; }

/* Wordmark — Fraunces with a coral heart pseudo-element above the dotless ı.
   The ::after is positioned via translateX so it stays centred over the
   dotless letter regardless of font-size. */
.mqm-cover-card-wordmark {
	font-family: var(--mqm-font-serif);
	font-weight: 700;
	font-size: 11px;
	color: var(--mqm-navy);
	letter-spacing: -0.01em;
	margin: 0 0 6px;
	line-height: 1;
	display: inline-block;
}
/* Mirrors the site: the dotless ı is wrapped in its own span, the heart is
   ::after on THAT span — so the heart positioning is relative to the letter,
   not the wordmark as a whole. */
.mqm-cover-card-wordmark .mqm-cover-card-i {
	position: relative;
	display: inline-block;
}
.mqm-cover-card-wordmark .mqm-cover-card-i::after {
	content: "♥";
	position: absolute;
	left: 50%;
	top: 0;
	transform: translate(-50%, -85%);
	font-size: 0.32em;
	color: var(--mqm-coral);
	font-family: var(--mqm-font-body);
	font-weight: 700;
	line-height: 1;
	pointer-events: none;
}

/* Photo zone — 70% of card width at a 3:4 portrait aspect.
   Phone-first: most customer photos arrive as 3:4 (default iPhone / Android
   portrait) or 9:16 (modern phones). A portrait slot fills natively from
   those sources. Landscape photos fall back to smart-fit (top-biased crop
   or contain with cream bands) — see applySmartFit() in the JS. */
/* Photo zone — frameless landscape window (per the approved design, the
   photo sits as a wide horizontal rectangle at the top of the cover, NOT
   a portrait crop). Object-fit: cover so any aspect ratio fills cleanly
   with no cream "frame". */
/* Portrait phone-first photo frame. Most customer uploads are 3:4 / 9:16
   (phone portrait), so the frame mirrors that ratio: 70×90mm in print
   (~7:9 ≈ 0.78), giving full-bleed fills for portrait shots and gentle
   centre crops for landscape ones. */
.mqm-cover-card-photo {
	display: block;
	width: 56%;
	aspect-ratio: 70 / 90;
	height: auto;
	margin: 12px auto 16px;
	border-radius: 6px;
	overflow: hidden;
	background: transparent;
	box-shadow: 0 8px 18px rgba(14, 41, 71, 0.16);
	border: 0;
}
.mqm-cover-card-photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center center;   /* JS may override via applySmartFit */
}
.mqm-cover-card-photo .mqm-cover-card-empty {
	width: 100%;
	height: 100%;
}
.mqm-cover-card-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.mqm-cover-card-empty {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%; height: 100%;
	color: var(--mqm-muted);
	font: 500 11px var(--mqm-font-body);
	text-align: center;
	padding: 12px;
	background: repeating-linear-gradient(45deg, #FCEEDC 0 6px, #FFF7EE 6px 12px);
}

/* Title block. Three stacked lines, each on its own row. Lines now WRAP
   instead of nowrap — long preset titles like "Happy Mother's Day" or
   "Happy Father's Day" overflowed the card with the old nowrap rule and
   got clipped by overflow:hidden. `text-wrap: balance` keeps multi-line
   wraps visually centred. The JS toggles `.is-long` on cards whose title1
   is >12 chars so the font also shrinks a touch for those cases. */
.mqm-cover-card-title {
	margin: 6px 0 4px;
	font-family: var(--mqm-font-serif);
	font-weight: 700;
	color: var(--mqm-navy);
	line-height: 1.1;
	letter-spacing: -0.015em;
	font-size: 18px;
	text-wrap: balance;
	padding: 0 6px;               /* breathing room from the card edges */
}
.mqm-cover-card-title .line-1,
.mqm-cover-card-title .line-2,
.mqm-cover-card-title .line-3 {
	display: block;
	overflow-wrap: break-word;
}
.mqm-cover-card-title .line-2 {
	font-weight: 500;
	font-style: italic;
}
.mqm-cover-card-title .line-3 {
	color: var(--mqm-coral);
	font-weight: 700;
}
/* Auto-shrink for long titles. Triggered by the JS adding `.is-long` to
   the title block when title_line1 > 12 chars. Picks up presets like
   "Happy Mother's Day" / "Happy Father's Day". */
.mqm-cover-card-title.is-long              { font-size: 14.5px; line-height: 1.12; }
.mqm-cover-card-title.is-long .line-1      { letter-spacing: -0.02em; }
.mqm-cover-card-title.is-long .line-3      { font-size: 15.5px; margin-top: 2px; }
/* Heart accent — sits inline after line-1 so it follows the natural text
   flow. Previously absolute-positioned at `left: 100%`, which orphaned
   the heart on its own line when line-1 wrapped. Now it sits as a real
   inline character at the end of the (possibly multi-line) title block. */
.mqm-cover-card-title .line-1 {
	display: block;
}
.mqm-cover-card-title .line-1::after {
	content: " ♥";
	font-family: var(--mqm-font-body);
	font-style: normal;
	font-weight: 700;
	font-size: 0.5em;
	margin-left: 0.18em;
	letter-spacing: 0.15em;
	color: var(--mqm-coral);
	line-height: 1;
	vertical-align: 0.35em;
}

/* Subtitle pill. */
.mqm-cover-card-subtitle {
	display: inline-block;
	margin: 4px auto 6px;
	padding: 3px 9px;
	background: var(--mqm-peach);
	color: var(--mqm-navy);
	border-radius: 999px;
	font-size: 7px;
	font-weight: 500;
	letter-spacing: 0.01em;
	line-height: 1.35;
	max-width: 95%;
}

/* Personalisation block — "Created for / [name] ♥ / & The [Family] Family".
   Sits in the lower section of the front cover with breathing room above. */
.mqm-cover-card-personal {
	margin: auto 0 6px;
	padding-top: 12px;
}
.mqm-cover-card-personal-label {
	display: block;
	font-size: 9px;
	font-weight: 700;
	color: var(--mqm-navy);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}
.mqm-cover-card-personal-name {
	display: inline-block;
	font-family: var(--mqm-font-script);
	font-weight: 400;
	color: var(--mqm-coral);
	font-size: 24px;
	line-height: 1;
	margin: 4px 0 2px;
	position: relative;
}
.mqm-cover-card-personal-name::after {
	content: " ♥";
	font-family: var(--mqm-font-body);
	font-size: 0.32em;
	margin-left: 0.15em;
	vertical-align: 0.55em;
	color: var(--mqm-coral);
}
.mqm-cover-card-personal-family {
	display: block;
	font-family: var(--mqm-font-serif);
	font-weight: 600;
	color: var(--mqm-navy);
	font-size: 11px;
	margin-top: 2px;
	letter-spacing: 0.01em;
}
/* Empty personalisation slots collapse cleanly — when the customer hasn't
   typed a child name or family yet, the span renders with no text content,
   :empty matches, and `display: none` hides the span (which also drops the
   heart ::after pseudo-element since it can't render on a hidden parent).
   Prevents the cover from literally reading "your child ♥" before any
   name is entered. */
.mqm-cover-card-personal-name:empty,
.mqm-cover-card-personal-family:empty {
	display: none;
}

/* Right column — short caption telling the customer what they're looking at. */
.mqm-cover-meta-label {
	font: 700 10.5px var(--mqm-font-body);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--mqm-coral);
	margin: 0 0 6px;
}

/* Step 2 — preset dropdown gets a small dashed underline so it visually
   groups with the form below it as "your cover voice" rather than reading
   as a category filter. The custom-only fields get a subtle indent + left
   border so they read as "more options" rather than primary inputs. */
[data-mqm-preset] {
	/* Slight emphasis — the dropdown is the most impactful control here. */
	font-weight: 600;
}
.mqm-custom-field {
	border-left: 2px solid rgba(255, 84, 112, 0.22);
	padding-left: 10px;
	margin-left: 2px;
}
.mqm-custom-field:not([hidden]) ~ .mqm-custom-field {
	/* Tighter spacing between contiguous custom fields. */
	margin-top: 6px;
}
/* HTML5's [hidden] attribute sets display:none by default — but our
   `.mqm-field { display: flex }` rule above wins specificity and forces the
   field visible. Restore the intended behaviour for ANY field carrying the
   hidden attribute. !important is the cleanest fix without rewriting the
   field rule. */
.mqm-field[hidden],
.mqm-custom-field[hidden] {
	display: none !important;
}
.mqm-cover-meta-title {
	font-family: var(--mqm-font-serif);
	font-weight: 700;
	font-size: 22px;
	line-height: 1.15;
	color: var(--mqm-navy);
	margin: 0 0 8px;
	letter-spacing: -0.012em;
}
.mqm-cover-meta-sub {
	font: 400 14px/1.5 var(--mqm-font-body);
	color: var(--mqm-muted);
	margin: 0;
}

/* ---------- Fields — elegant treatment ----------
   Labels: small caps Fraunces (the editorial serif), letter-spaced.
   Inputs: soft cream fill (sits naturally against the warm modal bg),
   hairline border, gentle inner shadow on rest, coral glow on focus.
   The whole block breathes a little more than the previous compact look. */
.mqm-fields {
	display: grid;
	gap: 18px;
}
.mqm-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14px;
}
.mqm-field { display: flex; flex-direction: column; gap: 7px; }
.mqm-label {
	font: 600 11px/1 "Fraunces", "Inter", serif;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--mqm-navy, #10233D);
	padding-left: 2px;
}
.mqm-label-hint,
.mqm-label-opt {
	font-weight: 400;
	letter-spacing: 0.04em;
	text-transform: none;
	color: var(--mqm-ink-soft);
	margin-left: 6px;
	font-size: 11px;
	font-style: italic;
	font-family: "Fraunces", serif;
}

/* Inline hint shown under the address input once Places autocomplete loads. */
.mqm-field-hint {
	font: 400 12px/1.4 "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	margin: 4px 2px 0;
	letter-spacing: 0.01em;
}

/* Style the Google Places autocomplete dropdown so it matches the modal.
   z-index MUST be higher than the modal overlay (9999) — Google's default
   is 1000 which means the dropdown gets painted behind the modal and
   appears invisible. 10001 puts it cleanly on top. */
.pac-container {
	z-index: 10001 !important;
	border-radius: 12px;
	margin-top: 4px;
	box-shadow: 0 12px 28px rgba(14, 41, 71, 0.16), 0 3px 8px rgba(14, 41, 71, 0.08);
	border: 1px solid rgba(16, 35, 61, 0.10);
	font-family: "Inter", sans-serif;
	overflow: hidden;
}
.pac-item {
	padding: 10px 14px;
	font-size: 13.5px;
	color: var(--mqm-ink, #10233D);
	border-top: 1px solid rgba(16, 35, 61, 0.06);
	cursor: pointer;
}
.pac-item:first-child { border-top: 0; }
.pac-item:hover { background: rgba(255, 84, 112, 0.06); }
.pac-item-query { font-weight: 600; color: var(--mqm-ink, #10233D); }
.pac-matched { font-weight: 700; }
.pac-icon { display: none; }
.pac-item-selected { background: rgba(255, 84, 112, 0.10); }

/* ---------- Stripe Elements (card field on Step 4) ---------- */
.mqm-pay {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin-top: 4px;
	padding-bottom: 6px;
	border-bottom: 1px dashed rgba(16, 35, 61, 0.10);
	margin-bottom: 10px;
}
.mqm-stripe-mount {
	background: rgba(255, 255, 255, 0.92);
	border: 1px solid rgba(16, 35, 61, 0.12);
	border-radius: 10px;
	padding: 14px 14px;
	min-height: 50px;
	transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}
.mqm-stripe-mount:focus-within {
	background: #fff;
	border-color: rgba(255, 84, 112, 0.45);
	box-shadow: 0 0 0 3px rgba(255, 84, 112, 0.18);
}
.mqm-stripe-placeholder {
	font: 400 13px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	letter-spacing: 0.01em;
}
.mqm-stripe-placeholder--missing {
	color: #8c4f1a;
	background: #fff3e0;
	padding: 10px 12px;
	border-radius: 6px;
	font-size: 12.5px;
}
.mqm-pay-error {
	font: 500 12.5px "Inter", sans-serif;
	color: #c43a4e;
	margin: 0;
}
.mqm-pay-testnote {
	font: 400 12px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	margin: 0;
	font-style: italic;
}
.mqm-pay-testnote code {
	background: rgba(16, 35, 61, 0.06);
	padding: 1px 5px;
	border-radius: 4px;
	font: 600 11.5px ui-monospace, monospace;
	letter-spacing: 0;
}

/* ---------- Payment Request Button (Apple/Google Pay) ----------
   Section is hidden by default (via `hidden` HTML attribute) and revealed
   only when Stripe's canMakePayment() returns truthy. The button itself
   is injected by Stripe — we just style the wrapper + the "or" divider. */
.mqm-prb {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 4px;
}
.mqm-prb[hidden] { display: none; }
.mqm-prb-mount {
	min-height: 44px;
}
.mqm-pay-divider {
	display: flex;
	align-items: center;
	gap: 10px;
	font: 500 11px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	margin: 2px 0;
}
.mqm-pay-divider::before,
.mqm-pay-divider::after {
	content: "";
	flex: 1;
	height: 1px;
	background: rgba(16, 35, 61, 0.10);
}
.mqm-pay-divider span {
	white-space: nowrap;
}

/* ---------- Payment trust line ----------
   Small lock icon + provider line. Subtle so it doesn't compete with the
   card field but visible enough to read as reassurance. */
.mqm-pay-trust {
	display: flex;
	align-items: center;
	gap: 7px;
	font: 500 11.5px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	letter-spacing: 0.01em;
	margin-top: 4px;
}
.mqm-pay-trust-icon {
	width: 14px;
	height: 14px;
	color: var(--mqm-ink-soft);
	flex-shrink: 0;
}

/* Hide the "Powered by Google" badge.
   Note: this is technically against Google's Places API ToS unless a Google
   Map is also displayed on the page. Enforcement is essentially nil but the
   risk exists — if Google ever changes their stance we restore the badge by
   removing the rules below. */
.pac-container::after {
	display: none !important;
	height: 0 !important;
}
.pac-logo::after {
	display: none !important;
}
.mqm-input,
.mqm-textarea {
	appearance: none;
	width: 100%;
	border: 1px solid rgba(16, 35, 61, 0.12);
	border-radius: 12px;
	background: #FFFCF8;
	padding: 13px 16px;
	font: 500 15px/1.35 "Inter", sans-serif;
	color: var(--mqm-navy, #10233D);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.8),
		0 1px 2px rgba(16, 35, 61, 0.04);
	transition: border-color 160ms ease, box-shadow 200ms ease, background 160ms ease;
}
.mqm-input::placeholder,
.mqm-textarea::placeholder {
	color: rgba(16, 35, 61, 0.32);
	font-weight: 400;
	font-style: italic;
}
.mqm-input:hover,
.mqm-textarea:hover {
	border-color: rgba(16, 35, 61, 0.22);
	background: #FFFFFF;
}
.mqm-input:focus,
.mqm-textarea:focus {
	outline: none;
	border-color: var(--mqm-coral, #F25B76);
	background: #FFFFFF;
	box-shadow:
		0 0 0 3px rgba(242, 91, 118, 0.18),
		inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.mqm-textarea { resize: vertical; min-height: 70px; font-family: "Inter", sans-serif; }

/* ---------- Step 4 checkout — single coloured frame, two columns inside ----------
   The whole frame uses the warm gradient. Book + meta sit on the left,
   form fills the right. On narrow viewports the columns stack vertically. */
.mqm-checkout-grid {
	display: grid;
	grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
	gap: 32px;
	align-items: start;
	padding: 0;
	border-radius: 0;
	background: transparent;
	margin-bottom: 18px;
	position: relative;
	overflow: visible;
}

.mqm-checkout-aside {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	background: transparent;
	padding: 0;
	position: sticky;
	top: 16px;
}

.mqm-checkout-aside .mqm-summary-info {
	text-align: center;
	width: 100%;
	min-width: 0;
}

/* =========================================================================
   Buy-now "reserved book / add photos later" hero
   Shown only in the buy-now flow (JS toggles [hidden]). Replaces the blank
   cover card so the missing photo/name reads as intentional, not broken.
   ========================================================================= */
.mqm-buynow-preview {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	width: 100%;
	gap: 8px;
}
.mqm-buynow-preview[hidden] { display: none; }

/* Soft circular badge: pink camera + heart, faint photo shapes behind,
   sparkle accent, "Reserved" tag. */
.mqm-reserved {
	position: relative;
	width: 112px;
	height: 112px;
	margin: 2px 0;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background:
		radial-gradient(circle at 50% 38%, #FFFFFF 0%, var(--mqm-cream) 55%, var(--mqm-peach) 100%);
	box-shadow:
		0 16px 30px rgba(16, 35, 61, 0.14),
		0 4px 10px rgba(16, 35, 61, 0.08),
		inset 0 0 0 6px rgba(255, 255, 255, 0.6);
}

/* Faint photo placeholder shapes tucked behind the disc. */
.mqm-reserved-ph {
	position: absolute;
	width: 36px;
	height: 36px;
	border-radius: 8px;
	background: rgba(255, 255, 255, 0.85);
	border: 1.5px solid var(--mqm-peach-soft);
	box-shadow: 0 6px 12px rgba(16, 35, 61, 0.08);
}
.mqm-reserved-ph--1 { top: 12px;  left: 8px;   transform: rotate(-14deg); opacity: 0.85; }
.mqm-reserved-ph--2 { top: 8px;   right: 10px; transform: rotate(11deg);  opacity: 0.7; }
.mqm-reserved-ph--3 { bottom: 10px; right: 16px; transform: rotate(-7deg); opacity: 0.55; }

/* The pink camera disc that sits front-and-centre. */
.mqm-reserved-disc {
	position: relative;
	z-index: 2;
	width: 60px;
	height: 60px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: linear-gradient(150deg, #FFFFFF 0%, #FFF1F3 100%);
	box-shadow:
		0 10px 20px rgba(242, 91, 118, 0.22),
		inset 0 0 0 3px rgba(255, 255, 255, 0.9);
}
.mqm-reserved-cam {
	width: 34px;
	height: 34px;
	color: var(--mqm-coral);
}
.mqm-reserved-heart { color: var(--mqm-coral); }

/* Sparkle accent, top-right of the badge. */
.mqm-reserved-sparkle {
	position: absolute;
	z-index: 3;
	top: 6px;
	right: 8px;
	width: 22px;
	height: 22px;
	color: var(--mqm-coral);
	filter: drop-shadow(0 2px 3px rgba(242, 91, 118, 0.25));
}
.mqm-reserved-sparkle svg { width: 100%; height: 100%; display: block; }

/* "Reserved" pill, bottom-centre of the badge. */
.mqm-reserved-tag {
	position: absolute;
	z-index: 3;
	bottom: -6px;
	left: 50%;
	transform: translateX(-50%);
	padding: 3px 12px;
	border-radius: 999px;
	background: var(--mqm-navy);
	color: #fff;
	font: 700 9px/1 var(--mqm-font-body);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	box-shadow: 0 4px 10px rgba(16, 35, 61, 0.2);
}

.mqm-buynow-headline {
	margin: 4px 0 0;
	font: 600 16px/1.15 var(--mqm-font-serif);
	color: var(--mqm-navy);
	letter-spacing: -0.012em;
}
.mqm-buynow-copy {
	margin: 0;
	max-width: 240px;
	font: 400 12px/1.45 var(--mqm-font-body);
	color: var(--mqm-ink-soft);
}

/* 3 compact step pills: Pay today / Get upload link / Add photos + name. */
.mqm-buynow-steps {
	display: flex;
	flex-direction: column;
	gap: 5px;
	width: 100%;
	margin-top: 1px;
}
.mqm-buynow-step {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 5px 11px;
	border-radius: 10px;
	background: rgba(255, 255, 255, 0.7);
	border: 1px solid var(--mqm-peach-soft);
	font: 600 11.5px/1.2 var(--mqm-font-body);
	color: var(--mqm-navy);
	text-align: left;
}
.mqm-buynow-step-n {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: var(--mqm-coral);
	color: #fff;
	font: 700 9.5px/1 var(--mqm-font-body);
}

/* Buy-now: the reserved hero + headline already say "your book", so drop the
   duplicate "Your book" kicker and the "My favourite colouring book" title
   from the summary block, and pull the product line + price up tight. Keeps
   the price visible without scrolling. */
.mqm-mode-buynow .mqm-summary-kicker,
.mqm-mode-buynow [data-mqm-summary-title] {
	display: none;
}
.mqm-mode-buynow .mqm-summary-meta {
	margin-top: 6px;
}
.mqm-mode-buynow .mqm-summary-pricing {
	margin-top: 8px;
	padding-top: 8px;
}

.mqm-checkout-form {
	min-width: 0;
	/* Slightly tighter row gap inside the form so it visually balances the
	   compact aside on the left. */
	gap: 12px;
}

/* ----- Pricing breakdown in Step 4 summary aside -----
   Lives below the cover title/meta in the .mqm-summary-info column.
   Shows base price, optional voucher discount line (hidden until applied),
   and total. Updates live via updatePricingDisplay(). */
.mqm-summary-pricing {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px dashed rgba(14, 41, 71, 0.16);
	font: 500 12.5px/1.4 var(--mqm-font-body);
	color: var(--mqm-navy);
}
.mqm-summary-line {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	padding: 2px 0;
}
.mqm-summary-line--discount {
	color: #2f7a2f;
	font-weight: 600;
}
.mqm-summary-line--total {
	margin-top: 6px;
	padding-top: 6px;
	border-top: 1px solid rgba(14, 41, 71, 0.10);
	font: 700 14px/1.2 var(--mqm-font-body);
	color: var(--mqm-navy);
}
.mqm-summary-fineprint {
	margin: 6px 0 0;
	font-size: 10.5px;
	color: rgba(14, 41, 71, 0.55);
	font-style: italic;
}

/* ----- Promo code field (Step 4 — Check out) -----
   Inline input + Apply button row. Field-hint below shows live validation
   feedback in green (.is-ok) or coral-deep (.is-error). */
.mqm-promo-row {
	display: flex;
	gap: 8px;
	align-items: stretch;
}
.mqm-promo-row .mqm-input {
	flex: 1;
	min-width: 0;
	text-transform: uppercase;       /* visually nudges customers to type uppercase codes */
	letter-spacing: 0.04em;
}
.mqm-btn-promo {
	flex-shrink: 0;
	border: 0;
	border-radius: 999px;
	padding: 0 18px;
	min-height: 38px;
	font: 600 13px/1 var(--mqm-font-body);
	color: #fff;
	background: var(--mqm-coral, #F35C78);
	cursor: pointer;
	transition: background 160ms ease, transform 120ms ease;
}
.mqm-btn-promo:hover { background: #d94b65; }
.mqm-btn-promo:active { transform: translateY(1px); }
.mqm-btn-promo:disabled {
	background: #d9d9d9;
	cursor: default;
}
.mqm-field-hint.is-ok    { color: #2f7a2f; font-weight: 600; }
.mqm-field-hint.is-error { color: #c62853; font-weight: 600; }

/* Form inputs sit on the gradient background — soften their fill so the
   warm tones show through and the inputs don't feel like a separate UI
   tray glued on top of the frame. */
.mqm-checkout-form .mqm-input,
.mqm-checkout-form .mqm-textarea {
	background: rgba(255, 255, 255, 0.78);
}
.mqm-checkout-form .mqm-input:focus,
.mqm-checkout-form .mqm-textarea:focus {
	background: #ffffff;
}

/* Below ~720px (small tablets / phones) — collapse to single column,
   book aside above form. Book + meta sit side-by-side for compactness. */
@media (max-width: 720px) {
	.mqm-checkout-grid {
		grid-template-columns: 1fr;
		gap: 22px;
		padding: 20px;
	}
	.mqm-checkout-aside {
		flex-direction: row;
		align-items: center;
		gap: 18px;
		position: static;
	}
	.mqm-checkout-aside .mqm-cover-card--step4 {
		flex: 0 0 160px;
	}
	.mqm-checkout-aside .mqm-summary-info {
		text-align: left;
	}
	/* Buy-now flow: keep the reserved hero stacked ABOVE the order summary
	   (not side-by-side) so the 3 mini steps stay readable on phones. */
	.mqm-mode-buynow .mqm-checkout-aside {
		flex-direction: column;
		align-items: center;
	}
	.mqm-mode-buynow .mqm-checkout-aside .mqm-summary-info {
		text-align: center;
	}
	.mqm-buynow-preview { width: 100%; }
	.mqm-buynow-steps { max-width: 320px; margin-left: auto; margin-right: auto; }
}

/* Tiny phones — stack the in-aside row back to vertical so the book stays
   readable rather than getting squished. */
@media (max-width: 480px) {
	.mqm-checkout-aside {
		flex-direction: column;
	}
	.mqm-checkout-aside .mqm-summary-info {
		text-align: center;
	}
}

/* Legacy .mqm-summary class kept as alias in case it's still referenced. */
.mqm-summary { display: contents; }

.mqm-summary-cover {
	position: relative;
	width: 116px;
	aspect-ratio: 3 / 4;
	border-radius: 4px 8px 8px 4px;
	overflow: hidden;
	background: #FFF6E9;
	box-shadow:
		0 20px 36px rgba(15, 27, 45, 0.26),
		0 6px 14px rgba(15, 27, 45, 0.10),
		inset 4px 0 0 rgba(15, 27, 45, 0.10);
	transform: rotate(-2.5deg);
}
.mqm-summary-cover-canvas { display: block; width: 100%; height: 100%; }

.mqm-summary-cover-overlay {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;                              /* aligned with the big preview overlay — title at top in both */
	padding: 8px 10px 18px;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 100%);
	border-radius: 0;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	text-align: center;
}
.mqm-summary-cover-title {
	font: 600 9.5px/1.15 "Fraunces", serif;
	color: var(--mqm-ink);
	margin: 0;
	letter-spacing: -0.012em;
	text-shadow: 0 1px 1.5px rgba(255, 255, 255, 0.65);
}
.mqm-summary-cover-sub {
	font: 500 7.5px "Inter", sans-serif;
	color: var(--mqm-rose-deep);
	margin: 3px 0 0;
	font-style: italic;
	text-shadow: 0 1px 1.5px rgba(255, 255, 255, 0.65);
	letter-spacing: 0.02em;
}
.mqm-summary-cover-sub:empty { display: none; }

.mqm-summary-info { min-width: 0; }
.mqm-summary-kicker {
	font: 700 10px "Inter", sans-serif;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--mqm-rose-deep);
	margin: 0 0 4px;
}
.mqm-summary-info h4 {
	margin: 0 0 4px;
	font: 600 17px "Fraunces", serif;
	color: var(--mqm-ink);
	letter-spacing: -0.012em;
}
.mqm-summary-meta {
	font: 400 13px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	margin: 0;
}

/* ---------- Privacy banner (step 1 + 3) ---------- */
.mqm-privacy {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 12px 14px;
	background: rgba(63, 193, 184, 0.10);
	border: 1px solid rgba(63, 193, 184, 0.30);
	border-radius: 10px;
	margin: 18px 0 6px;
	font: 500 13px/1.5 "Inter", sans-serif;
	color: var(--mqm-ink);
}
.mqm-privacy svg { flex-shrink: 0; width: 18px; height: 18px; color: var(--mqm-turquoise); margin-top: 1px; }
.mqm-privacy strong { color: var(--mqm-ink); font-weight: 700; }

/* ---------- Footer (actions) ---------- */
.mqm-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 16px 22px 18px;
	border-top: 1px solid var(--mqm-line);
	background: #FFFCF6;
}
.mqm-foot-hint {
	font: 500 13px "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	margin: 0;
	flex: 1;
}
.mqm-foot-hint.is-err { color: var(--mqm-rose-deep); }
.mqm-btn {
	appearance: none;
	border: 0;
	border-radius: 999px;
	padding: 0 22px;
	height: 46px;
	font: 600 14.5px "Inter", sans-serif;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	transition: transform 140ms ease, box-shadow 140ms ease, background 160ms ease, color 160ms ease;
}
.mqm-btn-primary {
	background: var(--mqm-rose);
	color: #fff;
	box-shadow: 0 10px 22px rgba(255, 84, 112, 0.32);
}
.mqm-btn-primary:hover { background: var(--mqm-rose-deep); transform: translateY(-1px); box-shadow: 0 14px 28px rgba(198, 40, 83, 0.34); }
.mqm-btn-primary:disabled {
	background: #E9DDC5;
	color: #aaa39a;
	cursor: not-allowed;
	box-shadow: none;
	transform: none;
}
.mqm-btn-ghost {
	background: transparent;
	color: var(--mqm-ink);
	padding: 0 14px;
}
.mqm-btn-ghost:hover { background: rgba(15, 27, 45, 0.05); }
.mqm-btn svg { width: 16px; height: 16px; }
.mqm-btn .mqm-spinner {
	width: 16px; height: 16px;
	border: 2px solid rgba(255,255,255,0.4);
	border-top-color: #fff;
	border-radius: 50%;
	animation: mqm-spin 700ms linear infinite;
}
@keyframes mqm-spin { to { transform: rotate(360deg); } }

/* ---------- Success state ---------- */
.mqm-success {
	display: none;
	text-align: center;
	padding: 30px 8px 8px;
	animation: mqm-fade 320ms ease both;
}
.mqm-success.is-active { display: block; }
.mqm-success-tick {
	width: 76px;
	height: 76px;
	margin: 0 auto 16px;
	border-radius: 50%;
	background: var(--mqm-success);
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 16px 38px rgba(43, 181, 115, 0.40);
	animation: mqm-pop 360ms cubic-bezier(.2,.9,.3,1.4) both;
}
.mqm-success-tick svg { width: 36px; height: 36px; }
.mqm-success h3 {
	font-family: "Fraunces", serif;
	font-weight: 600;
	font-size: 28px;
	color: var(--mqm-ink);
	margin: 0 0 8px;
}
.mqm-success p {
	font: 400 15px/1.55 "Inter", sans-serif;
	color: var(--mqm-ink-soft);
	margin: 0 auto 18px;
	max-width: 44ch;
}
.mqm-success-id {
	display: inline-block;
	margin-top: 6px;
	padding: 6px 14px;
	background: #FFF6E9;
	border: 1px solid var(--mqm-line);
	border-radius: 999px;
	font: 600 13px "Inter", sans-serif;
	letter-spacing: 0.04em;
	color: var(--mqm-ink);
}

/* ---------- Mobile ---------- */
@media (max-width: 640px) {
	.mqm-overlay { padding: 0; }
	.mqm-shell { border-radius: 18px 18px 0 0; max-height: 100vh; height: 100vh; align-self: flex-end; }
	.mqm-overlay { align-items: flex-end; }
	.mqm-head { padding: 14px 16px; }
	.mqm-body { padding: 22px 18px 10px; }
	.mqm-foot { padding: 14px 16px; flex-wrap: wrap; }
	.mqm-foot-hint { flex: 1 1 100%; order: 3; margin-top: 4px; }
	.mqm-row { grid-template-columns: 1fr; }
	.mqm-step-label { display: none; }
	.mqm-cover-preview { grid-template-columns: 1fr; gap: 16px; padding: 16px; }
	.mqm-cover-meta-title { font-size: 18px; }
	.mqm-title { font-size: 22px; }
	.mqm-grid { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 8px; }
	.mqm-style-cards--row { grid-template-columns: 1fr; }
	.mqm-preview-stage { grid-template-columns: 1fr; gap: 18px; }
	.mqm-preview-book { max-width: 200px; align-self: center; margin: 0 auto; }
	.mqm-book-spread { max-width: 340px; }
	.mqm-privacy-pill {
		position: static;
		margin-bottom: 10px;
		font-size: 11px;
		padding: 5px 12px 5px 9px;
	}
	.mqm-privacy-pill strong { display: none; }
}

/* =============================================================================
   DUAL-MODE: segmented toggle + Plan step + tiered sizing (added 2026-06-09)
   The toggle sits on its own row at the top of the head; the Plan step lets
   the customer pick edition + size and see the price before anything else.
   ========================================================================== */
.mqm-head { flex-wrap: wrap; }
.mqm-modetoggle {
	order: -1;
	flex-basis: 100%;
	display: flex;
	gap: 4px;
	padding: 4px;
	background: var(--mqm-peach-soft);
	border-radius: 999px;
}
.mqm-modetoggle-opt {
	flex: 1;
	appearance: none;
	border: 0;
	background: transparent;
	padding: 9px 14px;
	border-radius: 999px;
	font: 700 13.5px var(--mqm-font-body);
	color: var(--mqm-muted);
	cursor: pointer;
	transition: background 180ms ease, color 180ms ease, box-shadow 180ms ease;
}
.mqm-modetoggle-opt.is-active {
	background: #fff;
	color: var(--mqm-ink);
	box-shadow: 0 4px 12px rgba(16, 35, 61, 0.12);
}

/* Edition toggle (Printed / Digital) */
.mqm-edition {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 10px;
	margin: 6px 0 18px;
}
.mqm-edition-opt {
	appearance: none;
	text-align: left;
	border: 2px solid var(--mqm-line);
	background: #fff;
	border-radius: 14px;
	padding: 12px 14px;
	cursor: pointer;
	display: flex;
	flex-direction: column;
	gap: 2px;
	transition: border-color 160ms ease, box-shadow 160ms ease;
}
.mqm-edition-opt.is-active {
	border-color: var(--mqm-coral);
	box-shadow: 0 6px 18px rgba(243, 92, 120, 0.18);
}
.mqm-edition-name { font: 700 15px var(--mqm-font-body); color: var(--mqm-ink); }
.mqm-edition-desc { font: 500 12.5px var(--mqm-font-body); color: var(--mqm-muted); }

/* Printed is Australia-only. When the plan-step country is outside AU, the
   printed option is disabled and reads as unavailable. */
.mqm-edition-opt.is-disabled,
.mqm-edition-opt:disabled {
	opacity: 0.5;
	cursor: not-allowed;
	filter: grayscale(0.45);
	box-shadow: none;
}

/* Delivery-country selector on the plan step, above the edition toggle. */
.mqm-plan-country {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0 0 14px;
}
.mqm-plan-country .mqm-label { margin: 0; }
.mqm-plan-country .mqm-select {
	max-width: 260px;
	background-color: #fff;
	cursor: pointer;
}

/* Size cards (Moment / Story / Heirloom) */
.mqm-sizes {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 12px;
}
.mqm-size {
	position: relative;
	appearance: none;
	text-align: left;
	border: 2px solid var(--mqm-line);
	background: #fff;
	border-radius: 16px;
	padding: 16px 16px 18px;
	cursor: pointer;
	display: flex;
	flex-direction: column;
	gap: 3px;
	transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}
.mqm-size:hover { transform: translateY(-2px); }
.mqm-size.is-active {
	border-color: var(--mqm-coral);
	box-shadow: 0 10px 24px rgba(243, 92, 120, 0.2);
}
.mqm-size-name { font: 700 16px var(--mqm-font-serif); color: var(--mqm-ink); }
.mqm-size-photos { font: 600 12.5px var(--mqm-font-body); color: var(--mqm-muted); }
.mqm-size-price { font: 800 22px var(--mqm-font-body); color: var(--mqm-coral); margin-top: 6px; }
.mqm-size-blurb { font: 500 12px var(--mqm-font-body); color: var(--mqm-muted); margin-top: 4px; }
.mqm-size-tick {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var(--mqm-coral);
	color: #fff;
	display: none;
	align-items: center;
	justify-content: center;
}
.mqm-size-tick svg { width: 14px; height: 14px; }
.mqm-size.is-active .mqm-size-tick { display: inline-flex; }
.mqm-plan-note {
	margin: 16px 0 0;
	font: 500 13px var(--mqm-font-body);
	color: var(--mqm-muted);
}

/* Parental-consent checkbox at checkout */
.mqm-consent {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	margin-top: 8px;
	font: 500 13px var(--mqm-font-body);
	color: var(--mqm-muted);
	cursor: pointer;
}
.mqm-consent input {
	margin-top: 3px;
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
	accent-color: var(--mqm-coral);
}
.mqm-consent a { color: var(--mqm-ink); text-decoration: underline; }

/* Success CTA (buy-now "add your photos now" link) */
.mqm-success-cta {
	margin-top: 10px;
	text-decoration: none;
	align-self: center;
}

/* Buy-now mode hides the photo-dependent UI on the cover + age steps. */
.mqm-mode-buynow [data-mqm-cover-carousel],
.mqm-mode-buynow .mqm-preview-stage,
.mqm-mode-buynow .mqm-preview-heading,
.mqm-mode-buynow .mqm-cover-card-photo {
	display: none !important;
}

/* Locked personalisation mode (returning buy-now customer adding photos to a
   paid order). The tier is fixed and the order is already paid, so we hide the
   mode toggle, the entire payment/details form, the consent box and the price
   breakdown. The checkout step becomes a single-column "review & send" card. */
.mqm-mode-personalise .mqm-modetoggle,
.mqm-mode-personalise .mqm-checkout-form,
.mqm-mode-personalise [data-mqm-summary-pricing] {
	display: none !important;
}
.mqm-mode-personalise .mqm-checkout-grid {
	grid-template-columns: 1fr;
	max-width: 420px;
	margin-inline: auto;
}

@media (max-width: 560px) {
	.mqm-sizes { grid-template-columns: 1fr; }
	.mqm-edition { grid-template-columns: 1fr; }
}

/* =========================================================================
   Checkout redesign 2026-07 — lighter white cards, horizontal step rail,
   icon meta row, footer trust line. Applies to Step 4 (both flows).
   ========================================================================= */
[data-step="4"] .mqm-checkout-grid { padding: 0; gap: 22px; }

/* Two clean white cards on the modal's light background. */
.mqm-checkout-aside,
.mqm-checkout-form {
	background: #fff;
	border: 1px solid var(--mqm-line);
	border-radius: 18px;
	padding: 22px 20px;
	box-shadow: 0 12px 30px rgba(16, 35, 61, 0.06);
}
.mqm-checkout-aside { position: sticky; top: 12px; }
.mqm-mode-buynow .mqm-buynow-preview { width: 100%; }

/* Softer input fills so they read as fields on the white card. */
.mqm-checkout-form .mqm-input,
.mqm-checkout-form .mqm-textarea { background: #FAF6F0; }
.mqm-checkout-form .mqm-input:focus,
.mqm-checkout-form .mqm-textarea:focus { background: #fff; }

/* Horizontal step rail: number circle on top, label below, chevrons between. */
.mqm-buynow-steps {
	flex-direction: row;
	gap: 0;
	align-items: flex-start;
	justify-content: space-between;
	width: 100%;
	margin-top: 6px;
	padding: 12px 6px;
	border: 1px solid var(--mqm-line);
	border-radius: 14px;
	background: #fff;
}
.mqm-buynow-step {
	position: relative;
	flex: 1 1 0;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 0 6px;
	border: 0;
	background: transparent;
	text-align: center;
	font: 600 11px/1.25 var(--mqm-font-body);
	color: var(--mqm-navy);
}
.mqm-buynow-step-n { width: 22px; height: 22px; font-size: 11px; }
.mqm-buynow-step:not(:last-child)::after {
	content: '';
	position: absolute;
	top: 7px;
	right: -5px;
	width: 7px;
	height: 7px;
	border-top: 2px solid var(--mqm-peach);
	border-right: 2px solid var(--mqm-peach);
	transform: rotate(45deg);
}

/* Product meta as a 3-item icon row (book / edition / personalise window). */
.mqm-summary-meta--chips {
	display: flex;
	align-items: stretch;
	justify-content: space-between;
	gap: 4px;
	width: 100%;
	margin-top: 12px;
	padding: 10px 4px;
	border: 1px solid var(--mqm-line);
	border-radius: 14px;
	background: #fff;
	text-align: left;
}
.mqm-meta-chip {
	display: flex;
	align-items: center;
	gap: 7px;
	flex: 1 1 0;
	min-width: 0;
	padding: 2px 8px;
}
.mqm-meta-chip:not(:last-child) { border-right: 1px solid var(--mqm-line); }
.mqm-meta-chip-ic { flex-shrink: 0; line-height: 0; }
.mqm-meta-chip-ic svg { width: 18px; height: 18px; color: var(--mqm-coral); display: block; }
.mqm-meta-chip-txt { display: flex; flex-direction: column; min-width: 0; }
.mqm-meta-chip-txt strong {
	font: 700 11.5px/1.25 var(--mqm-font-body);
	color: var(--mqm-navy);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.mqm-meta-chip-txt em {
	font: 500 10.5px/1.2 var(--mqm-font-body);
	font-style: normal;
	color: var(--mqm-muted);
}

/* Stacked, larger checkout title (Almost there, / your details). */
[data-step="4"] .mqm-title {
	font-size: clamp(27px, 2.4vw + 14px, 38px);
	line-height: 1.05;
	margin: 0 0 18px;
}

/* Footer trust line on the checkout step (an error hint takes precedence). */
.mqm-foot-secure {
	display: none;
	align-items: center;
	gap: 8px;
	flex: 1;
	font: 500 12.5px var(--mqm-font-body);
	color: var(--mqm-muted);
}
.mqm-foot-secure-ic { width: 16px; height: 16px; color: var(--mqm-turquoise, #3FC1B8); flex-shrink: 0; }
[data-step="4"] .mqm-foot-secure { display: inline-flex; }
[data-step="4"] .mqm-foot-hint:not(.is-err) { display: none; }
[data-step="4"] .mqm-foot-hint.is-err { display: block; flex: 1; }
[data-step="4"] .mqm-foot-hint.is-err ~ .mqm-foot-secure { display: none; }

@media (max-width: 720px) {
	.mqm-checkout-aside { position: static; }
	.mqm-buynow-steps { padding: 10px 4px; }
	.mqm-meta-chip { padding: 2px 5px; }
	.mqm-meta-chip-txt strong { font-size: 11px; }
}
