/**
 * Form styling.
 *
 * Loaded only on pages containing a Contact Form 7 form. Contact Form 7's own
 * stylesheet is not loaded; everything it emits is styled here so there is one
 * set of rules rather than two fighting each other.
 *
 * Controls follow the Claude Design: a sunken (surface-sunken) fill, a 12px
 * radius, thin muted labels and pill submit buttons.
 *
 * Accessibility notes:
 * - The resting field border is soft, matching the design, so the field reads
 *   mainly by its fill; the strong green focus ring (3px) carries the active
 *   state. If a procurement requirement needs a 3:1 resting boundary
 *   (WCAG 1.4.11), set the border colour back to --border-strong.
 * - Error state is never colour alone: it adds a thicker border and an icon
 *   glyph, satisfying WCAG 1.4.1.
 * - Focus uses the same ring as the rest of the site.
 */

/*
 * The form is capped at the content measure, not the narrow one.
 *
 * `--width--narrow` (34rem) is the right cap for a single-column form. This one
 * pairs fields, and 34rem is under the 2 x 14rem the paired rows need — so on
 * the contact page every pair silently collapsed back to one field per line and
 * the form read as a long thin ladder. The content measure (44rem) fits two
 * fields plus their gap with room to spare, and still stops the form stretching
 * to the full width of a wide column.
 */
.wpcf7 {
	max-inline-size: min(var(--wp--style--global--content-size), 100%);
}

/*
 * A square-metre figure is at most five characters. Letting it run the full
 * width of the form implies a long answer is expected and makes the column of
 * inputs look ragged where it sits alone between two paired rows.
 */
.wpcf7 input[type="number"] {
	max-inline-size: 12rem;
}

.wpcf7 form > * + * {
	margin-block-start: var(--wp--preset--spacing--m);
}

/*
 * Contact Form 7 wraps its hidden fields in a real `<fieldset>`, which picks up
 * the user-agent's default `2px groove` border and renders as an empty bordered
 * box at the top of every form — indistinguishable from a broken first field.
 * The element still has to exist and still has to submit, so it is reset rather
 * than hidden.
 */
.wpcf7 .hidden-fields-container {
	margin: 0;
	padding: 0;
	border: 0;
}

/* --- Fields -------------------------------------------------------------- */

.indoor-field {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--xs);
	margin-block: 0;
}

/*
 * Two-up rows collapse to one column below the md breakpoint. Intrinsic sizing
 * (minmax + auto-fit) rather than a media query, so the fields respond to the
 * space they are actually given.
 */
.indoor-field-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--m);
	margin-block: 0;
}

.indoor-field label,
.wpcf7 label {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	color: var(--wp--preset--color--text-muted);
	line-height: 1.4;
}

/*
 * "(obligatoriskt)" is spelled out rather than shown as an asterisk. An
 * asterisk alone is ambiguous to screen-reader users and needs a legend.
 */
.indoor-required {
	font-weight: 400;
	color: var(--wp--preset--color--text-muted);
}

.indoor-hint {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--text-muted);
	line-height: 1.4;
}

/* --- Controls ------------------------------------------------------------ */

/*
 * border-box is required, not cosmetic.
 *
 * These controls are 100% wide with 14px of horizontal padding and a 1px
 * border. Under the default content-box, that computes to parent + 30px — a
 * 364px field inside a 334px column, pushing the page 10px wider than a 375px
 * viewport and making the whole page scroll sideways on a phone.
 *
 * Scoped to form controls rather than applied globally, so it cannot disturb
 * block layouts that were built and verified against the current box model.
 */
.wpcf7 input,
.wpcf7 select,
.wpcf7 textarea,
.wpcf7 button {
	box-sizing: border-box;
}

.wpcf7 input[type="text"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"],
.wpcf7 input[type="number"],
.wpcf7 input[type="url"],
.wpcf7 input[type="date"],
.wpcf7 select,
.wpcf7 textarea {
	inline-size: 100%;
	font-family: var(--wp--preset--font-family--body);
	/*
	 * 16px minimum on the actual input: iOS Safari zooms the viewport when a
	 * focused field is smaller than that, which is disorienting mid-form.
	 */
	font-size: max(1rem, var(--wp--preset--font-size--base));
	line-height: 1.5;
	color: var(--wp--preset--color--text-primary);
	/* A brand-green caret, matching the checkbox accent and the focus ring. */
	caret-color: var(--wp--preset--color--brand-primary);
	background-color: var(--wp--preset--color--surface-sunken);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--text-primary) 16%, transparent);
	border-radius: var(--wp--custom--radius--field);
	padding: 0.8rem 0.9rem;
	/* Comfortable 44px target height (WCAG 2.5.8). */
	min-block-size: 44px;
	transition:
		border-color var(--wp--custom--transition--fast),
		box-shadow var(--wp--custom--transition--fast);
}

