/**
 * Jazital Pro Forms — frontend.
 *
 * Everything is scoped under .jpf-form-wrap and driven by custom properties set
 * per form instance, so two forms with different accents, radii and themes can
 * sit on the same page without fighting. Nothing here sets a font-family by
 * default: the form inherits the theme's typography, which is what makes it
 * look like part of the site rather than a widget dropped on top of it.
 */

/* ==================================================================
 * Tokens
 * ================================================================== */

.jpf-form-wrap {
	/* Overridden per instance by Renderer::style_vars(). */
	--jpf-accent: #6366f1;
	--jpf-accent-rgb: 99 102 241;
	--jpf-radius: 12px;
	--jpf-font-size: 15px;
	--jpf-gap: 20px;
	--jpf-form-width: 100%;

	--jpf-text: #0f172a;
	--jpf-label: #0f172a;
	--jpf-muted: #64748b;
	--jpf-border: #e2e8f0;
	--jpf-border-strong: #cbd5e1;
	--jpf-bg: transparent;
	--jpf-input-bg: #ffffff;
	--jpf-input-h: 46px;
	--jpf-error: #e11d48;
	--jpf-error-bg: #fff1f2;
	--jpf-success: #059669;
	--jpf-success-bg: #ecfdf5;

	--jpf-ring: 0 0 0 4px rgb(var(--jpf-accent-rgb) / 0.14);
	--jpf-shadow-sm: 0 1px 2px rgb(15 23 42 / 0.04);
	--jpf-shadow-md: 0 4px 16px -2px rgb(15 23 42 / 0.08), 0 2px 4px -2px rgb(15 23 42 / 0.04);
	--jpf-shadow-lg: 0 20px 40px -12px rgb(15 23 42 / 0.14), 0 4px 10px -4px rgb(15 23 42 / 0.06);

	--jpf-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--jpf-dur: 0.18s;

	box-sizing: border-box;
	max-width: var(--jpf-form-width);
	color: var(--jpf-text);
	font-size: var(--jpf-font-size);
	line-height: 1.5;
}

.jpf-form-wrap *,
.jpf-form-wrap *::before,
.jpf-form-wrap *::after {
	box-sizing: border-box;
}

/**
 * Dark is opt-in, never automatic.
 *
 * This used to follow `prefers-color-scheme`, and that was wrong. The media
 * query describes the visitor's operating system, not the page the form is
 * sitting in. A visitor with dark mode on, reading a light site, got a form
 * with dark inputs and near-white labels dropped onto a white page — unreadable,
 * and nothing to do with any choice the site owner made.
 *
 * A form should follow the site around it, and the site's colour scheme is not
 * something CSS can ask about. So the default is light, and dark is something
 * you turn on deliberately:
 *
 *   - add the `jpf-dark` class to the wrapper via the `jpf_form_classes`
 *     filter, on the forms or the pages where your design is dark, or
 *   - set the colours directly on the form's Style tab, which overrides all of
 *     this and needs no code.
 *
 * A site that genuinely follows the visitor's OS can opt back into that in one
 * rule of its own:
 *
 *   @media (prefers-color-scheme: dark) { .jpf-form-wrap { ... } }
 */
.jpf-form-wrap.jpf-dark {
	--jpf-text: #e2e8f0;
	--jpf-label: #f1f5f9;
	--jpf-muted: #94a3b8;
	--jpf-border: #334155;
	--jpf-border-strong: #475569;
	--jpf-input-bg: #1e293b;
	--jpf-error-bg: #451a24;
	--jpf-success-bg: #052e26;
	--jpf-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
	--jpf-shadow-md: 0 4px 16px -2px rgb(0 0 0 / 0.4);
	--jpf-shadow-lg: 0 20px 40px -12px rgb(0 0 0 / 0.55);
}

/**
 * `hidden` must actually hide.
 *
 * The browser's own [hidden] { display: none } is specificity 0,1,0 — the same
 * as any .jpf-class rule — and an author stylesheet beats the UA stylesheet at
 * equal specificity. So every element here that was given a `display` silently
 * ignored its `hidden` attribute: the empty error slots rendered as bare red
 * icons under every field, and a multi-step form showed Back, Continue and
 * Submit all at once. This has to outrank the component rules, hence the
 * !important.
 */
.jpf-form-wrap [hidden] { display: none !important; }

.jpf-icon {
	flex: none;
	display: inline-block;
	vertical-align: middle;
}

/* Visually hidden but readable by assistive tech. */
.jpf-form-wrap .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ==================================================================
 * Form shell
 * ================================================================== */

.jpf-form {
	margin: 0;
	padding: 0;
	background: var(--jpf-bg);
}

.jpf-fields {
	display: flex;
	flex-wrap: wrap;
	gap: var(--jpf-gap);
	align-items: flex-start;
}

.jpf-field {
	flex: 1 1 100%;
	min-width: 0;
	position: relative;
}

/**
 * Widths are computed against the row gap so two half fields land exactly
 * edge to edge. Percentages alone would overflow by one gap.
 */
.jpf-w-full { flex-basis: 100%; }
.jpf-w-half { flex-basis: calc(50% - (var(--jpf-gap) / 2)); }
.jpf-w-third { flex-basis: calc(33.333% - (var(--jpf-gap) * 2 / 3)); }
.jpf-w-two-thirds { flex-basis: calc(66.666% - (var(--jpf-gap) / 3)); }
.jpf-w-quarter { flex-basis: calc(25% - (var(--jpf-gap) * 3 / 4)); }

/**
 * Per-breakpoint widths.
 *
 * These blocks sit after the base widths and carry the same specificity, so
 * the later one wins — which is exactly the cascade we want: mobile overrides
 * tablet overrides desktop. A field with no tablet class simply keeps its
 * desktop width, which is what "inherit" means.
 *
 * The previous `.jpf-field { flex-basis: 100% !important }` blanket is gone.
 * It made phone layout unarguable — you could not keep two short fields side
 * by side even when they fitted, and !important meant nothing could override it.
 */
@media (max-width: 900px) {
	.jpf-w-t-full { flex-basis: 100%; }
	.jpf-w-t-half { flex-basis: calc(50% - (var(--jpf-gap) / 2)); }
	.jpf-w-t-third { flex-basis: calc(33.333% - (var(--jpf-gap) * 2 / 3)); }
	.jpf-w-t-two-thirds { flex-basis: calc(66.666% - (var(--jpf-gap) / 3)); }
	.jpf-w-t-quarter { flex-basis: calc(25% - (var(--jpf-gap) * 3 / 4)); }
}

