/* Spin Wheel Discount — frontend styles */

.swd-root, .swd-root * {
	box-sizing: border-box;
	/* Isolate from the site theme so the popup looks identical everywhere
	   (themes love to restyle h3/p/button with their own font + UPPERCASE). */
	text-transform: none;
	letter-spacing: normal;
}
.swd-root {
	/* Default to a clean UI stack; a custom Font family setting overrides via --swd-font. */
	font-family: var(--swd-font, -apple-system, BlinkMacSystemFont, system-ui, Roboto, Helvetica, Arial, sans-serif);
	position: fixed;
	inset: 0;
	z-index: 999999;
	pointer-events: none;
}

/* --- Theme isolation -------------------------------------------------------
   Themes and page builders very often force their heading/body font (and
   sometimes UPPERCASE / a bigger size) onto h3/p/button/a WITH !important.
   A normal reset can't beat that, so we pin the popup's own typography on the
   specific text elements with high specificity + !important. SVG wheel/printer
   text is deliberately excluded so it keeps its own display font.
   Applied to EVERY preset so all themes share identical typography + spacing —
   only their colours differ. (The Royal WHEEL SVG is a separate file, untouched.) */
.swd-root.swd-skin .swd-eyebrow,
.swd-root.swd-skin .swd-title,
.swd-root.swd-skin .swd-subtitle,
.swd-root.swd-skin .swd-result-heading,
.swd-root.swd-skin .swd-coupon-code,
.swd-root.swd-skin .swd-emailed-note,
.swd-root.swd-skin .swd-email-input,
.swd-root.swd-skin .swd-email-label,
.swd-root.swd-skin .swd-consent-label,
.swd-root.swd-skin .swd-consent-label a,
.swd-root.swd-skin .swd-btn,
.swd-root.swd-skin .swd-decline-link,
.swd-root.swd-skin .swd-close-btn {
	font-family: var(--swd-font, -apple-system, BlinkMacSystemFont, system-ui, Roboto, Helvetica, Arial, sans-serif) !important;
	letter-spacing: normal !important;
	text-transform: none !important;
}
/* Re-apply the intended small-caps eyebrow after the reset above. */
.swd-root.swd-skin .swd-eyebrow {
	text-transform: uppercase !important;
	letter-spacing: 0.08em !important;
}
/* Pin the title's size/weight/line-height so every preset — and the live popup
   vs the admin preview (both share .swd-root.swd-skin) — renders IDENTICALLY at
   a compact, one-line size, immune to the theme's !important heading rules. */
.swd-root.swd-skin .swd-head .swd-title {
	/* FIXED size (not vw-based): the modal is a fixed 880px, so the title must
	   not scale with the browser window — otherwise the same popup looks a
	   different size at different window widths / preview vs live. */
	font-size: 28px !important;
	line-height: 1.15 !important;
	font-weight: 800 !important;
}
/* Identical, fixed content-panel padding for every preset and in both the live
   popup and the admin preview — !important so it also wins over the old
   preview-only padding overrides below. */
.swd-root.swd-skin .swd-head {
	padding: 26px 34px 0 !important;
}
.swd-root.swd-skin .swd-form-side {
	padding: 8px 34px 28px !important;
}
/* Phone step-down so the fixed title + padding don't overflow the narrow modal. */
@media (max-width: 640px) {
	.swd-root.swd-skin .swd-head .swd-title { font-size: 22px !important; }
	.swd-root.swd-skin .swd-head { padding: 22px 20px 0 !important; }
	.swd-root.swd-skin .swd-form-side { padding: 8px 20px 22px !important; }
}
.swd-root[hidden] { display: none; }
/* The hidden attribute must win over display set on .swd-btn etc.,
   otherwise "hidden" buttons (Copy/Claim on a loss) stay visible. */
.swd-root [hidden] { display: none !important; }

body.swd-no-scroll { overflow: hidden; }