.wpcf7 textarea {
	min-block-size: 8rem;
	resize: vertical;
}

.wpcf7 select {
	/* Custom chevron as an inline SVG data URI: no extra request, no icon font. */
	appearance: none;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23585652' stroke-width='2' d='M3 6l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.875rem center;
	padding-inline-end: 2.5rem;
}

.wpcf7 input:focus-visible,
.wpcf7 select:focus-visible,
.wpcf7 textarea:focus-visible {
	outline: 3px solid var(--wp--preset--color--brand-primary);
	outline-offset: 1px;
	border-color: var(--wp--preset--color--brand-primary);
}

.wpcf7 input::placeholder,
.wpcf7 textarea::placeholder {
	color: var(--wp--preset--color--text-muted);
	opacity: 1;
}

/* --- File input ---------------------------------------------------------- */

.wpcf7 input[type="file"] {
	inline-size: 100%;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	padding: var(--wp--preset--spacing--xs);
	border: 1px dashed var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--field);
	background-color: var(--wp--preset--color--surface-raised);
}

.wpcf7 input[type="file"]::file-selector-button {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--text-on-dark);
	background-color: var(--wp--preset--color--brand-primary);
	border: 0;
	border-radius: var(--wp--custom--radius--pill);
	padding: 0.5rem 1rem;
	margin-inline-end: var(--wp--preset--spacing--s);
	cursor: pointer;
	min-block-size: 44px;
}

/* --- Consent checkbox ---------------------------------------------------- */

.indoor-consent .wpcf7-list-item {
	margin: 0;
}

.indoor-consent .wpcf7-list-item label {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--wp--preset--spacing--xs);
	align-items: start;
	font-weight: 400;
	cursor: pointer;
}

/*
 * 24px, not 20px. WCAG 2.2 SC 2.5.8 sets a 24x24 minimum for pointer targets.
 * The surrounding <label> is clickable and large enough that the checkbox
 * passed via the spacing exception, but relying on an exception for the one
 * control a visitor must actively tick to submit an enquiry is the wrong
 * trade — especially on touch.
 */
.indoor-consent input[type="checkbox"] {
	inline-size: 1.5rem;
	block-size: 1.5rem;
	margin-block-start: 0.05em;
	accent-color: var(--wp--preset--color--brand-primary);
	flex: 0 0 auto;
}

.indoor-consent input[type="checkbox"]:focus-visible {
	outline: 3px solid var(--wp--preset--color--brand-primary);
	outline-offset: 2px;
}

/* --- Submit -------------------------------------------------------------- */

.wpcf7 input[type="submit"],
.wpcf7 button[type="submit"] {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--text-on-dark);
	background-color: var(--wp--preset--color--brand-primary);
	border: 0;
	border-radius: var(--wp--custom--radius--pill);
	padding: 0.9rem 1.75rem;
	min-block-size: 44px;
	cursor: pointer;
	transition: background-color var(--wp--custom--transition--fast);
}

.wpcf7 input[type="submit"]:hover,
.wpcf7 button[type="submit"]:hover {
	background-color: var(--wp--preset--color--brand-primary-hover);
}

.wpcf7 input[type="submit"]:focus-visible,
.wpcf7 button[type="submit"]:focus-visible {
	outline: 3px solid var(--wp--preset--color--brand-primary);
	outline-offset: 3px;
}

.wpcf7 input[type="submit"]:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

/* --- Validation ---------------------------------------------------------- */

/*
 * Field-level error. The border thickens and an icon is prepended, so the
 * error is never signalled by colour alone (WCAG 1.4.1).
 */
.wpcf7 .wpcf7-not-valid {
	border-color: var(--wp--preset--color--error);
	border-width: 2px;
}

.wpcf7 .wpcf7-not-valid-tip {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3-xs);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--error);
	margin-block-start: var(--wp--preset--spacing--3-xs);
}

.wpcf7 .wpcf7-not-valid-tip::before {
	content: "⚠";
	font-size: 1em;
	line-height: 1;
}

/*
 * The response region. CF7 marks it role="status"/aria-live, so the message is
 * announced without moving focus.
 */
/*
 * Hidden until it has something to say.
 *
 * Contact Form 7 always renders the response container and marks it
 * `aria-hidden="true"` while it is empty, so assistive technology already
 * ignores it — but it still painted a 36px empty bordered box under every form,
 * which looked like a field that had failed to render. Keyed on CF7's own
 * attribute rather than `:empty`, because CF7 toggles that attribute at exactly
 * the moment a message appears.
 */