@media (max-width: 600px) {
	.jpf-w-m-full { flex-basis: 100%; }
	.jpf-w-m-half { flex-basis: calc(50% - (var(--jpf-gap) / 2)); }
	.jpf-w-m-third { flex-basis: calc(33.333% - (var(--jpf-gap) * 2 / 3)); }
	.jpf-w-m-two-thirds { flex-basis: calc(66.666% - (var(--jpf-gap) / 3)); }
	.jpf-w-m-quarter { flex-basis: calc(25% - (var(--jpf-gap) * 3 / 4)); }
}

/**
 * Per-breakpoint visibility.
 *
 * Presentational only: a field hidden here still submits and is still
 * validated, so hiding a required field on a breakpoint would stop those
 * visitors submitting with nothing on screen to explain why. The builder warns
 * about that combination rather than silently changing what gets submitted —
 * conditional logic is the tool for actually removing a field.
 */
@media (min-width: 901px) { .jpf-hide-d { display: none; } }
@media (max-width: 900px) and (min-width: 601px) { .jpf-hide-t { display: none; } }
@media (max-width: 600px) { .jpf-hide-m { display: none; } }

.jpf-logic-hidden { display: none; }

/* ==================================================================
 * Labels, descriptions, errors
 * ================================================================== */

.jpf-label {
	display: block;
	margin-bottom: 7px;
	color: var(--jpf-label);
	/* Falls back to the relative size when no explicit label size is set, so
	   the per-field override is opt-in and the form-wide font size still
	   drives labels by default. */
	font-size: var(--jpf-label-size, 0.9em);
	font-weight: 600;
	letter-spacing: -0.005em;
	line-height: 1.35;
}

.jpf-required {
	color: var(--jpf-error);
	font-weight: 500;
}

.jpf-desc {
	margin: 7px 0 0;
	color: var(--jpf-muted);
	font-size: 0.82em;
	line-height: 1.45;
}

.jpf-error {
	display: flex;
	align-items: center;
	gap: 5px;
	margin: 7px 0 0;
	color: var(--jpf-error);
	font-size: 0.82em;
	font-weight: 500;
	animation: jpf-shake 0.3s var(--jpf-ease);
}

.jpf-error::before {
	content: "";
	flex: none;
	width: 14px;
	height: 14px;
	background-color: currentColor;
	/* Lucide alert-circle, as a mask so it takes the error colour. */
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4'/%3E%3Cpath d='M12 16h.01'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4'/%3E%3Cpath d='M12 16h.01'/%3E%3C/svg%3E") center / contain no-repeat;
}

@keyframes jpf-shake {
	0%, 100% { transform: translateX(0); }
	25% { transform: translateX(-3px); }
	75% { transform: translateX(3px); }
}

.jpf-labels-hidden .jpf-label { display: none; }

/* ==================================================================
 * Inputs — base
 * ================================================================== */

.jpf-input {
	width: 100%;
	min-height: var(--jpf-input-h);
	padding: 11px 14px;
	margin: 0;
	color: var(--jpf-text);
	font: inherit;
	font-size: 1em;
	line-height: 1.4;
	background: var(--jpf-input-bg);
	border: 1px solid var(--jpf-border);
	border-radius: var(--jpf-radius);
	box-shadow: var(--jpf-shadow-sm);
	outline: none;
	appearance: none;
	-webkit-appearance: none;
	transition:
		border-color var(--jpf-dur) var(--jpf-ease),
		box-shadow var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease);
}

.jpf-input::placeholder {
	color: var(--jpf-muted);
	opacity: 0.75;
}

.jpf-input:hover:not(:focus):not(:disabled) {
	border-color: var(--jpf-border-strong);
}

.jpf-input:focus,
.jpf-input:focus-visible {
	border-color: var(--jpf-accent);
	box-shadow: var(--jpf-ring);
}

.jpf-input:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

.jpf-field.jpf-has-error .jpf-input {
	border-color: var(--jpf-error);
	background-color: var(--jpf-error-bg);
}

.jpf-field.jpf-has-error .jpf-input:focus {
	box-shadow: 0 0 0 4px rgb(225 29 72 / 0.13);
}

.jpf-textarea {
	min-height: 120px;
	padding-top: 12px;
	resize: vertical;
	line-height: 1.55;
}

/* Number fields: the spinner arrows clash with the padding on every browser. */
.jpf-field-number .jpf-input::-webkit-outer-spin-button,
.jpf-field-number .jpf-input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.jpf-field-number .jpf-input {
	-moz-appearance: textfield;
	appearance: textfield;
}

/* Date and time: the native picker icon is unstyleable, so it is replaced. */
.jpf-field-date .jpf-input::-webkit-calendar-picker-indicator,
.jpf-field-time .jpf-input::-webkit-calendar-picker-indicator {
	opacity: 0;
	position: absolute;
	right: 0;
	width: 44px;
	height: 100%;
	cursor: pointer;
}

.jpf-field-date .jpf-input-wrap,
.jpf-field-time .jpf-input-wrap {
	position: relative;
}

.jpf-field-date .jpf-input-wrap::after,
.jpf-field-time .jpf-input-wrap::after {
	content: "";
	position: absolute;
	top: 50%;
	right: 14px;
	width: 17px;
	height: 17px;
	transform: translateY(-50%);
	background-color: var(--jpf-muted);
	pointer-events: none;
	transition: background-color var(--jpf-dur) var(--jpf-ease);
}

.jpf-field-date .jpf-input-wrap::after {
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E") center / contain no-repeat;
}

.jpf-field-time .jpf-input-wrap::after {
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center / contain no-repeat;
}

.jpf-field-date .jpf-input:focus ~ .jpf-input-wrap::after { background-color: var(--jpf-accent); }

/* The "type it again" input on email and password fields. */
.jpf-confirm { margin-top: 10px; }

.jpf-label-sub {
	font-size: 0.82em;
	font-weight: 500;
	color: var(--jpf-muted);
	margin-bottom: 5px;
}

/* Character counter */
.jpf-counter {
	margin-top: 6px;
	color: var(--jpf-muted);
	font-size: 0.75em;
	font-variant-numeric: tabular-nums;
	text-align: right;
	transition: color var(--jpf-dur) var(--jpf-ease);
}