/* ---------------- Overlay (center position only) ---------------- */
.swd-overlay {
	position: fixed;
	inset: 0;
	background: var(--swd-overlay, #000);
	opacity: var(--swd-overlay-opacity, 0.6);
	pointer-events: auto;
}

/* ---------------- Modal box ---------------- */
.swd-modal {
	position: fixed;
	background: var(--swd-modal-bg, #fff);
	color: var(--swd-text, #2d3436);
	border-radius: var(--swd-radius, 16px);
	box-shadow: 0 20px 60px rgba(0,0,0,.35);
	padding: 28px 24px 32px;
	width: 380px;
	max-width: calc(100vw - 24px);
	max-height: 100vh;
	max-height: 100dvh; /* avoids mobile address-bar clipping where supported */
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	text-align: center;
	pointer-events: auto;
}

/* Center placement */
.swd-position-center .swd-modal {
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

/* ---------------- Side (edge) placements ---------------- */
.swd-position-left .swd-modal,
.swd-position-right .swd-modal {
	top: 0;
	bottom: 0;
	height: 100vh;
	height: 100dvh; /* accounts for mobile browser chrome */
	width: clamp(420px, 50vw, 900px);   /* a true half-page panel */
	max-width: 100vw;
	border-radius: 0;
	overflow-y: auto;
	padding: 28px 40px;
}
.swd-position-left .swd-modal {
	left: 0;
	animation: swd-slide-in-left .45s cubic-bezier(0.16, 1, 0.3, 1);
}
.swd-position-right .swd-modal {
	right: 0;
	animation: swd-slide-in-right .45s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes swd-slide-in-left {
	from { transform: translateX(-100%); }
	to   { transform: translateX(0); }
}
@keyframes swd-slide-in-right {
	from { transform: translateX(100%); }
	to   { transform: translateX(0); }
}

/* =========================================================
   Layout system (CSS grid).
   Three regions: head (title/subtitle), wheel, form (steps).
   - Stacked: single column — head, wheel, form (button below wheel).
   - Beside:  wheel in one column; head + form stacked in the other.
   ========================================================= */
.swd-modal {
	display: grid;
	gap: 10px 26px;
	align-items: center;
	justify-items: center;
}
.swd-wheel-side { grid-area: wheel; }
.swd-head { grid-area: head; width: 100%; }
.swd-form-side { grid-area: form; width: 100%; align-self: start; }

/* Stacked: head on top, wheel in the middle, form (spin button / result) below. */
.swd-layout-stacked .swd-modal {
	grid-template-columns: minmax(0, 1fr);
	grid-template-areas: "head" "wheel" "form";
	text-align: center;
}

/* Beside: wheel spans both rows on one side; head + form on the other. */
.swd-layout-beside .swd-modal {
	grid-template-columns: auto minmax(220px, 1fr);
	grid-template-areas: "wheel head" "wheel form";
	justify-items: stretch;
	text-align: left;
}
.swd-layout-beside .swd-head { align-self: end; }
.swd-layout-beside .swd-form-side { align-self: start; }

/* Right placement in beside mode puts the wheel on the right. */
.swd-position-right.swd-layout-beside .swd-modal {
	grid-template-columns: minmax(220px, 1fr) auto;
	grid-template-areas: "head wheel" "form wheel";
}

/* Center + beside needs a wider modal to fit two columns. */
.swd-position-center.swd-layout-beside .swd-modal { width: 680px; }

/* In side (edge) placements the wheel is larger and emerges half off the
   screen edge, so its centre sits on the edge with the prizes fanning inward.
   The wheel is pinned flush to the emerging edge (no outer padding, no
   centring) so the -50% margin lands the hub exactly on the edge. */
.swd-position-left.swd-layout-beside  .swd-wheel-wrap,
.swd-position-left.swd-layout-beside  .swd-wheel-side,
.swd-position-right.swd-layout-beside .swd-wheel-wrap,
.swd-position-right.swd-layout-beside .swd-wheel-side { --swd-wheel-d: clamp(340px, 46vh, 560px); }
.swd-position-left.swd-layout-beside .swd-wheel-side {
	justify-content: flex-start;
	padding-left: 0;
	margin-left: calc(var(--swd-wheel-d) * -0.5);
}
.swd-position-right.swd-layout-beside .swd-wheel-side {
	justify-content: flex-end;
	padding-right: 0;
	margin-right: calc(var(--swd-wheel-d) * -0.5);
}

/* =========================================================
   Spin control: exactly one trigger is shown.
   - hub:    the button lives inside the wheel centre.
   - button: a separate button in the form; the hub becomes
             a plain decorative centre (no text, not clickable).
   ========================================================= */
.swd-spin-control-hub .swd-form-spin-btn { display: none; }
.swd-spin-control-button .swd-spin-hub {
	font-size: 0;
	cursor: default;
	pointer-events: none;
}

.swd-close-btn {
	position: absolute;
	top: 8px;
	right: 12px;
	background: none;
	border: none;
	font-size: 26px;
	line-height: 1;
	cursor: pointer;
	color: var(--swd-text, #2d3436);
	opacity: .6;
}
.swd-close-btn:hover { opacity: 1; }

/* Small kicker above the title. Only the Royal theme shows it (see below);
   hidden by default so other themes are unchanged. */
.swd-eyebrow { display: none; }
.swd-title { margin: 0 0 4px; font-size: 22px; font-weight: 800; }
.swd-subtitle { margin: 0 0 18px; font-size: 14px; opacity: .8; }

/* ---------------- Email gate ---------------- */
.swd-email-label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.swd-email-input {
	width: 100%;
	padding: 10px 12px;
	border: 1px solid #ddd;
	border-radius: 8px;
	font-size: 14px;
	margin-bottom: 12px;
	transition: border-color .15s ease, box-shadow .15s ease;
}
/* Invalid state: red border (and a soft ring) instead of a text message. */
.swd-email-input.swd-invalid {
	border-color: #e74c3c;
	box-shadow: 0 0 0 3px rgba(231, 76, 60, 0.15);
	outline: none;
}
.swd-consent-label.swd-invalid { color: #e74c3c; }
.swd-consent-label.swd-invalid input { outline: 2px solid #e74c3c; outline-offset: 2px; }

.swd-consent-label {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	font-size: 12px;
	text-align: left;
	margin: 4px 0 12px;
	line-height: 1.4;
}
.swd-consent-label input { margin-top: 2px; flex-shrink: 0; }
.swd-consent-label a { color: var(--swd-primary, inherit) !important; text-decoration: underline; font-weight: 600; }
.swd-consent-label a:hover { color: var(--swd-primary, inherit) !important; text-decoration: none; }

.swd-decline-link {
	display: block;
	margin: 12px auto 0;
	background: none;
	border: none;
	color: inherit;
	opacity: .6;
	font-size: 12px;
	text-decoration: underline;
	cursor: pointer;
}
.swd-decline-link:hover { opacity: 1; }

.swd-emailed-note { font-size: 13px; opacity: .75; margin: 4px 0 12px; }

/* ---------------- Buttons ---------------- */
.swd-btn {
	display: inline-block;
	width: 100%;
	background: var(--swd-primary, #6c5ce7);
	color: var(--swd-btn-text, #fff);
	border: none;
	padding: 12px 20px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: .5px;
	border-radius: 999px;
	cursor: pointer;
	text-decoration: none;
	transition: transform .15s ease, opacity .15s ease;
}
.swd-btn { box-shadow: var(--swd-btn-shadow, none); }
.swd-btn:hover { transform: translateY(-1px); opacity: .92; color: var(--swd-btn-text, #fff); }

/* ---------------- Wheel ---------------- */
/* Diameter is a variable so the wheel, its labels, hub and rim dots all scale
   together. min() caps it at the chosen size but lets it shrink to fit narrow
   screens, keeping it fully responsive without media queries. */
.swd-wheel-wrap {
	position: relative;
	width: var(--swd-wheel-d, 260px);
	height: var(--swd-wheel-d, 260px);
	margin: 0 auto 20px;
	/* A square SVG grows its bounding box by up to √2 while it rotates. Left
	   unclipped, that overflow reaches the modal's scroll area and flickers a
	   scrollbar for the whole spin. Clip it here — the pointer sits inside at 1%,
	   so it's unaffected. The 3D printer doesn't rotate, so it never did this. */
	overflow: hidden;
}
.swd-size-small  .swd-wheel-wrap { --swd-wheel-d: min(200px, 64vw); }
.swd-size-medium .swd-wheel-wrap { --swd-wheel-d: min(260px, 72vw); }
.swd-size-large  .swd-wheel-wrap { --swd-wheel-d: min(320px, 78vw); }

.swd-wheel {
	width: 100%;
	height: 100%;
	position: relative;
	transform: rotate(var(--swd-wheel-rotation, 0deg));
	transition: transform 4.6s cubic-bezier(0.12, 0.8, 0.15, 1);
	will-change: transform;
}
/* Labels read radially (outward from the centre) and are baked into the SVG, so
   they rotate together with the wheel — the winning segment always lands upright
   at the pointer. */
.swd-wheel-svg {
	display: block;
	width: 100%;
	height: 100%;
}
/* CSS variables resolve here (they do not resolve inside SVG presentation
   attributes), so themeable colours/fonts are applied via these rules. */
.swd-wheel-svg .swd-wheel-ring,
.swd-wheel-svg .swd-wheel-hub { fill: var(--swd-border, #fff); }
.swd-wheel-svg .swd-wheel-dots circle { fill: rgba(0,0,0,0.18); }

/* Marquee wheel hardware (every preset except Royal). The bulbs are warm filament
   glass, baked into the SVG. The rim band and inner lip take the wheel panel's own
   gradient colours; the trim (outer edge, spokes, hub ring) follows the Wheel
   border colour — so a preset keeps its palette with no extra settings. */
.swd-wheel-svg .swd-marquee-rim { fill: var(--swd-wheel-bg-start, #2b0b0e); }
.swd-wheel-svg .swd-marquee-lip { fill: var(--swd-wheel-bg-end, #1a1a1a); }
.swd-wheel-svg .swd-marquee-spokes line { stroke: var(--swd-border, #fff); }
.swd-wheel-svg .swd-marquee-hub {
	fill: var(--swd-wheel-bg-end, #1a1a1a);
	stroke: var(--swd-border, #fff);
}
.swd-wheel-svg text {
	font-family: var(--swd-font, inherit);
	fill: var(--swd-wheel-text, #fff);   /* overrides the SVG's inherited fill */
	paint-order: stroke;
	stroke: rgba(0,0,0,0.18);
	stroke-width: 0.6px;
}

.swd-pointer {
	position: absolute;
	z-index: 3;
	filter: drop-shadow(0 2px 3px rgba(0,0,0,.35));
}

/* Top pointer (points down into the wheel) */
.swd-pointer-pos-top .swd-pointer {
	top: -4px;
	left: 50%;
	width: 0;
	height: 0;
	transform: translateX(-50%);
	border-left: 15px solid transparent;
	border-right: 15px solid transparent;
	border-top: 26px solid var(--swd-pointer, #2d3436);
}

/* Side pointer (points left, in from the right edge — carnival style) */
.swd-pointer-pos-right .swd-pointer {
	top: 50%;
	right: -14px;
	width: 0;
	height: 0;
	transform: translateY(-50%);
	border-top: 15px solid transparent;
	border-bottom: 15px solid transparent;
	border-right: 26px solid var(--swd-pointer, #2d3436);
}
.swd-pointer-pos-right .swd-pointer::after {
	content: '';
	position: absolute;
	right: -30px;
	top: 50%;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--swd-pointer, #2d3436);
	transform: translateY(-50%);
}

/* Right-edge placement: the wheel emerges off the RIGHT of the screen, so the
   side pointer would be off-screen. Flip it to the LEFT of the wheel, pointing
   right/inward. Kept in sync with pointerAngle=180 in the frontend JS. */
.swd-position-right.swd-pointer-pos-right .swd-pointer {
	right: auto;
	left: -14px;
	border-right: 0;
	border-left: 26px solid var(--swd-pointer, #2d3436);
}
.swd-position-right.swd-pointer-pos-right .swd-pointer::after {
	right: auto;
	left: -30px;
}

/* Hub button (shown as the spin control in hub mode; the SVG draws the
   white hub cap beneath it). */
.swd-spin-hub {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 22%;
	height: 22%;
	border-radius: 50%;
	background: var(--swd-primary, #6c5ce7);
	color: var(--swd-btn-text, #fff);
	border: none;
	cursor: pointer;
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	box-shadow: 0 3px 10px rgba(0,0,0,.28);
	transition: filter .15s ease, transform .1s ease;
}
.swd-spin-hub span {
	font-size: calc(var(--swd-wheel-d, 260px) * 0.042);
	font-weight: 800;
	line-height: 1.05;
	text-transform: uppercase;
	letter-spacing: .3px;
	padding: 0 4px;
}
.swd-spin-hub:hover { filter: brightness(1.06); }
.swd-spin-hub:active { transform: translate(-50%, -50%) scale(.96); }
.swd-spin-hub:disabled { cursor: not-allowed; opacity: .85; }

/* Button mode: hide the hub button entirely; the SVG's white hub shows. */
.swd-spin-control-button .swd-spin-hub { display: none; }

/* ---------------- Roulette game mode ----------------
   .swd-roulette is also a .swd-wheel-wrap, so it inherits the --swd-wheel-d
   sizing (and the side-placement emerge). The wheel and the ball track rotate
   independently; the ball drops from the rim into the pocket near the end. */
.swd-rw-wheel {
	position: absolute; inset: 0;
	transform: rotate(var(--swd-rw-wheel, 0deg));
	transition: transform 6s cubic-bezier(.16, .72, .14, 1);
	filter: drop-shadow(0 12px 26px rgba(0,0,0,.5));
}
.swd-rw-wheel svg { width: 100%; height: 100%; display: block; }
.swd-rw-track {
	position: absolute; inset: 0;
	transform: rotate(var(--swd-rw-ball, 0deg));
	transition: transform 5.7s cubic-bezier(.12, .66, .16, 1);
	pointer-events: none;
}
.swd-rw-ball {
	position: absolute;
	left: 50%; top: var(--swd-rw-ball-top, 7%);
	width: 4.4%; height: 4.4%;
	border-radius: 50%;
	transform: translate(-50%, -50%);
	background: radial-gradient(circle at 34% 30%, #fff, #e7e7ea 55%, #a9adb6);
	box-shadow: 0 2px 5px rgba(0,0,0,.55), inset 0 -2px 4px rgba(0,0,0,.25);
	transition: top .95s cubic-bezier(.34, 1.5, .55, 1) 4.65s;
	z-index: 5;
}
@media (prefers-reduced-motion: reduce) {
	.swd-rw-wheel, .swd-rw-track, .swd-rw-ball { transition-duration: .8s; }
}

/* ---------------- 3D printer game mode (beta) ----------------
   The discount is "printed" upward, layer by layer. Filament colour comes from
   --swd-print-filament. The scene sits on the (dark) wheel panel like an enclosure. */
.swd-printer { width: 100%; max-width: 340px; margin: 0 auto; }
.swd-printer .swd-pr-svg { width: 100%; height: auto; display: block; filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.45)); }
/* Transforms are in SVG user units; the nozzle group rises (JS) while its inner
   group sweeps side to side (below). */
.swd-pr-noz, .swd-pr-noz-bob { transform-box: view-box; }
.swd-pr-printing .swd-pr-noz-bob { animation: swd-pr-bob .7s ease-in-out infinite; }
/* Sweep width is set per-print (--swd-pr-amp) so the head only travels as wide
   as the value being printed. */
@keyframes swd-pr-bob {
	0%, 100% { transform: translateX(calc(var(--swd-pr-amp, 72px) * -1)); }
	50%      { transform: translateX(var(--swd-pr-amp, 72px)); }
}
/* Filament spool slowly unwinds while printing. */
.swd-pr-spool-grp { transform-box: view-box; transform-origin: 62px 51px; }
.swd-pr-run .swd-pr-spool-grp { animation: swd-pr-spin 2.6s linear infinite; }
@keyframes swd-pr-spin { to { transform: rotate(-360deg); } }
/* The filament (bowden) tube + feed line only make sense while a print is
   running and the head is diving. At rest the head is parked up top, so a tube
   stretched across the frame looks odd — keep both hidden until the build runs,
   then fade them in. (An author CSS rule overrides the inline opacity attrs.) */
.swd-pr-bowden, .swd-pr-feed { opacity: 0; transition: opacity .25s ease; }
.swd-pr-run .swd-pr-bowden { opacity: .9; }
.swd-pr-run .swd-pr-feed   { opacity: .55; }
@media (prefers-reduced-motion: reduce) {
	.swd-pr-printing .swd-pr-noz-bob { animation: none; }
	.swd-pr-run .swd-pr-spool-grp { animation: none; }
}

/* ---------------- Result panel ---------------- */
.swd-coupon-code {
	font-size: 22px;
	font-weight: 800;
	letter-spacing: 1px;
	border: 2px dashed var(--swd-primary, #6c5ce7);
	border-radius: 10px;
	padding: 10px;
	margin: 12px 0;
	text-align: center;
}
.swd-copy-btn { background: #2d3436; margin-bottom: 10px; }
.swd-claim-btn { text-align: center; }

/* Once the outcome is known, the "spin to win" invitation is spent: the title
   and subtitle come out, and the win/no-luck message becomes the headline. */
.swd-showing-result .swd-head .swd-title,
.swd-showing-result .swd-head .swd-subtitle { display: none; }
.swd-showing-result .swd-result-heading {
	font-size: clamp(24px, 3.2vw, 34px);
	line-height: 1.1;
	font-weight: 800;
	margin: 0 0 14px;
	text-align: center;
	text-wrap: balance;
}
.swd-showing-result .swd-step-result { text-align: center; }
.swd-showing-result .swd-emailed-note { text-align: center; }

/* ---------------- Launcher tab ---------------- */
/* A round wheel-icon button that stays out of the way, then slides open to
   reveal the text on hover/focus. Colours come from the launcher's own pickers
   (--swd-launcher-bg / --swd-launcher-text). */
.swd-launcher {
	position: fixed;
	bottom: 24px;
	right: 24px;
	/* Icon sits on the edge side; text expands inward. Row-reverse keeps the
	   icon at the right (edge) for the default right/centre placement. */
	flex-direction: row-reverse;
	display: inline-flex;
	align-items: center;
	margin: 0;
	padding: 0;
	background: var(--swd-launcher-bg, #7c3aed);
	color: var(--swd-launcher-text, #fff);
	border: none;
	border-radius: 999px;
	font-family: var(--swd-font, -apple-system, BlinkMacSystemFont, system-ui, Roboto, Helvetica, Arial, sans-serif);
	font-weight: 700;
	font-size: 13.5px;
	letter-spacing: .2px;
	line-height: 1;
	text-transform: none;
	cursor: pointer;
	box-shadow: 0 10px 26px rgba(0, 0, 0, .26), 0 2px 6px rgba(0, 0, 0, .16);
	pointer-events: auto;
	z-index: 999998;
	-webkit-appearance: none;
	appearance: none;
	transition: box-shadow .22s ease;
}
.swd-launcher:hover,
.swd-launcher:focus-visible {
	box-shadow: 0 16px 34px rgba(0, 0, 0, .32), 0 4px 12px rgba(0, 0, 0, .22);
	outline: none;
}
/* The icon fills a fixed 52px disc so the collapsed button is a clean circle. */
.swd-launcher-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	flex: none;
}
/* Text is clipped to nothing until the button is hovered/focused. */
.swd-launcher-text {
	max-width: 0;
	opacity: 0;
	overflow: hidden;
	white-space: nowrap;
	padding: 0;
	transition: max-width .34s cubic-bezier(.2, .8, .2, 1), opacity .26s ease, padding .3s ease;
}
.swd-launcher:hover .swd-launcher-text,
.swd-launcher:focus-visible .swd-launcher-text,
.swd-launcher-expanded .swd-launcher-text {
	max-width: 240px;
	opacity: 1;
	padding-left: 18px;   /* right/centre placement: text is on the left */
}
/* Always-expanded launchers keep the text out at rest, so left placements need
   the padding on the other side (the icon is on the edge, text runs inward). */
.swd-launcher-pos-left.swd-launcher-expanded .swd-launcher-text { padding-left: 0; padding-right: 18px; }

/* Only the built-in wheel icon spins — a gift, a star or a custom logo shouldn't.
   Opt in rather than out, so a new icon can never start rotating by accident. */
.swd-launcher-icon .swd-launcher-img { display: block; width: 20px; height: 20px; object-fit: contain; }
.swd-launcher-icon-wheel svg { animation: swd-launcher-spin 6s linear infinite; }
@keyframes swd-launcher-spin { to { transform: rotate(360deg); } }

/* Resting shape of the icon button (and its expanded form). Circle is the
   default 999px above; these are the alternatives. */
.swd-launcher-shape-rounded { border-radius: 16px; }
.swd-launcher-shape-square  { border-radius: 9px; }

/* "Won" mode — after a win the launcher stays open showing the coupon code and
   a countdown to expiry (click to copy). Placed after the hover rules so it
   keeps the code visible whether or not the pointer is over it. */
.swd-launcher-won .swd-launcher-text {
	max-width: 360px;
	opacity: 1;
	overflow: visible;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	line-height: 1.2;
	padding-left: 16px;
	padding-right: 14px;
}
.swd-launcher-pos-left.swd-launcher-won .swd-launcher-text { padding-left: 14px; padding-right: 16px; }
.swd-launcher-won .swd-launcher-code { font-weight: 800; letter-spacing: .5px; font-size: 13px; white-space: nowrap; }
.swd-launcher-won .swd-launcher-timer:not(:empty) { font-size: 11px; font-weight: 600; opacity: .82; margin-top: 1px; white-space: nowrap; }
.swd-launcher-won .swd-launcher-icon svg { animation: none; }

/* Launcher glow — a coloured drop-shadow halo (optionally two-tone), which can
   gently pulse. Colours/strength come from --swd-launcher-glow (set per-launcher). */
.swd-launcher { filter: var(--swd-launcher-glow, none); }
.swd-launcher-glow-anim { animation: swd-lg-pulse 2.6s ease-in-out infinite; }
@keyframes swd-lg-pulse {
	0%, 100% { filter: var(--swd-launcher-glow, none); }
	50%      { filter: var(--swd-launcher-glow-strong, var(--swd-launcher-glow, none)); }
}
@media (prefers-reduced-motion: reduce) {
	.swd-launcher-glow-anim { animation: none; }
}

/* Left placement: icon on the left (edge), text expands to the right. */
.swd-launcher-pos-left {
	right: auto;
	left: 24px;
	flex-direction: row;
}
.swd-launcher-pos-left:hover .swd-launcher-text,
.swd-launcher-pos-left:focus-visible .swd-launcher-text {
	padding-left: 0;
	padding-right: 18px;
}

/* Reduced motion: no spin, no slide — show the full label so it never relies
   on a hover animation to be readable. */
@media (prefers-reduced-motion: reduce) {
	.swd-launcher-icon svg { animation: none; }
	.swd-launcher-text {
		max-width: 240px;
		opacity: 1;
		transition: none;
		padding-left: 16px;
		padding-right: 6px;
	}
	.swd-launcher-pos-left .swd-launcher-text { padding-left: 6px; padding-right: 16px; }
}

/* =========================================================
   Skin — the shared, polished prize-wheel look.
   Every preset (Royal, Modern, Classic, Dark) uses this same
   structure: a two-panel card (coloured wheel panel + content
   panel), a ticked rim, an arrow pointer and a domed hub. The
   wheel is the dynamic SVG, so any number of segments renders
   cleanly. Palette colours come from the inline CSS variables
   (the colour pickers); each preset supplies its own via the
   settings. Everything that ISN'T a picker (rim tick, hub dome,
   heading ink, etc.) is a --swd-skin-* variable whose defaults
   below reproduce the Royal look; presets override them at the
   bottom of this section.
   ========================================================= */
.swd-skin {
	/* Royal gold/purple constants — kept as the skin's baseline. */
	--swd-royal-purple:    var(--swd-primary, #7c3aed);
	--swd-royal-purple-dk: #35105f;
	--swd-royal-bg:        #170829;
	--swd-royal-gold:      #f7c948;
	--swd-royal-gold-lt:   #fff4b8;
	--swd-royal-gold-dk:   #d79c0f;

	/* Skin contract — presets override these; defaults = Royal. */
	--swd-skin-heading:       var(--swd-royal-purple-dk);
	--swd-skin-muted:         rgba(35, 17, 45, 0.74);
	--swd-skin-close:         var(--swd-skin-heading);
	--swd-skin-eyebrow-rule:  var(--swd-royal-gold);
	--swd-skin-modal-border:  rgba(247, 201, 72, 0.34);
	--swd-skin-modal-shadow:  0 28px 90px rgba(12, 4, 25, 0.48);
	--swd-skin-panel-glow:    rgba(247, 201, 72, 0.22);
	--swd-skin-input-bg:      #ffffff;
	--swd-skin-input-border:  rgba(53, 16, 95, 0.2);
	--swd-skin-input-ink:     #2d3436;
	--swd-skin-rim-tick:      color-mix(in srgb, var(--swd-border, #f7c948) 55%, #fff);
	--swd-skin-rim-hilite:    rgba(255, 255, 255, 0.45);
	--swd-skin-rim-inset:     rgba(53, 16, 95, 0.28);
	--swd-skin-hub-lt:        #fff8cc;
	--swd-skin-hub:           var(--swd-royal-gold);
	--swd-skin-hub-dk:        var(--swd-royal-gold-dk);
	--swd-skin-hub-ink:       var(--swd-royal-purple-dk);
	--swd-skin-wheelhub:      var(--swd-royal-gold-dk);
	--swd-skin-copy-bg:       var(--swd-royal-purple-dk);
	--swd-skin-coupon-border: var(--swd-primary, var(--swd-royal-purple));
	--swd-skin-coupon-ink:    var(--swd-royal-purple-dk);
	--swd-skin-coupon-bg:     #ffffff;
}

/* --- Two-panel modal card --- */
.swd-skin .swd-modal {
	padding: 0;
	gap: 0;
	overflow: hidden auto;             /* clip panels to the rounded corners; still scroll if tall */
	border: 1px solid var(--swd-skin-modal-border);
	box-shadow: var(--swd-skin-modal-shadow);
}
.swd-skin.swd-position-center .swd-modal { width: min(880px, calc(100vw - 32px)); }
.swd-skin.swd-position-center.swd-layout-beside .swd-modal { width: min(880px, calc(100vw - 32px)); }

/* Coloured wheel panel fills its whole grid column, edge to edge. */
.swd-skin .swd-wheel-side {
	align-self: stretch;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(24px, 4vw, 44px);
	background:
		radial-gradient(circle at 30% 22%, var(--swd-skin-panel-glow), transparent 60%),
		linear-gradient(160deg, var(--swd-wheel-bg-start, var(--swd-royal-purple-dk)), var(--swd-wheel-bg-end, var(--swd-royal-bg)));
}
.swd-skin .swd-wheel-wrap { margin: 0; }

/* Content panel padding (head sits above the form). */
.swd-skin .swd-head      { padding: clamp(28px, 4vw, 46px) clamp(24px, 3.5vw, 44px) 0; }
.swd-skin .swd-form-side { padding: 10px clamp(24px, 3.5vw, 44px) clamp(28px, 4vw, 46px); }

.swd-skin .swd-close-btn { color: var(--swd-skin-close); opacity: 0.65; }

/* --- Content typography --- */
.swd-skin .swd-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 12px;
	color: var(--swd-eyebrow, var(--swd-royal-purple));
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}
.swd-skin .swd-eyebrow::before {
	content: '';
	width: 24px;
	height: 2px;
	background: var(--swd-skin-eyebrow-rule);
}
.swd-skin .swd-head .swd-title {
	color: var(--swd-skin-heading);
	font-size: clamp(26px, 3.4vw, 38px);
	font-weight: 800;
	line-height: 1.05;
	margin-bottom: 12px;
}
/* The win/lose message is a heading too, so it follows the skin like the title
   above. It used to inherit the generic Text colour, whose fallback (#2d3436)
   is dark — which left it near-invisible on the dark presets' dark modals. */
.swd-skin .swd-result-heading {
	color: var(--swd-skin-heading);
}
.swd-skin .swd-subtitle {
	color: var(--swd-skin-muted);
	font-size: 15px;
	line-height: 1.55;
	opacity: 1;
}
.swd-skin .swd-email-input {
	min-height: 48px;
	padding: 12px 18px;
	background: var(--swd-skin-input-bg);
	color: var(--swd-skin-input-ink) !important;
	border: 1px solid var(--swd-skin-input-border);
	border-radius: 10px;
}

/* --- Buttons & result --- */
.swd-skin .swd-btn {
	border-radius: 12px;
	font-weight: 800;
	background: linear-gradient(135deg, var(--swd-btn-start, var(--swd-royal-purple)), var(--swd-btn-end, var(--swd-royal-purple-dk)));
	box-shadow: var(--swd-btn-shadow, none);   /* controlled by the shadow colour/strength settings */
}
.swd-skin .swd-copy-btn { background: var(--swd-skin-copy-bg); box-shadow: none; }
.swd-skin .swd-coupon-code {
	border: 2px dashed var(--swd-skin-coupon-border);
	color: var(--swd-skin-coupon-ink);
	background: var(--swd-skin-coupon-bg);
	border-radius: 10px;
}

/* --- Wheel: the SVG draws its own rim, bulbs and hub; theme their colours.
   Rim follows the Wheel border colour; hub ring follows the skin. --- */
.swd-skin .swd-wheel-svg .swd-wheel-ring     { fill: var(--swd-border, var(--swd-royal-gold)); }
.swd-skin .swd-wheel-svg .swd-wheel-hub      { fill: var(--swd-skin-wheelhub); }

/* --- Arrow pointer (no ball), pointing in from the right --- */
.swd-skin.swd-pointer-pos-right .swd-pointer {
	right: 1%;
	border-top-width: 18px;
	border-bottom-width: 18px;
	border-right-width: 34px;
	border-right-color: var(--swd-pointer, var(--swd-royal-gold));
	filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.3));
}
.swd-skin.swd-pointer-pos-right .swd-pointer::after { display: none; }
.swd-skin.swd-pointer-pos-top .swd-pointer {
	top: 1%;
	border-top-color: var(--swd-pointer, var(--swd-royal-gold));
}
/* Right-edge placement: flip the arrow to the left of the wheel. */
.swd-skin.swd-position-right.swd-pointer-pos-right .swd-pointer {
	right: auto;
	left: 1%;
	border-right-width: 0;
	border-left: 34px solid var(--swd-pointer, var(--swd-royal-gold));
}

/* Every preset uses the arrow above. Its colour still follows each preset's
   Pointer colour, so they share one shape without sharing one palette. */

/* Hub-mode spin button (Modern/Classic/Dark): a clean flat disc matching the
   SVG hub. In button mode the base rule hides it and the SVG's flat hub shows. */
.swd-skin .swd-spin-hub {
	background: radial-gradient(circle at 38% 30%, #ffffff, #eef1f6);
	color: var(--swd-skin-heading, var(--swd-royal-purple-dk));
	box-shadow: 0 3px 10px rgba(0, 0, 0, 0.28), inset 0 0 0 3px var(--swd-border, var(--swd-royal-gold));
}

/* =========================================================
   Royal keeps its ORIGINAL wheel dressing — untouched: a gold
   ticked rim behind the wheel, a domed gold hub, and upright
   (counter-rotated) labels. Only Royal; the other presets use
   the marquee wheel above.
   ========================================================= */
.swd-wheel-royal .swd-wheel-wrap::before {
	content: '';
	position: absolute;
	inset: 2%;
	border-radius: 50%;
	background: var(--swd-border, var(--swd-royal-gold));   /* fallback if color-mix unsupported */
	background: repeating-conic-gradient(
		from 0deg,
		var(--swd-border, var(--swd-royal-gold)) 0deg 8deg,
		var(--swd-skin-rim-tick) 8deg 12deg
	);
	box-shadow:
		inset 0 0 0 5px var(--swd-skin-rim-hilite),
		inset 0 0 0 12px var(--swd-skin-rim-inset),
		0 18px 40px rgba(0, 0, 0, 0.34);
}
/* The roulette has its own carved wooden rim, so drop the ticked ring there. */
.swd-wheel-royal .swd-roulette::before { display: none; }

/* Upright labels: counter-rotate against the wheel spin so they stay readable. */
.swd-wheel-royal .swd-wheel-svg .swd-wheel-labels text {
	transform-box: fill-box;
	transform-origin: center;
	transform: rotate(calc(var(--swd-wheel-rotation, 0deg) * -1));
	transition: transform 4.6s cubic-bezier(0.12, 0.8, 0.15, 1);
}
.swd-wheel-royal .swd-wheel-svg .swd-wheel-dots circle { fill: rgba(0, 0, 0, 0.18); }

/* Domed gold hub cap (shown in both spin-control modes). No cast shadow — the
   dome sits flush in the middle of the wheel rather than floating over it. */
.swd-wheel-royal .swd-spin-hub,
.swd-wheel-royal.swd-spin-control-button .swd-spin-hub {
	display: flex;
	background: radial-gradient(circle at 34% 28%, var(--swd-skin-hub-lt), var(--swd-skin-hub) 58%, var(--swd-skin-hub-dk));
	color: var(--swd-skin-hub-ink);
	box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.5);
}
/* Button mode: the dome is decorative, so size it to 20% of the wheel's radius.
   The wheel's radius is 138 of the SVG's 340 units, so 20% of it is 16.24% of the
   wrapper's width. In hub mode the dome is the spin button and keeps its full
   size, since it has to be clickable and hold a label. */
.swd-wheel-royal.swd-spin-control-button .swd-spin-hub {
	pointer-events: none;
	cursor: default;
	width: 16.24%;
	height: 16.24%;
}
.swd-wheel-royal.swd-spin-control-button .swd-spin-hub span { display: none; }

/* Trim the coloured wheel/printer panel padding in the compact preview canvas.
   Head/form/title spacing is handled by the shared .swd-root.swd-skin rules
   above so the preview matches the live popup exactly for every preset. */
.swd-admin-preview.swd-skin .swd-wheel-side { padding: 22px 16px; }

/* =========================================================
   Royal's colour variants. They share the Royal wheel above
   (.swd-wheel-royal) and its gold trim; only the jewel hue
   changes. `--swd-royal-purple` already follows --swd-primary,
   so the two dark tones are all that need restating.
   ========================================================= */
.swd-theme-royal_blue {
	--swd-royal-purple-dk: #12306E;
	--swd-royal-bg:        #050F26;
}
.swd-theme-royal_red {
	--swd-royal-purple-dk: #5E0B18;
	--swd-royal-bg:        #240509;
}
.swd-theme-royal_green {
	--swd-royal-purple-dk: #0A3D2A;
	--swd-royal-bg:        #041A11;
}

/* =========================================================
   Per-preset palettes — only the skin constants that differ.
   The picker colours (button, wheel panel, border, pointer,
   eyebrow, popup bg, text) are supplied per preset through the
   settings palette applied when the preset is chosen.
   ========================================================= */

/* Modern — clean indigo with a brushed-silver rim on a light card. */
.swd-theme-modern {
	--swd-skin-heading:       #0f172a;
	--swd-skin-muted:         rgba(15, 23, 42, 0.66);
	--swd-skin-eyebrow-rule:  var(--swd-eyebrow, #4f46e5);
	--swd-skin-modal-border:  rgba(79, 70, 229, 0.16);
	--swd-skin-modal-shadow:  0 26px 70px rgba(30, 27, 75, 0.28);
	--swd-skin-panel-glow:    rgba(199, 210, 254, 0.30);
	--swd-skin-input-border:  rgba(15, 23, 42, 0.16);
	--swd-skin-rim-tick:      color-mix(in srgb, var(--swd-border, #cbd5e1) 45%, #fff);
	--swd-skin-rim-inset:     rgba(30, 27, 75, 0.22);
	--swd-skin-hub-lt:        #ffffff;
	--swd-skin-hub:           #cbd5e1;
	--swd-skin-hub-dk:        #94a3b8;
	--swd-skin-hub-ink:       #1e293b;
	--swd-skin-wheelhub:      #94a3b8;
	--swd-skin-copy-bg:       #312e81;
	--swd-skin-coupon-border: var(--swd-primary, #4f46e5);
	--swd-skin-coupon-ink:    #312e81;
}

/* Classic — carnival red & gold on a warm cream card. */
.swd-theme-classic {
	--swd-skin-heading:       #7a1420;
	--swd-skin-muted:         rgba(42, 26, 18, 0.72);
	--swd-skin-eyebrow-rule:  var(--swd-eyebrow, #c1121f);
	--swd-skin-modal-border:  rgba(244, 196, 48, 0.40);
	--swd-skin-modal-shadow:  0 26px 80px rgba(58, 14, 14, 0.42);
	--swd-skin-panel-glow:    rgba(244, 196, 48, 0.22);
	--swd-skin-input-border:  rgba(122, 20, 32, 0.22);
	--swd-skin-rim-inset:     rgba(122, 20, 32, 0.30);
	--swd-skin-hub-lt:        #fff2c0;
	--swd-skin-hub:           #f4c430;
	--swd-skin-hub-dk:        #b8860b;
	--swd-skin-hub-ink:       #7a1420;
	--swd-skin-wheelhub:      #b8860b;
	--swd-skin-copy-bg:       #7a1420;
	--swd-skin-coupon-border: var(--swd-primary, #c1121f);
	--swd-skin-coupon-ink:    #7a1420;
}

/* Dark — smooth charcoal card with a friendly blue accent and a muted
   brushed-steel rim (deliberately understated, no neon glow). */
.swd-theme-dark {
	--swd-skin-heading:       #f3f5f8;
	--swd-skin-muted:         rgba(230, 233, 239, 0.62);
	--swd-skin-close:         #e6e9ef;
	--swd-skin-eyebrow-rule:  var(--swd-eyebrow, #60a5fa);
	--swd-skin-modal-border:  rgba(96, 165, 250, 0.18);
	--swd-skin-modal-shadow:  0 28px 80px rgba(0, 0, 0, 0.55);
	--swd-skin-panel-glow:    rgba(96, 165, 250, 0.10);
	--swd-skin-input-bg:      rgba(255, 255, 255, 0.05);
	--swd-skin-input-border:  rgba(255, 255, 255, 0.14);
	--swd-skin-input-ink:     #e6e9ef;
	--swd-skin-rim-tick:      color-mix(in srgb, var(--swd-border, #4e6180) 62%, #dbe4f2);
	--swd-skin-rim-hilite:    rgba(255, 255, 255, 0.14);
	--swd-skin-rim-inset:     rgba(0, 0, 0, 0.5);
	--swd-skin-hub-lt:        #e8eef7;
	--swd-skin-hub:           #9db0cd;
	--swd-skin-hub-dk:        #5a6f92;
	--swd-skin-hub-ink:       #10233f;
	--swd-skin-wheelhub:      #5a6f92;
	--swd-skin-copy-bg:       #1e3a8a;
	--swd-skin-coupon-border: var(--swd-primary, #3b82f6);
	--swd-skin-coupon-ink:    #cfe0fb;
	--swd-skin-coupon-bg:     rgba(255, 255, 255, 0.04);
}

/* Casino Gold — emerald-felt wheel panel, gold rim, black card with gold text. */
.swd-theme-casino {
	--swd-skin-heading:       #f5e9c6;
	--swd-skin-muted:         rgba(245, 233, 198, 0.66);
	--swd-skin-close:         #f5e9c6;
	--swd-skin-eyebrow-rule:  var(--swd-eyebrow, #e8c25a);
	--swd-skin-modal-border:  rgba(232, 194, 90, 0.30);
	--swd-skin-modal-shadow:  0 28px 84px rgba(0, 0, 0, 0.62);
	--swd-skin-panel-glow:    rgba(232, 194, 90, 0.14);
	--swd-skin-input-bg:      rgba(255, 255, 255, 0.05);
	--swd-skin-input-border:  rgba(232, 194, 90, 0.28);
	--swd-skin-input-ink:     #f5e9c6;
	--swd-skin-rim-tick:      color-mix(in srgb, var(--swd-border, #e8c25a) 55%, #fff6d8);
	--swd-skin-rim-hilite:    rgba(255, 248, 220, 0.4);
	--swd-skin-rim-inset:     rgba(0, 0, 0, 0.42);
	--swd-skin-hub-lt:        #fff6cf;
	--swd-skin-hub:           #e8c25a;
	--swd-skin-hub-dk:        #a97b1e;
	--swd-skin-hub-ink:       #2a1e05;
	--swd-skin-wheelhub:      #c99a2e;
	--swd-skin-copy-bg:       #0f6b49;
	--swd-skin-coupon-border: var(--swd-primary, #e8c25a);
	--swd-skin-coupon-ink:    #f5e9c6;
	--swd-skin-coupon-bg:     rgba(255, 255, 255, 0.04);
}

/* ---------------- Inline error banner ---------------- */
.swd-root.swd-skin .swd-error {
	margin: 12px 0 0;
	padding: 9px 12px;
	border-radius: 8px;
	background: rgba(239, 68, 68, 0.12);
	border: 1px solid rgba(239, 68, 68, 0.42);
	color: #ef4444;
	font-size: 13px;
	font-weight: 600;
	text-align: left;
	font-family: var(--swd-font, -apple-system, BlinkMacSystemFont, system-ui, Roboto, Helvetica, Arial, sans-serif);
}

/* ---------------- Responsive ---------------- */
@media (max-width: 640px) {
	/* On small screens every layout collapses to a single stacked column
	   (head, wheel, form) so two columns never get cramped. */
	.swd-layout-beside .swd-modal,
	.swd-position-right.swd-layout-beside .swd-modal,
	.swd-modal {
		grid-template-columns: minmax(0, 1fr) !important;
		grid-template-areas: "head" "wheel" "form" !important;
		text-align: center;
		width: auto !important;
	}
	.swd-wheel-side { margin: 0 !important; }
}

@media (max-width: 480px) {
	.swd-position-center .swd-modal { width: calc(100vw - 24px); padding: 22px 16px 26px; }
	.swd-position-center.swd-layout-beside .swd-modal { width: calc(100vw - 24px); }

	/* Side panels take the full width on phones. */
	.swd-position-left .swd-modal,
	.swd-position-right .swd-modal {
		width: 100vw;
		max-width: 100vw;
		padding: 22px 16px 26px;
	}

	/* 16px inputs stop iOS Safari from auto-zooming when the field is tapped. */
	.swd-email-input { font-size: 16px; }

	/* Larger, finger-friendly tap targets. */
	.swd-btn { padding: 14px 20px; }
	.swd-close-btn { top: 6px; right: 8px; font-size: 30px; padding: 6px; line-height: 1; }
	.swd-title { font-size: 20px; }
}

/* Extra-small phones: trim padding so the wheel gets maximum room. */
@media (max-width: 360px) {
	.swd-modal { padding: 18px 12px 22px; }
}