.wpcf7 .wpcf7-response-output[aria-hidden="true"] {
	display: none;
}

.wpcf7 .wpcf7-response-output {
	margin-block-start: var(--wp--preset--spacing--m);
	margin-inline: 0;
	padding: var(--wp--preset--spacing--s) var(--wp--preset--spacing--m);
	border: 2px solid var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--field);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
}

.wpcf7 form.sent .wpcf7-response-output {
	border-color: var(--wp--preset--color--success);
	background-color: color-mix(in srgb, var(--wp--preset--color--success) 8%, white);
	color: var(--wp--preset--color--success);
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.spam .wpcf7-response-output {
	border-color: var(--wp--preset--color--error);
	background-color: color-mix(in srgb, var(--wp--preset--color--error) 6%, white);
	color: var(--wp--preset--color--error);
}

/* --- Submitting state ---------------------------------------------------- */

.wpcf7 .wpcf7-spinner {
	background-color: var(--wp--preset--color--brand-primary);
}

@media (prefers-reduced-motion: reduce) {
	.wpcf7 .wpcf7-spinner {
		animation: none;
	}
}

@media (forced-colors: active) {
	.wpcf7 input,
	.wpcf7 select,
	.wpcf7 textarea {
		border: 1px solid ButtonText;
	}
}

/* ---------------------------------------------------------------------------
   Hero quote form

   The short four-field enquiry that opens the home page. It sits inside the
   hero rather than behind a button, because the benchmark found no Stockholm
   competitor offering any low-commitment entry point.

   Presented as a panel so it reads as one object against the hero rather than
   as loose fields: a tinted surface, a hairline, and the 8px radius the design
   system permits on rectangles (§9.1 item 6).
   --------------------------------------------------------------------------- */

.indoor-hero-quote .wpcf7 {
	background-color: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--border-subtle);
	border-radius: 8px;
	padding: var(--wp--preset--spacing--m);
	max-inline-size: var(--wp--style--global--content-size);
}

/*
 * Four fields across on a wide hero, dropping to two and then one as space
 * runs out. `auto-fit` with a `minmax` floor rather than breakpoints, so the
 * count follows the space the hero actually has (design-system §4.3 prefers
 * intrinsic layout to media queries).
 */
.indoor-field-row--quad {
	/*
	 * A 13rem floor resolves to two columns in the hero's ~600px half, giving a
	 * tidy 2x2 block. An 11rem floor produced three across and stranded the
	 * fourth field alone on a second row.
	 */
	grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--s);
}

.indoor-hero-quote .indoor-consent {
	margin-block-start: var(--wp--preset--spacing--s);
}

.indoor-hero-quote .wpcf7-submit {
	margin-block-start: var(--wp--preset--spacing--s);
}

/* ---------------------------------------------------------------------------
   Assurances

   The three reassurance lines under the form. Rendered from a real list so the
   count is announced and each item is a list item; the marker is replaced with
   a check drawn in CSS rather than an icon font or an image request.
   --------------------------------------------------------------------------- */

.indoor-assurances {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--m);
	list-style: none;
	margin-block: var(--wp--preset--spacing--m) 0;
	padding-inline-start: 0;
	color: var(--wp--preset--color--text-muted);
}

.indoor-assurances li {
	display: flex;
	align-items: baseline;
	gap: 0.5ch;
}

/*
 * In the hero's right column the three lines stack rather than sit in a row,
 * which is what `flex-wrap` gives once the column is too narrow for two of
 * them side by side. No breakpoint needed.
 */
.indoor-hero-aside .indoor-assurances {
	flex-direction: column;
	gap: var(--wp--preset--spacing--xs);
}

.indoor-hero-aside__phone {
	margin-block-start: var(--wp--preset--spacing--m);
	padding-block-start: var(--wp--preset--spacing--s);
	border-block-start: 1px solid var(--wp--preset--color--border-subtle);
	color: var(--wp--preset--color--text-muted);
}

/*
 * The check is decorative — the sentence carries the meaning — so it is a
 * pseudo-element and never announced. Brand green on the light hero surface
 * measures 8.03:1, well past the 3:1 needed for a non-text indicator.
 */
.indoor-assurances li::before {
	content: "✓";
	color: var(--wp--preset--color--brand-primary);
	font-weight: 600;
}

.indoor-hero-quote__alt {
	margin-block-start: var(--wp--preset--spacing--s);
	color: var(--wp--preset--color--text-muted);
}