.jpf-counter.is-near { color: #d97706; }
.jpf-counter.is-over { color: var(--jpf-error); font-weight: 600; }

/* ==================================================================
 * Select
 * ================================================================== */

.jpf-select-wrap {
	position: relative;
	display: block;
}

.jpf-select {
	padding-right: 40px;
	cursor: pointer;
	background-image: none;
}

.jpf-select[multiple] {
	padding-right: 14px;
	min-height: 120px;
	cursor: default;
}

.jpf-select-arrow {
	position: absolute;
	top: 50%;
	right: 13px;
	color: var(--jpf-muted);
	transform: translateY(-50%);
	pointer-events: none;
	transition: transform var(--jpf-dur) var(--jpf-ease), color var(--jpf-dur) var(--jpf-ease);
}

.jpf-select:focus + .jpf-select-arrow {
	color: var(--jpf-accent);
	transform: translateY(-50%) rotate(180deg);
}

.jpf-select[multiple] + .jpf-select-arrow { display: none; }

/* ==================================================================
 * Choices — radio and checkbox
 * ================================================================== */

.jpf-choices {
	display: grid;
	gap: 9px;
}

.jpf-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.jpf-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.jpf-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 600px) {
	.jpf-cols-2, .jpf-cols-3, .jpf-cols-4 { grid-template-columns: 1fr; }
}

/**
 * A choice is prose with a control next to it, not a card.
 *
 * Boxing every option by default put a border around each line of a ten-point
 * scale, which reads as ten separate things to decide rather than one question
 * — and on a long list it is visual noise with nothing to say. The card is now
 * opt-in per field via `choice_style`, where it earns its keep: a handful of
 * options that are genuinely selectable regions.
 */
.jpf-choice {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 3px 0;
	margin: 0;
	background: transparent;
	border: 1px solid transparent;
	border-radius: calc(var(--jpf-radius) * 0.75);
	cursor: pointer;
	transition:
		border-color var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease),
		box-shadow var(--jpf-dur) var(--jpf-ease);
}

/* Boxed: the opt-in card treatment. */
.jpf-choices-boxed .jpf-choice {
	padding: 11px 13px;
	background: var(--jpf-input-bg);
	border-color: var(--jpf-border);
}

.jpf-choices-boxed .jpf-choice:hover { border-color: var(--jpf-border-strong); }

/* The real input is hidden but still focusable, so keyboard and screen
   readers get native semantics while the mark below does the drawing. */
.jpf-choice-input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	opacity: 0;
	pointer-events: none;
}

.jpf-choice-mark {
	flex: none;
	position: relative;
	display: grid;
	place-items: center;
	width: 19px;
	height: 19px;
	margin-top: 1px;
	color: transparent;
	background: var(--jpf-input-bg);
	border: 1.5px solid var(--jpf-border-strong);
	border-radius: 5px;
	transition:
		border-color var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease),
		color var(--jpf-dur) var(--jpf-ease);
}

/* Radios read as circles; checkboxes as squares. */
.jpf-field-radio .jpf-choice-mark,
.jpf-rating .jpf-choice-mark {
	border-radius: 50%;
}

.jpf-field-radio .jpf-choice-mark::after {
	content: "";
	width: 8px;
	height: 8px;
	background: currentColor;
	border-radius: 50%;
	transform: scale(0);
	transition: transform var(--jpf-dur) var(--jpf-ease);
}

.jpf-choice-input:checked ~ .jpf-choice-mark {
	color: #fff;
	background: var(--jpf-accent);
	border-color: var(--jpf-accent);
}

.jpf-field-radio .jpf-choice-input:checked ~ .jpf-choice-mark::after {
	transform: scale(1);
}

.jpf-choice-input:checked ~ .jpf-choice-mark .jpf-icon {
	animation: jpf-pop 0.22s var(--jpf-ease);
}

@keyframes jpf-pop {
	from { transform: scale(0.4); opacity: 0; }
	to { transform: scale(1); opacity: 1; }
}

/* Only a boxed choice highlights its whole row when picked — on a plain one
   the filled control is the answer, and tinting the line as well is noise. */
.jpf-choices-boxed .jpf-choice:has(.jpf-choice-input:checked) {
	background: rgb(var(--jpf-accent-rgb) / 0.05);
	border-color: var(--jpf-accent);
}

.jpf-choices-boxed .jpf-choice:has(.jpf-choice-input:focus-visible) {
	box-shadow: var(--jpf-ring);
	border-color: var(--jpf-accent);
}

/* Keyboard focus still has to be visible without the card. */
.jpf-choice:has(.jpf-choice-input:focus-visible) .jpf-choice-mark {
	box-shadow: var(--jpf-ring);
	border-color: var(--jpf-accent);
}

.jpf-choice-label {
	font-size: 0.94em;
	line-height: 1.45;
}

.jpf-choice-label a {
	color: var(--jpf-accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.jpf-other-input { margin-top: 8px; }

/* Consent sits flush; it is prose with a box, not a card. */
.jpf-consent {
	background: transparent;
	border-color: transparent;
	padding: 0;
}

.jpf-consent:hover { border-color: transparent; }

.jpf-consent:has(.jpf-choice-input:checked) {
	background: transparent;
	border-color: transparent;
}

/* ==================================================================
 * Composite fields — name, address
 * ================================================================== */

.jpf-composite {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.jpf-sub {
	flex: 1 1 100%;
	min-width: 0;
}

.jpf-composite-name .jpf-sub { flex: 1 1 0; }
.jpf-composite-name .jpf-sub-narrow { flex: 0 0 90px; }
.jpf-composite-address .jpf-sub-half { flex: 1 1 calc(50% - 5px); }

/* Explicit per-part widths. These beat the type's own defaults above because
   they come later at equal specificity, which is the point: a part only gets
   one of these classes when someone chose a width for it. */
.jpf-composite .jpf-sub-w-full { flex: 1 1 100%; }
.jpf-composite .jpf-sub-w-two-thirds { flex: 1 1 calc(66.666% - 4px); }
.jpf-composite .jpf-sub-w-half { flex: 1 1 calc(50% - 5px); }
.jpf-composite .jpf-sub-w-third { flex: 1 1 calc(33.333% - 7px); }
.jpf-composite .jpf-sub-w-quarter { flex: 1 1 calc(25% - 8px); }

.jpf-sub-label {
	display: block;
	margin-top: 5px;
	color: var(--jpf-muted);
	font-size: 0.74em;
	line-height: 1.3;
}

/* The sub-labels are redundant when the placeholder already says the same
   thing, so they only appear once a value is present. */
.jpf-sub .jpf-input:placeholder-shown ~ .jpf-sub-label {
	opacity: 0;
	visibility: hidden;
}

.jpf-sub .jpf-sub-label {
	opacity: 1;
	visibility: visible;
	transition: opacity var(--jpf-dur) var(--jpf-ease);
}

@media (max-width: 600px) {
	/* Every part stacks by default, including the narrow ones. A 90px Prefix
	   box sitting alone on a row above a full-width First name reads as a
	   broken layout — the narrow width only earns its place when something
	   sits beside it. Overridable per part below. */
	.jpf-composite-name .jpf-sub,
	.jpf-composite-name .jpf-sub-narrow,
	.jpf-composite-address .jpf-sub,
	.jpf-composite-address .jpf-sub-half,
	.jpf-composite .jpf-sub[class*="jpf-sub-w-"] {
		flex: 1 1 100%;
	}

	/* ...unless the part names its own mobile width. The extra .jpf-sub is
	   load-bearing: the stack rule above carries an attribute selector, so it
	   is 0,3,0 and a plain two-class override here would silently lose to it. */
	.jpf-composite .jpf-sub.jpf-sub-m-full { flex: 1 1 100%; }
	.jpf-composite .jpf-sub.jpf-sub-m-two-thirds { flex: 1 1 calc(66.666% - 4px); }
	.jpf-composite .jpf-sub.jpf-sub-m-half { flex: 1 1 calc(50% - 5px); }
	.jpf-composite .jpf-sub.jpf-sub-m-third { flex: 1 1 calc(33.333% - 7px); }
	.jpf-composite .jpf-sub.jpf-sub-m-quarter { flex: 1 1 calc(25% - 8px); }
}

/* ==================================================================
 * File upload
 * ================================================================== */

.jpf-dropzone {
	position: relative;
	border: 1.5px dashed var(--jpf-border-strong);
	border-radius: var(--jpf-radius);
	background: var(--jpf-input-bg);
	transition:
		border-color var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease);
}

.jpf-dropzone:hover,
.jpf-dropzone.is-dragging {
	border-color: var(--jpf-accent);
	background: rgb(var(--jpf-accent-rgb) / 0.04);
}

.jpf-dropzone.is-dragging { border-style: solid; }

.jpf-file-input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
	cursor: pointer;
}

.jpf-dropzone:has(.jpf-file-input:focus-visible) {
	border-color: var(--jpf-accent);
	box-shadow: var(--jpf-ring);
}

.jpf-dropzone-inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 9px;
	padding: 26px 18px;
	text-align: center;
	pointer-events: none;
}

.jpf-dropzone-icon {
	color: var(--jpf-accent);
	transition: transform var(--jpf-dur) var(--jpf-ease);
}

.jpf-dropzone.is-dragging .jpf-dropzone-icon { transform: translateY(-3px) scale(1.08); }

.jpf-dropzone-text strong {
	display: block;
	font-size: 0.92em;
	font-weight: 600;
}

.jpf-dropzone-text span {
	display: block;
	margin-top: 3px;
	color: var(--jpf-muted);
	font-size: 0.78em;
}

.jpf-file-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.jpf-file-list:not(:empty) {
	padding: 10px;
	border-top: 1px solid var(--jpf-border);
}

.jpf-file-item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 10px;
	border-radius: 8px;
	background: rgb(var(--jpf-accent-rgb) / 0.05);
	animation: jpf-slide-in 0.22s var(--jpf-ease);
}

.jpf-file-item + .jpf-file-item { margin-top: 6px; }
.jpf-file-item.is-invalid { background: var(--jpf-error-bg); color: var(--jpf-error); }

.jpf-file-name {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	font-size: 0.84em;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.jpf-file-size {
	flex: none;
	color: var(--jpf-muted);
	font-size: 0.76em;
	font-variant-numeric: tabular-nums;
}

.jpf-file-remove {
	flex: none;
	display: grid;
	place-items: center;
	width: 24px;
	height: 24px;
	padding: 0;
	color: var(--jpf-muted);
	background: none;
	border: 0;
	border-radius: 6px;
	cursor: pointer;
	transition: color var(--jpf-dur) var(--jpf-ease), background-color var(--jpf-dur) var(--jpf-ease);
}

.jpf-file-remove:hover {
	color: var(--jpf-error);
	background: rgb(225 29 72 / 0.1);
}

@keyframes jpf-slide-in {
	from { opacity: 0; transform: translateY(-4px); }
	to { opacity: 1; transform: translateY(0); }
}

/* ==================================================================
 * Rating
 * ================================================================== */

.jpf-rating {
	display: inline-flex;
	gap: 4px;
}

.jpf-rating-input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.jpf-rating-item {
	display: grid;
	place-items: center;
	padding: 3px;
	color: var(--jpf-border-strong);
	cursor: pointer;
	transition: color var(--jpf-dur) var(--jpf-ease), transform var(--jpf-dur) var(--jpf-ease);
}

.jpf-rating-item .jpf-icon { fill: transparent; transition: fill var(--jpf-dur) var(--jpf-ease); }

.jpf-rating-item:hover { transform: scale(1.15); }

/**
 * Hovering a star lights it and everything before it. `:has` + the sibling
 * combinator gets this with no JavaScript: the trick is that the markup is
 * input/label pairs in order, so "the label I am hovering, and any label
 * before a hovered one" is expressible.
 */
.jpf-rating:hover .jpf-rating-item { color: #f59e0b; }
.jpf-rating:hover .jpf-rating-item .jpf-icon { fill: #f59e0b; }

.jpf-rating .jpf-rating-item:hover ~ .jpf-rating-item,
.jpf-rating:hover .jpf-rating-item:has(~ .jpf-rating-item:hover) ~ .jpf-rating-item {
	color: var(--jpf-border-strong);
}

.jpf-rating .jpf-rating-item:hover ~ .jpf-rating-item .jpf-icon {
	fill: transparent;
}

/* Checked state: the chosen star and every earlier one stay lit. */
.jpf-rating-input:checked ~ .jpf-rating-item { color: var(--jpf-border-strong); }
.jpf-rating-input:checked ~ .jpf-rating-item .jpf-icon { fill: transparent; }

.jpf-rating-input:checked + .jpf-rating-item,
.jpf-rating-input:checked + .jpf-rating-item ~ .jpf-rating-item { color: var(--jpf-border-strong); }

.jpf-rating:not(:hover) .jpf-rating-item.is-filled { color: #f59e0b; }
.jpf-rating:not(:hover) .jpf-rating-item.is-filled .jpf-icon { fill: #f59e0b; }

.jpf-rating-input:focus-visible + .jpf-rating-item {
	outline: 2px solid var(--jpf-accent);
	outline-offset: 2px;
	border-radius: 4px;
}

.jpf-rating-heart:not(:hover) .jpf-rating-item.is-filled,
.jpf-rating-heart:hover .jpf-rating-item { color: #e11d48; }
.jpf-rating-heart:not(:hover) .jpf-rating-item.is-filled .jpf-icon,
.jpf-rating-heart:hover .jpf-rating-item .jpf-icon { fill: #e11d48; }

.jpf-rating-thumbs-up:not(:hover) .jpf-rating-item.is-filled,
.jpf-rating-thumbs-up:hover .jpf-rating-item,
.jpf-rating-circle:not(:hover) .jpf-rating-item.is-filled,
.jpf-rating-circle:hover .jpf-rating-item { color: var(--jpf-accent); }
.jpf-rating-thumbs-up:not(:hover) .jpf-rating-item.is-filled .jpf-icon,
.jpf-rating-thumbs-up:hover .jpf-rating-item .jpf-icon,
.jpf-rating-circle:not(:hover) .jpf-rating-item.is-filled .jpf-icon,
.jpf-rating-circle:hover .jpf-rating-item .jpf-icon { fill: var(--jpf-accent); }

/* ==================================================================
 * Range
 * ================================================================== */

.jpf-range { padding-top: 6px; }

.jpf-range-input {
	width: 100%;
	height: 6px;
	margin: 0;
	padding: 0;
	background: var(--jpf-border);
	border-radius: 999px;
	outline: none;
	appearance: none;
	-webkit-appearance: none;
	cursor: pointer;
	/* The filled portion is painted by the JS updating --jpf-range-pct. */
	background-image: linear-gradient(var(--jpf-accent), var(--jpf-accent));
	background-size: var(--jpf-range-pct, 50%) 100%;
	background-repeat: no-repeat;
}

.jpf-range-input::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 20px;
	height: 20px;
	background: #fff;
	border: 2px solid var(--jpf-accent);
	border-radius: 50%;
	box-shadow: var(--jpf-shadow-md);
	cursor: grab;
	transition: transform var(--jpf-dur) var(--jpf-ease), box-shadow var(--jpf-dur) var(--jpf-ease);
}

.jpf-range-input::-moz-range-thumb {
	width: 20px;
	height: 20px;
	background: #fff;
	border: 2px solid var(--jpf-accent);
	border-radius: 50%;
	box-shadow: var(--jpf-shadow-md);
	cursor: grab;
}

.jpf-range-input:hover::-webkit-slider-thumb { transform: scale(1.12); }
.jpf-range-input:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.05); }
.jpf-range-input:focus-visible::-webkit-slider-thumb { box-shadow: var(--jpf-ring); }

.jpf-range-output {
	display: inline-block;
	margin-top: 10px;
	padding: 3px 10px;
	color: #fff;
	font-size: 0.82em;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	background: var(--jpf-accent);
	border-radius: 999px;
}

.jpf-range-scale {
	display: flex;
	justify-content: space-between;
	margin-top: 6px;
	color: var(--jpf-muted);
	font-size: 0.74em;
	font-variant-numeric: tabular-nums;
}

/* ==================================================================
 * Layout fields
 * ================================================================== */

.jpf-heading {
	margin: 0;
	color: var(--jpf-label);
	font-size: 1.3em;
	font-weight: 700;
	letter-spacing: -0.015em;
	line-height: 1.25;
}

.jpf-field-heading { margin-top: 4px; }
.jpf-align-center { text-align: center; }
.jpf-align-right { text-align: right; }

.jpf-paragraph {
	color: var(--jpf-muted);
	font-size: 0.92em;
	line-height: 1.6;
}

.jpf-paragraph p { margin: 0 0 0.6em; }
.jpf-paragraph p:last-child { margin-bottom: 0; }

.jpf-divider {
	height: 0;
	margin: 4px 0;
	border: 0;
	border-top: 1px solid var(--jpf-border);
}

/* ==================================================================
 * Stepper
 * ================================================================== */

.jpf-stepper { margin-bottom: 28px; }

.jpf-stepper-list {
	display: flex;
	align-items: flex-start;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: none;
}

.jpf-stepper-item {
	position: relative;
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	min-width: 0;
	text-align: center;
}

/* The connector between markers. Drawn on the item rather than between them
   so the last one can simply not have it. */
.jpf-stepper-item:not(:last-child)::after {
	content: "";
	position: absolute;
	top: 15px;
	left: calc(50% + 20px);
	right: calc(-50% + 20px);
	height: 2px;
	background: var(--jpf-border);
	border-radius: 2px;
	transition: background-color 0.3s var(--jpf-ease);
}

.jpf-stepper-item.is-done::after { background: var(--jpf-accent); }

.jpf-stepper-marker {
	position: relative;
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	color: var(--jpf-muted);
	font-size: 0.8em;
	font-weight: 700;
	background: var(--jpf-input-bg);
	border: 2px solid var(--jpf-border);
	border-radius: 50%;
	transition:
		color 0.25s var(--jpf-ease),
		background-color 0.25s var(--jpf-ease),
		border-color 0.25s var(--jpf-ease),
		transform 0.25s var(--jpf-ease);
}

.jpf-stepper-marker > * { grid-area: 1 / 1; }
.jpf-stepper-tick { opacity: 0; transform: scale(0.5); transition: opacity 0.2s var(--jpf-ease), transform 0.2s var(--jpf-ease); }

.jpf-stepper-item.is-active .jpf-stepper-marker {
	color: #fff;
	background: var(--jpf-accent);
	border-color: var(--jpf-accent);
	box-shadow: var(--jpf-ring);
	transform: scale(1.08);
}

.jpf-stepper-item.is-done .jpf-stepper-marker {
	color: #fff;
	background: var(--jpf-accent);
	border-color: var(--jpf-accent);
}

.jpf-stepper-item.is-done .jpf-stepper-num { opacity: 0; }
.jpf-stepper-item.is-done .jpf-stepper-tick { opacity: 1; transform: scale(1); }

.jpf-stepper-num { transition: opacity 0.2s var(--jpf-ease); }

.jpf-stepper-label {
	color: var(--jpf-muted);
	font-size: 0.8em;
	font-weight: 500;
	line-height: 1.3;
	transition: color 0.25s var(--jpf-ease);
}

.jpf-stepper-item.is-active .jpf-stepper-label {
	color: var(--jpf-label);
	font-weight: 650;
}

.jpf-stepper-item.is-done .jpf-stepper-label { color: var(--jpf-text); }

/* Tabs variant */
.jpf-stepper-tabs .jpf-stepper-list {
	gap: 6px;
	padding: 5px;
	background: rgb(var(--jpf-accent-rgb) / 0.05);
	border-radius: calc(var(--jpf-radius) * 0.9);
}

.jpf-stepper-tabs .jpf-stepper-item {
	flex-direction: row;
	justify-content: center;
	padding: 9px 12px;
	border-radius: calc(var(--jpf-radius) * 0.7);
	transition: background-color 0.25s var(--jpf-ease);
}

.jpf-stepper-tabs .jpf-stepper-item::after { display: none; }
.jpf-stepper-tabs .jpf-stepper-item.is-active { background: var(--jpf-input-bg); box-shadow: var(--jpf-shadow-sm); }

.jpf-stepper-tabs .jpf-stepper-marker {
	width: 21px;
	height: 21px;
	font-size: 0.7em;
	border-width: 1.5px;
}

.jpf-stepper-tabs .jpf-stepper-item.is-active .jpf-stepper-marker {
	box-shadow: none;
	transform: none;
}

/* Dots variant */
.jpf-stepper-dots .jpf-stepper-list { justify-content: center; gap: 9px; }
.jpf-stepper-dots .jpf-stepper-item { flex: none; }
.jpf-stepper-dots .jpf-stepper-item::after { display: none; }

.jpf-stepper-dots .jpf-stepper-marker {
	width: 9px;
	height: 9px;
	border-width: 0;
	background: var(--jpf-border-strong);
}

.jpf-stepper-dots .jpf-stepper-num,
.jpf-stepper-dots .jpf-stepper-tick { display: none; }

.jpf-stepper-dots .jpf-stepper-item.is-active .jpf-stepper-marker {
	width: 26px;
	border-radius: 999px;
	box-shadow: none;
	transform: none;
}

.jpf-stepper-dots .jpf-stepper-item.is-done .jpf-stepper-marker { background: var(--jpf-accent); }

/* Progress bar variant */
.jpf-progress-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 9px;
}

.jpf-progress-label {
	color: var(--jpf-label);
	font-size: 0.95em;
	font-weight: 650;
}

.jpf-progress-count {
	color: var(--jpf-muted);
	font-size: 0.8em;
	font-variant-numeric: tabular-nums;
}

.jpf-progress-track {
	height: 7px;
	overflow: hidden;
	background: var(--jpf-border);
	border-radius: 999px;
}

.jpf-progress-fill {
	height: 100%;
	background: linear-gradient(90deg, var(--jpf-accent), rgb(var(--jpf-accent-rgb) / 0.7));
	border-radius: 999px;
	transition: width 0.4s var(--jpf-ease);
}

@media (max-width: 640px) {
	/* Step titles do not survive being squeezed into a phone's width. */
	.jpf-stepper-progress-numbers .jpf-stepper-label { display: none; }
	.jpf-stepper-tabs .jpf-stepper-label { display: none; }
}

/* Step transitions */
.jpf-step {
	animation: jpf-step-in 0.32s var(--jpf-ease);
}

.jpf-step.is-leaving-back { animation: jpf-step-in-back 0.32s var(--jpf-ease); }

@keyframes jpf-step-in {
	from { opacity: 0; transform: translateX(14px); }
	to { opacity: 1; transform: translateX(0); }
}

@keyframes jpf-step-in-back {
	from { opacity: 0; transform: translateX(-14px); }
	to { opacity: 1; transform: translateX(0); }
}

.jpf-step-head { margin-bottom: 20px; }

.jpf-step-title {
	margin: 0;
	color: var(--jpf-label);
	font-size: 1.22em;
	font-weight: 700;
	letter-spacing: -0.015em;
}

.jpf-step-desc {
	margin: 5px 0 0;
	color: var(--jpf-muted);
	font-size: 0.9em;
}

/* ==================================================================
 * Buttons
 * ================================================================== */

.jpf-actions {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 26px;
}

.jpf-actions-main {
	display: flex;
	gap: 10px;
	margin-left: auto;
}

.jpf-actions-left .jpf-actions-main { margin-left: 0; margin-right: auto; }
.jpf-actions-center { justify-content: center; }
.jpf-actions-center .jpf-actions-main { margin: 0 auto; }
.jpf-actions-full .jpf-actions-main { flex: 1; }
.jpf-actions-full .jpf-btn-submit,
.jpf-actions-full .jpf-btn-next { flex: 1; }

/* A multistep form keeps Back on the left and Continue on the right,
   regardless of the button alignment chosen for a single-step form. */
.jpf-is-multistep .jpf-actions .jpf-actions-main { margin-left: auto; }

.jpf-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 0 20px;
	min-height: var(--jpf-input-h);
	color: #fff;
	font: inherit;
	font-size: 0.94em;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	background: var(--jpf-accent);
	border: 1px solid transparent;
	border-radius: var(--jpf-radius);
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
	transition:
		transform var(--jpf-dur) var(--jpf-ease),
		box-shadow var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease),
		opacity var(--jpf-dur) var(--jpf-ease);
}

.jpf-btn-primary {
	box-shadow:
		0 1px 2px rgb(var(--jpf-accent-rgb) / 0.3),
		0 6px 18px -6px rgb(var(--jpf-accent-rgb) / 0.5);
}

.jpf-btn-primary:hover:not(:disabled) {
	transform: translateY(-1px);
	box-shadow:
		0 2px 4px rgb(var(--jpf-accent-rgb) / 0.3),
		0 10px 26px -8px rgb(var(--jpf-accent-rgb) / 0.6);
}

.jpf-btn-primary:active:not(:disabled) {
	transform: translateY(0);
	box-shadow: 0 1px 2px rgb(var(--jpf-accent-rgb) / 0.3);
}

.jpf-btn:focus-visible {
	outline: none;
	box-shadow: var(--jpf-ring), 0 6px 18px -6px rgb(var(--jpf-accent-rgb) / 0.5);
}

.jpf-btn-ghost {
	color: var(--jpf-text);
	background: transparent;
	border-color: var(--jpf-border);
	box-shadow: none;
}

.jpf-btn-ghost:hover:not(:disabled) {
	background: rgb(var(--jpf-accent-rgb) / 0.05);
	border-color: var(--jpf-accent);
	color: var(--jpf-accent);
}

.jpf-btn-small { min-height: 38px; padding: 0 15px; font-size: 0.86em; }
.jpf-btn-large { min-height: 54px; padding: 0 28px; font-size: 1.02em; }

.jpf-btn:disabled,
.jpf-btn.is-loading {
	cursor: not-allowed;
	opacity: 0.75;
}

.jpf-btn.is-loading { pointer-events: none; }
.jpf-btn.is-loading .jpf-btn-label { opacity: 0.85; }
.jpf-btn.is-loading .jpf-icon:not(.jpf-spinner) { display: none; }

.jpf-spinner {
	display: none;
	width: 15px;
	height: 15px;
	border: 2px solid rgb(255 255 255 / 0.35);
	border-top-color: #fff;
	border-radius: 50%;
	animation: jpf-spin 0.6s linear infinite;
}

.jpf-btn.is-loading .jpf-spinner { display: block; }

@keyframes jpf-spin { to { transform: rotate(360deg); } }

/* ==================================================================
 * Messages
 * ================================================================== */

.jpf-form-message:empty { display: none; }
.jpf-form-message { margin-top: 18px; }

.jpf-notice {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	padding: 14px 16px;
	border-radius: var(--jpf-radius);
	font-size: 0.92em;
	line-height: 1.5;
	animation: jpf-slide-in 0.3s var(--jpf-ease);
}

.jpf-notice .jpf-icon { margin-top: 1px; }
.jpf-notice-text > p { margin: 0 0 0.5em; }
.jpf-notice-text > p:last-child { margin-bottom: 0; }

.jpf-notice-success {
	color: var(--jpf-success);
	background: var(--jpf-success-bg);
	border: 1px solid rgb(5 150 105 / 0.2);
}

.jpf-notice-error {
	color: var(--jpf-error);
	background: var(--jpf-error-bg);
	border: 1px solid rgb(225 29 72 / 0.2);
}

.jpf-notice-info,
.jpf-notice-warning {
	color: var(--jpf-text);
	background: rgb(var(--jpf-accent-rgb) / 0.06);
	border: 1px solid rgb(var(--jpf-accent-rgb) / 0.18);
}

.jpf-notice-warning { color: #b45309; background: #fffbeb; border-color: rgb(180 83 9 / 0.2); }

.jpf-notice-wrap { padding: 0; }

/* The success state that replaces the form after an AJAX submit. */
.jpf-success-panel {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	padding: 44px 24px;
	text-align: center;
	animation: jpf-success-in 0.45s var(--jpf-ease);
}

@keyframes jpf-success-in {
	from { opacity: 0; transform: scale(0.97); }
	to { opacity: 1; transform: scale(1); }
}

.jpf-success-icon {
	display: grid;
	place-items: center;
	width: 58px;
	height: 58px;
	color: #fff;
	background: var(--jpf-success);
	border-radius: 50%;
	animation: jpf-success-pop 0.5s var(--jpf-ease) 0.1s backwards;
}

@keyframes jpf-success-pop {
	0% { transform: scale(0); }
	60% { transform: scale(1.12); }
	100% { transform: scale(1); }
}

.jpf-success-text { font-size: 1em; line-height: 1.6; }
.jpf-success-text > p { margin: 0 0 0.6em; }
.jpf-success-text > p:last-child { margin-bottom: 0; }
.jpf-success-text h1, .jpf-success-text h2, .jpf-success-text h3 { margin: 0 0 0.3em; }

/* ==================================================================
 * Payments
 * ================================================================== */

.jpf-presets {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
	gap: 8px;
}

.jpf-preset-input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.jpf-preset {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	min-height: var(--jpf-input-h);
	padding: 10px 8px;
	background: var(--jpf-input-bg);
	border: 1.5px solid var(--jpf-border);
	border-radius: var(--jpf-radius);
	cursor: pointer;
	text-align: center;
	transition:
		border-color var(--jpf-dur) var(--jpf-ease),
		background-color var(--jpf-dur) var(--jpf-ease),
		transform var(--jpf-dur) var(--jpf-ease);
}

.jpf-preset:hover { border-color: var(--jpf-border-strong); transform: translateY(-1px); }

.jpf-preset-amount {
	font-size: 1.02em;
	font-weight: 700;
	letter-spacing: -.02em;
	font-variant-numeric: tabular-nums;
}

.jpf-preset-label { font-size: .74em; color: var(--jpf-muted); }

.jpf-preset-input:checked + .jpf-preset {
	color: var(--jpf-accent);
	background: rgb(var(--jpf-accent-rgb) / .07);
	border-color: var(--jpf-accent);
}

.jpf-preset-input:focus-visible + .jpf-preset {
	box-shadow: var(--jpf-ring);
	border-color: var(--jpf-accent);
}

.jpf-preset-custom-wrap { margin-top: 10px; }

/* The amount box, with its currency symbol inside the field. */
.jpf-amount { position: relative; }

.jpf-amount-symbol {
	position: absolute;
	top: 50%;
	left: 14px;
	transform: translateY(-50%);
	color: var(--jpf-muted);
	font-weight: 600;
	pointer-events: none;
}

.jpf-amount-input {
	padding-left: 34px;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

/* Number spinners fight the padding on every browser. */
.jpf-amount-input::-webkit-outer-spin-button,
.jpf-amount-input::-webkit-inner-spin-button,
.jpf-qty-input::-webkit-outer-spin-button,
.jpf-qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.jpf-amount-input, .jpf-qty-input { -moz-appearance: textfield; appearance: textfield; }

.jpf-price-fixed {
	display: flex;
	align-items: center;
	min-height: var(--jpf-input-h);
	padding: 10px 14px;
	background: rgb(var(--jpf-accent-rgb) / .06);
	border: 1px solid rgb(var(--jpf-accent-rgb) / .2);
	border-radius: var(--jpf-radius);
}

.jpf-price-fixed .jpf-price-value {
	font-size: 1.1em;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--jpf-accent);
	font-variant-numeric: tabular-nums;
}

.jpf-choice-priced { justify-content: flex-start; }

.jpf-choice-priced .jpf-choice-label { flex: 1; }

.jpf-choice-price {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--jpf-accent);
	white-space: nowrap;
}

.jpf-qty { display: flex; align-items: center; gap: 10px; }
.jpf-qty .jpf-qty-input { max-width: 110px; text-align: center; font-weight: 600; }
.jpf-qty-unit { color: var(--jpf-muted); font-size: .86em; }

/* The running total. */
.jpf-total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin-top: 22px;
	padding: 14px 16px;
	background: rgb(var(--jpf-accent-rgb) / .06);
	border: 1px solid rgb(var(--jpf-accent-rgb) / .2);
	border-radius: var(--jpf-radius);
	transition: opacity var(--jpf-dur) var(--jpf-ease);
}

/* Nothing chosen yet: still visible, but not shouting a £0.00 total. */
.jpf-total.is-zero { opacity: .6; }

.jpf-total-label {
	font-size: .84em;
	font-weight: 650;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--jpf-muted);
}

.jpf-total-value {
	font-size: 1.5em;
	font-weight: 800;
	letter-spacing: -.03em;
	color: var(--jpf-accent);
	font-variant-numeric: tabular-nums;
}

.jpf-captcha { margin-top: 18px; }

/* The honeypot. Kept out of view without display:none, which bots skip. */
.jpf-hp {
	position: absolute !important;
	left: -9999px !important;
	top: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* ==================================================================
 * Themes
 * ================================================================== */

/* Minimal — no boxes, a single rule under each field. */
.jpf-theme-minimal {
	--jpf-input-bg: transparent;
}

.jpf-theme-minimal .jpf-input {
	padding-left: 0;
	padding-right: 0;
	border-width: 0 0 1.5px;
	border-radius: 0;
	box-shadow: none;
}

.jpf-theme-minimal .jpf-input:focus {
	border-color: var(--jpf-accent);
	box-shadow: 0 1.5px 0 0 var(--jpf-accent);
}

.jpf-theme-minimal .jpf-select { padding-right: 26px; }
.jpf-theme-minimal .jpf-select-arrow { right: 2px; }
.jpf-theme-minimal .jpf-choice { padding-left: 0; background: transparent; border-color: transparent; }
.jpf-theme-minimal .jpf-choice:has(.jpf-choice-input:checked) { background: transparent; }
.jpf-theme-minimal .jpf-field-date .jpf-input-wrap::after,
.jpf-theme-minimal .jpf-field-time .jpf-input-wrap::after { right: 2px; }

/* Underline — a filled well with an accent underline on focus. */
.jpf-theme-underline .jpf-input {
	background: rgb(var(--jpf-accent-rgb) / 0.04);
	border-width: 0 0 2px;
	border-color: var(--jpf-border-strong);
	border-radius: calc(var(--jpf-radius) * 0.5) calc(var(--jpf-radius) * 0.5) 0 0;
	box-shadow: none;
}

.jpf-theme-underline .jpf-input:focus {
	background: rgb(var(--jpf-accent-rgb) / 0.07);
	border-color: var(--jpf-accent);
	box-shadow: none;
}

/* Boxed — the whole form is a card. */
.jpf-theme-boxed .jpf-form {
	padding: 30px;
	background: var(--jpf-input-bg);
	border: 1px solid var(--jpf-border);
	border-radius: calc(var(--jpf-radius) * 1.4);
}

.jpf-theme-boxed.jpf-shadow-sm .jpf-form { box-shadow: var(--jpf-shadow-sm); }
.jpf-theme-boxed.jpf-shadow-md .jpf-form { box-shadow: var(--jpf-shadow-md); }
.jpf-theme-boxed.jpf-shadow-lg .jpf-form { box-shadow: var(--jpf-shadow-lg); }

@media (max-width: 600px) {
	.jpf-theme-boxed .jpf-form { padding: 20px; }
}

/* Glass — a frosted card. Falls back to a solid card where backdrop-filter
   is unsupported, which is why the background has an opaque-ish base. */
.jpf-theme-glass .jpf-form {
	padding: 30px;
	background: rgb(255 255 255 / 0.68);
	border: 1px solid rgb(255 255 255 / 0.5);
	border-radius: calc(var(--jpf-radius) * 1.4);
	box-shadow: var(--jpf-shadow-lg);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
	.jpf-theme-glass .jpf-form {
		background: rgb(255 255 255 / 0.42);
		-webkit-backdrop-filter: blur(18px) saturate(1.7);
		backdrop-filter: blur(18px) saturate(1.7);
	}
}

.jpf-theme-glass .jpf-input {
	background: rgb(255 255 255 / 0.6);
	border-color: rgb(255 255 255 / 0.7);
}

.jpf-theme-glass .jpf-input:focus { background: rgb(255 255 255 / 0.85); }
.jpf-theme-glass .jpf-choice { background: rgb(255 255 255 / 0.5); border-color: rgb(255 255 255 / 0.6); }

/* Glass, when dark is turned on. Same reasoning as the tokens above: opt-in,
   not decided by the visitor's operating system. */
.jpf-theme-glass.jpf-dark .jpf-form {
	background: rgb(15 23 42 / 0.55);
	border-color: rgb(255 255 255 / 0.1);
}

.jpf-theme-glass.jpf-dark .jpf-input {
	background: rgb(255 255 255 / 0.07);
	border-color: rgb(255 255 255 / 0.12);
}

.jpf-theme-glass.jpf-dark .jpf-choices-boxed .jpf-choice {
	background: rgb(255 255 255 / 0.05);
	border-color: rgb(255 255 255 / 0.1);
}

/* Shadow levels for the non-card themes apply to the inputs. */
.jpf-shadow-none .jpf-input { box-shadow: none; }
.jpf-shadow-md:not(.jpf-theme-boxed):not(.jpf-theme-glass) .jpf-input { box-shadow: var(--jpf-shadow-md); }
.jpf-shadow-lg:not(.jpf-theme-boxed):not(.jpf-theme-glass) .jpf-input { box-shadow: var(--jpf-shadow-md); }

/* ==================================================================
 * Field sizes
 * ================================================================== */

.jpf-size-small { --jpf-input-h: 38px; }
.jpf-size-small .jpf-input { padding: 8px 11px; }
.jpf-size-small .jpf-textarea { min-height: 96px; }

.jpf-size-large { --jpf-input-h: 54px; }
.jpf-size-large .jpf-input { padding: 14px 17px; }
.jpf-size-large .jpf-textarea { min-height: 150px; }

/* ==================================================================
 * Reduced motion
 * ================================================================== */

@media (prefers-reduced-motion: reduce) {
	.jpf-form-wrap *,
	.jpf-form-wrap *::before,
	.jpf-form-wrap *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	.jpf-btn-primary:hover:not(:disabled) { transform: none; }
	.jpf-rating-item:hover { transform: none; }
}

/* ==================================================================
 * Print
 * ================================================================== */

@media print {
	.jpf-actions,
	.jpf-stepper,
	.jpf-dropzone { display: none; }

	.jpf-step[hidden] { display: block !important; }
	.jpf-input { border: 1px solid #999; box-shadow: none; }
}
