/*
 * The Kitchensmiths booking form — Gravity Forms form 1, re-skinned to the
 * design's "Book a Consultation" panel
 * (docs/design/kitchensmiths-redesign.html lines 2333-2411).
 *
 * SCOPED TO .ks-booking-form THROUGHOUT, without exception. The site runs
 * eleven Gravity Forms; this skin is written against one of them. A rule that
 * escapes this scope silently redesigns the contact, job-application,
 * brochure and appliance-enquiry forms, none of which anyone would be looking
 * at when they broke.
 *
 * Gravity Forms' default theme here is `orbital`, which exposes CSS custom
 * properties. Where one exists it is used, because overriding a variable
 * rides along with the theme's own cascade instead of fighting it; the
 * property names below were read out of
 * plugins/gravityforms/assets/css/dist/gravity-forms-theme-framework.min.css
 * rather than guessed, since a misspelt custom property fails silently.
 *
 * Every value here traces to a design line. Where a rule sets a property the
 * variables cannot reach, the design line is cited on the rule.
 */

/* -------------------------------------------------------------------------
 * Orbital's own variables.
 *
 * --gf-ctrl-size-md defaults to 38px, which is what the unstyled panel
 * measured; the design's controls are 50px (line 2341).
 * ---------------------------------------------------------------------- */

.ks-booking-form .gform_wrapper {
	--gf-ctrl-size-md: 50px;
	--gf-ctrl-radius: 0;
	--gf-ctrl-border-width: 1px;
	--gf-ctrl-border-color: rgba(28, 42, 51, 0.2);
	--gf-ctrl-border-color-hover: rgba(28, 42, 51, 0.4);
	--gf-ctrl-border-color-focus: #b08d57;
	--gf-ctrl-bg-color: #ffffff;
	--gf-ctrl-bg-color-focus: #ffffff;
	--gf-ctrl-accent-color: #b08d57;
	--gf-ctrl-color: #1c2a33;
	--gf-ctrl-font-family: Jost, sans-serif;
	--gf-ctrl-font-size: 15px;
	--gf-ctrl-font-weight: 300;
	--gf-ctrl-padding-x: 14px;

	--gf-ctrl-label-color-primary: #8c9099;
	--gf-ctrl-label-color-req: #b08d57;
	--gf-ctrl-label-font-family-primary: Jost, sans-serif;
	--gf-ctrl-label-font-size-primary: 11px;
	--gf-ctrl-label-font-weight-primary: 500;
	--gf-ctrl-label-letter-spacing-primary: 0.14em;

	--gf-ctrl-desc-color: #8c9099;
	--gf-ctrl-desc-font-family: Jost, sans-serif;
	--gf-ctrl-desc-font-size: 13px;
	--gf-ctrl-desc-font-weight: 300;

	/*
	 * Row rhythm — design lines 2338 / 2352 / 2369: rows inside a group sit
	 * 20px apart.
	 *
	 * --gf-FORM-gap-y, not --gf-FIELD-gap-y. The first is the gap BETWEEN
	 * fields and defaults to 40px; the second is the gap between inputs
	 * WITHIN one field and defaults to 12px. Measured before this was here:
	 * every one of the eleven gaps down the panel was 40px.
	 */
	--gf-form-gap-y: 20px;
	--gf-form-gap-x: 20px;
	--gf-field-gap-y: 9px;

	/* Design line 2400. Defaults to 130px. */
	--gf-ctrl-textarea-height: 110px;
	--gf-ctrl-textarea-radius: 0;
	--gf-ctrl-textarea-line-height: 1.6;

	/*
	 * The submit button, design line 2409.
	 *
	 * Driven entirely through variables rather than by a rule on the button.
	 * Gravity Forms' framework styles it via selectors of the shape
	 * `.gform-theme--framework.gform-theme.gform_wrapper button.button:where(…)`
	 * — four classes and an element, and `:where()` contributes nothing — so a
	 * sanely-scoped rule of ours loses on specificity and the button stays
	 * Gravity Forms blue. Measured: rgb(32, 76, 229) with the rule in place.
	 * Custom properties INHERIT, so setting them here wins without an
	 * escalation to !important that the next person would have to escalate
	 * past in turn.
	 */
	--gf-ctrl-btn-bg-color-primary: #b08d57;
	--gf-ctrl-btn-bg-color-hover-primary: #1c2a33;
	--gf-ctrl-btn-bg-color-focus-primary: #1c2a33;
	--gf-ctrl-btn-color-primary: #16222a;
	--gf-ctrl-btn-color-hover-primary: #f5f2ec;
	--gf-ctrl-btn-color-focus-primary: #f5f2ec;
	--gf-ctrl-btn-border-color-primary: #b08d57;
	--gf-ctrl-btn-border-color-hover-primary: #1c2a33;
	--gf-ctrl-btn-border-color-focus-primary: #1c2a33;
	--gf-ctrl-btn-radius: 0;
	--gf-ctrl-btn-size-md: 64px;
	--gf-ctrl-btn-padding-x-md: 32px;
	--gf-ctrl-btn-font-family: Jost, sans-serif;
	--gf-ctrl-btn-font-size-md: 12px;
	--gf-ctrl-btn-font-weight: 500;
	--gf-ctrl-btn-letter-spacing: 0.14em;
}

/* -------------------------------------------------------------------------
 * Labels and descriptions (design lines 2340, 2364).
 *
 * text-transform has no orbital variable, so it is set directly.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gfield_label,
.ks-booking-form .gform-field-label {
	text-transform: uppercase;
	margin-bottom: 9px;
}

/* The sub-labels under the name field's three inputs (Salutation / First /
   Last, design line 2340) are the same micro-label, one step quieter. */
.ks-booking-form .ginput_complex label {
	text-transform: uppercase;
	font: 500 10px/1 Jost, sans-serif;
	letter-spacing: 0.12em;
	color: #8c9099;
}

/* The design's own sub-line above the form already says "Fields marked * are
   required" (line 2335), so Gravity Forms' legend would say it twice. */
.ks-booking-form .gform_heading,
.ks-booking-form .gform_required_legend {
	display: none;
}

/* -------------------------------------------------------------------------
 * Controls (design line 2341).
 *
 * Set explicitly as well as by variable: the variables carry most of it, but
 * the point here is the measured result, not the elegance of the cascade.
 *
 * ON THE LONG SELECTORS BELOW. Gravity Forms' framework styles controls
 * through chains of the shape
 * `.gform-theme--framework.gform-theme.gform_wrapper <el>:where(…)` — three
 * classes on one element, with `:where()` contributing nothing — which is
 * (0,3,1). A rule scoped only `.ks-booking-form .gform_wrapper <el>` is
 * (0,2,1) and LOSES, even though this stylesheet is enqueued last. Measured
 * while getting this wrong: the textarea stayed at Gravity Forms' 192px and
 * the submit button at its content width of 209px, while the browser's own
 * matched-rules inspector happily listed our rule as applying — it lists
 * matches, not winners, which is what made this worth writing down.
 *
 * So the two rules that have to beat that chain repeat it. Everything else
 * here is either variable-driven (variables inherit, so specificity never
 * enters into it) or targets something Gravity Forms does not itself style.
 * ---------------------------------------------------------------------- */

.ks-booking-form input[type="text"],
.ks-booking-form input[type="email"],
.ks-booking-form input[type="tel"],
.ks-booking-form input[type="number"],
.ks-booking-form select:not(.nav) {
	height: 50px;
	min-height: 50px;
	border: 1px solid rgba(28, 42, 51, 0.2);
	border-radius: 0;
	background-color: #ffffff;
	font-family: Jost, sans-serif;
	font-size: 15px;
	font-weight: 300;
	color: #1c2a33;
	padding: 0 14px;
}

/*
 * A <select> with `appearance: none` lays its text out as a normal line box,
 * so LINE-HEIGHT decides where that text sits — unlike an <input>, which
 * centres its value vertically whatever the line-height is. Under the shared
 * `15px` line-height this rule used to carry, a chosen salutation rendered
 * hard against the TOP edge of its 50px control while every text input beside
 * it looked correctly centred. That asymmetry is why this is a rule of its own
 * rather than a value in the block above.
 *
 * 48px = the 50px control less its two 1px borders.
 *
 * `:not(.nav)` here and above keeps all of it off the datepicker's own year
 * and month selects, which are a different size entirely.
 */
.ks-booking-form select:not(.nav) {
	line-height: 48px;
}

/* Height, radius and line-height come from the --gf-ctrl-textarea-*
   variables above; these are the properties those variables do not cover. */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework textarea {
	/* Design line 2400. --gf-ctrl-textarea-height is honoured as far as
	   --gf-local-height, but Gravity Forms' own min-block-size wins the
	   computed value, so the height is pinned here. See the note on this
	   rule's SELECTOR above for why it is as long as it is. */
	height: 110px;
	min-height: 110px;
	border-color: rgba(28, 42, 51, 0.2);
	background-color: #ffffff;
	font-family: Jost, sans-serif;
	font-size: 15px;
	font-weight: 300;
	color: #1c2a33;
}

.ks-booking-form input:focus,
.ks-booking-form select:focus,
.ks-booking-form textarea:focus {
	border-color: #b08d57;
	outline: 1px solid #b08d57;
	outline-offset: -2px;
}

/* The name field's 120px / 1fr / 1fr split (design line 2338). Gravity Forms
   emits its own grid row here, whose default is three equal auto columns. */
.ks-booking-form .ginput_container_name.gform-grid-row {
	display: grid;
	grid-template-columns: 120px minmax(0, 1fr) minmax(0, 1fr);
	gap: 20px;
}

.ks-booking-form .ginput_container_name .gform-grid-col {
	max-width: none;
	padding: 0;
}

/* The date CONTROL fills its field, like every other control in the panel.
 *
 * Gravity Forms fixes `input.datepicker` at 198px, a width its own layout was
 * built around and one that has nothing to do with this panel. Measured: 198px
 * inside a 256px field at 1440 and inside a 302px field at 390, with the
 * remainder left as bare panel beside it, while the email and postcode inputs
 * on either side ran the full width of their fields. It read as a field that
 * had failed to load rather than a deliberately short one.
 *
 * GROWN, NOT SET TO 100%. `.ginput_container` here is a flex row of three: the
 * input, an empty <kbd> the datepicker uses for keyboard hints, and the 24px
 * calendar toggle. At `width: 100%` the input claims the whole row and pushes
 * the toggle past the panel's right edge. `min-width: 0` because a flex item
 * will not shrink below its intrinsic content width without it.
 */
.ks-booking-form .gfield--type-date .ginput_container input.datepicker {
	flex: 1 1 auto;
	width: auto;
	min-width: 0;
}

/*
 * Gravity Forms gives every `gform-grid-row` a `margin: 0 -6px` negative
 * gutter, to be cancelled by 6px of padding on each grid column. Where this
 * skin sets its own column widths that padding is gone, and the row is left
 * 12px wider than its field, hanging 6px past the panel's inner edge on both
 * sides.
 *
 * Measured: the NAME row spanned 749.3 → 1294 while every other field in the
 * panel spanned 755.3 → 1288 — visible as the salutation/first/last trio
 * sitting a couple of pixels proud of the email and postcode boxes below it.
 *
 * Zeroed on the grid row itself rather than per field type. It was first
 * fixed on the address container alone, which left the identical defect on
 * the name field for someone else to notice — the cause is the grid row, so
 * that is where it is corrected.
 */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-grid-row {
	margin-left: 0;
	margin-right: 0;
}

/* The postcode is an address field with every input but the ZIP hidden, and
   Gravity Forms still sizes that input for a column of a multi-column address
   grid — measured at 280px inside a 572px row. The design gives it the full
   width of the panel (line 2361). */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_address {
	display: block;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_address input,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_address .ginput_full,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_address .ginput_left,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_address .ginput_right {
	width: 100%;
	max-width: none;
	padding-left: 0;
	padding-right: 0;
}

/* -------------------------------------------------------------------------
 * Section headers become the design's accent eyebrows (2337, 2368).
 * ---------------------------------------------------------------------- */

.ks-booking-form .gsection {
	border-bottom: 0;
	margin: 40px 0 0;
	padding: 0;
}

.ks-booking-form .gsection .gsection_title {
	font: 500 11px/1 Jost, sans-serif;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: #b08d57;
	margin: 0;
	padding: 0;
	border: 0;
}

/*
 * The design's vertical rhythm is NOT uniform, so the three places it departs
 * from the 20px row gap are set here rather than by flattening everything to
 * one number:
 *
 *   40px before a section eyebrow   (2368: margin-top 40px)
 *   22px after one                  (2338, 2369: margin-top 22px)
 *   26px before the consent row     (2405: margin-top 26px)
 *
 * Each is the DIFFERENCE from the 20px gap already in force, so changing that
 * gap moves all of them together.
 *
 * The first section sits directly under the panel's own sub-line, which
 * already carries its spacing (2337), so it takes no top margin.
 */
.ks-booking-form .gform_fields > .gsection:first-child {
	margin-top: 0;
	margin-bottom: 2px;
}

.ks-booking-form .gform_fields > .gsection:not(:first-child) {
	margin-top: 20px;
	margin-bottom: 2px;
}

.ks-booking-form .gfield--type-consent {
	margin-top: 6px;
}

/* -------------------------------------------------------------------------
 * Segmented radio rows — fields 10, 13 and 26 (design 2375, 2384, 2392).
 *
 * The input is CLIPPED, not display:none. display:none removes it from the
 * accessibility tree AND from tab order, which would make the time-of-day and
 * designer choices — both REQUIRED — unreachable by keyboard and invisible to
 * a screen reader. Clipping keeps it focusable, which is what makes the
 * :focus-visible ring below mandatory rather than decorative: the native ring
 * is now on a 1px box nobody can see.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gform_wrapper .gfield--type-radio .gfield_radio {
	display: flex;
	/*
	 * flex-direction is the whole fix here. Gravity Forms' framework sets
	 * `.gform-theme--framework .gfield--type-choice .gfield_radio
	 * { display: flex; flex-direction: column }`, and a rule setting only
	 * `display: flex` leaves that column in place — measured: all four
	 * choices still stacked on four separate rows, while every other part of
	 * the button styling had applied and looked correct.
	 */
	flex-direction: row;
	flex-wrap: nowrap;
	gap: 10px;
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice {
	flex: 1;
	margin: 0;
	/*
	 * display:block, because Gravity Forms makes each .gchoice a GRID whose
	 * first column is reserved for the radio input. Clipping the input (see
	 * below) takes it out of flow but does NOT release that column, so the
	 * label was laid out in the second track and sized to its own text:
	 * measured, a 135px choice held a 40px label, leaving the segmented row
	 * as four small boxes with gaps between them instead of four equal
	 * buttons.
	 */
	display: block;
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice input[type="radio"] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice label {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: center;
	height: 46px;
	margin: 0;
	padding: 0 8px;
	border: 1px solid rgba(28, 42, 51, 0.2);
	font: 300 14px/1.2 Jost, sans-serif;
	color: #6b747c;
	text-align: center;
	text-transform: none;
	letter-spacing: 0;
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* Design line 2377 gives the morning/afternoon pair 50px where the other two
   rows get 46px. The class is set by tools/configure-booking-form.php, so no
   field id is pinned in a selector here. */
.ks-booking-form .gform_wrapper .gfield--type-radio.ks-time-of-day .gchoice label {
	height: 50px;
	font-size: 15px;
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice label:hover {
	border-color: rgba(28, 42, 51, 0.4);
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice input[type="radio"]:checked + label {
	border-color: #b08d57;
	background-color: rgba(176, 141, 87, 0.12);
	font-weight: 400;
	color: #1c2a33;
}

.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice input[type="radio"]:focus-visible + label {
	outline: 2px solid #b08d57;
	outline-offset: 2px;
}

/* -------------------------------------------------------------------------
 * Consent (design lines 2405-2407).
 *
 * The description holds the ENTIRE privacy policy, which the design replaces
 * with a link. It is HIDDEN, never deleted — docs/known-issues.md records the
 * link's destination as an open owner decision, and this one declaration
 * reverts once that is settled.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gfield--type-consent > .gfield_label,
.ks-booking-form .gfield--type-consent .gfield_description {
	display: none;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .ginput_container_consent {
	display: flex;
	align-items: flex-start;
	gap: 12px;
}

.ks-booking-form .gfield_consent_label {
	font: 300 15px/1.6 Jost, sans-serif;
	color: #6b747c;
	text-transform: none;
	letter-spacing: 0;
	margin: 0;
}

.ks-booking-form .ginput_container_consent input[type="checkbox"] {
	flex: none;
	width: 18px;
	height: 18px;
	min-height: 0;
	margin: 3px 0 0;
	border-radius: 0;
	accent-color: #b08d57;
}

/* -------------------------------------------------------------------------
 * Submit (design line 2409).
 *
 * A <button type="submit">, NOT an <input type="submit"> — verified against
 * the rendered markup. A rule written for the input selector would match
 * nothing and leave the default blue button in place.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gform_footer {
	margin: 30px 0 0;
	padding: 0;
}

/* The footer is display:flex by default, which sizes the button to its own
   content whatever width it is given. Making the footer a block lets the
   button's width: 100% mean what it says (design line 2409). */
.ks-booking-form .gform_wrapper .gform_footer {
	display: block;
}

/* Colour, size, radius and typography are all variable-driven above. Full
   width and uppercase are the two the variables do not cover. */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform_footer button.gform_button,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform_footer input.gform_button {
	display: block;
	width: 100%;
	text-transform: uppercase;
	cursor: pointer;
}

/* -------------------------------------------------------------------------
 * Validation, repainted into the palette.
 *
 * The MESSAGE stays. Colour must never be the only carrier of an error state
 * (WCAG 1.4.1), and this form's errors are the difference between a booking
 * and a bounce.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gfield_error input,
.ks-booking-form .gfield_error select,
.ks-booking-form .gfield_error textarea {
	border-color: #9b2c2c;
}

.ks-booking-form .gfield_validation_message,
.ks-booking-form .validation_message,
.ks-booking-form .gform_submission_error {
	font: 400 13px/1.5 Jost, sans-serif;
	color: #9b2c2c;
	background: transparent;
	border: 0;
	padding-top: 8px;
}

.ks-booking-form .gform_validation_errors {
	background: rgba(155, 44, 44, 0.06);
	border: 1px solid rgba(155, 44, 44, 0.35);
	border-radius: 0;
	box-shadow: none;
	padding: 16px 18px;
	margin-bottom: 24px;
}

.ks-booking-form .gform_validation_errors > h2 {
	font: 400 15px/1.5 Jost, sans-serif;
	color: #9b2c2c;
	margin: 0;
}

/* -------------------------------------------------------------------------
 * Below 1024px.
 *
 * The design file carries no mobile screen for this page; this matches the
 * page build's own tablet breakpoint. Four buttons across a 390px viewport
 * would compress "No preference" to illegibility, so the rows go two-by-two.
 * ---------------------------------------------------------------------- */

@media (max-width: 1024px) {
	/* Salutation, first name and last name take a row each from 1024 down.
	 *
	 * This was a 100px / 1fr split, which is two columns for three fields: the
	 * salutation and the first name shared the top row and the last name sat
	 * alone underneath, so the two halves of somebody's name were set at two
	 * different widths on two different rows. It read as a broken grid rather
	 * than a deliberate one, and it got narrower the closer the viewport came
	 * to the breakpoint.
	 *
	 * One column serves the whole range. Below 768 the panel loses its side
	 * padding as well, and a 120px salutation box next to a first-name box
	 * would leave the first name under 100px there.
	 *
	 * The 20px gap is a rhythm for columns standing side by side; stacked,
	 * these follow the form's own row rhythm instead.
	 */
	.ks-booking-form .ginput_container_name.gform-grid-row {
		grid-template-columns: minmax(0, 1fr);
		gap: 12px;
	}

	.ks-booking-form .gform_wrapper .gfield--type-radio .gfield_radio {
		flex-wrap: wrap;
	}

	.ks-booking-form .gform_wrapper .gfield--type-radio .gchoice {
		flex: 1 1 calc(50% - 5px);
	}
}

/* -------------------------------------------------------------------------
 * The date picker.
 *
 * The design has no calendar mockup — it draws the date field as a plain
 * bordered control (line 2372) and stops there. So this invents nothing: it
 * reuses the panel's own vocabulary (Jost, square corners, hairline borders,
 * the accent for selection) so the popup does not read as a piece of another
 * product dropped onto the page. Left alone it renders in the system UI font
 * with a royal-blue selected day and striped rows.
 *
 * Gravity Forms 3.0 builds its own calendar as `.gform-datepicker-calendar`,
 * NOT jQuery UI's body-level `#ui-datepicker-div`, and renders it INSIDE the
 * field — verified in the DOM. So it sits within `.ks-booking-form` and the
 * scoping that covers the rest of this file covers it too, with no global
 * leak onto the site's other ten forms.
 * ---------------------------------------------------------------------- */

.ks-booking-form .gform-datepicker-calendar {
	border: 1px solid rgba(28, 42, 51, 0.2);
	border-radius: 0;
	background: #ffffff;
	box-shadow: 0 18px 40px rgba(28, 42, 51, 0.12);
	font-family: Jost, sans-serif;
	padding: 6px;
}

/*
 * THE MONTH AND YEAR HEADER.
 *
 * Gravity Forms draws these as two full-width bordered dropdowns stacked one
 * above the other, each flanked by a pair of buttons — four form controls
 * sitting on top of a calendar, in a panel whose whole character is quiet
 * type on flat colour. They are still selects, because they are genuinely
 * useful for jumping a year ahead and because replacing them would mean
 * replacing behaviour this skin has no business owning; they are just no
 * longer DRESSED as form fields.
 *
 * The two rows are in DOM order year-then-month and cannot be swapped in CSS
 * — they are table rows, and every trick for reordering them (flex or grid on
 * the tbody) breaks the day grid underneath, which depends on real table
 * layout. So the hierarchy is carried by type instead: the year is a quiet
 * uppercase micro-label, the month a Marcellus line, which is the same
 * eyebrow-then-heading pairing the rest of the page uses.
 */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar select.nav {
	height: 34px;
	min-height: 34px;
	width: auto;
	border: 0;
	border-radius: 0;
	background-color: transparent;
	/*
	 * No chevron. Gravity Forms draws one as a background image on every
	 * select, which on this header meant three affordances for one control —
	 * a chevron and a pair of arrows — on a line whose whole job is to read
	 * as a heading. Both selects still open on click.
	 */
	background-image: none;
	/* Gravity Forms puts a soft blue-tinted shadow on every control. On a
	   borderless header select it reads as a stray box floating around the
	   month name. */
	box-shadow: none;
	color: #1c2a33;
	/* Even spacing now that no chevron needs room on the right. (This rule
	   lost its padding entirely to Gravity Forms' own (0,4,1) selector chain
	   before it was lengthened to match, which put the chevron on top of the
	   text and rendered "2026" as "202".) */
	padding: 0 8px;
	text-align: center;
	text-align-last: center;
	cursor: pointer;
	/*
	 * Both mechanisms, because the cell's `text-align: center` alone does
	 * nothing here: Gravity Forms renders its controls block-level, and a
	 * block ignores its parent's text-align. Measured — the label cells were
	 * correctly centred on the calendar's midpoint (921px) while both selects
	 * sat flush against the cells' left edge at 808px.
	 */
	display: inline-block;
	margin-inline: auto;
}

/* No `max-width: 100%` on the selects above: the header's middle cell is
   sized by table layout, it measured 24px, and a select capped to its cell
   was clipped to about a character and a half. Letting the select size to its
   own content makes the cell grow to fit instead. */
/*
 * `:not(.nav)` matters here. The prev and next cells carry the row's own
 * class TOO — the arrow beside the year is `td.nav.prev.btn.year` — so a bare
 * `.year` selector styles the arrows as well as the label, and a width set
 * that way fought the 32px the arrows are meant to be. (It also made this
 * easy to misdiagnose: a probe reading `.yearSelector .year` returns the
 * 24px ARROW cell, not the colspan-5 label cell beside it.)
 *
 * The label cell already spans five of the seven columns, so it needs no
 * width — only its contents centred within it.
 */
.ks-booking-form .gform-datepicker-calendar .yearSelector td.year:not(.nav),
.ks-booking-form .gform-datepicker-calendar .monthSelector td.month:not(.nav) {
	text-align: center;
	white-space: nowrap;
}

/* The year: the panel's micro-label, one step down from the month. */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar .yearSelector select.nav {
	font: 500 11px/34px Jost, sans-serif;
	letter-spacing: 0.14em;
	color: #8c9099;
}

/* The month: the same Marcellus the page gives every heading. */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar .monthSelector select.nav {
	font: 400 21px/34px Marcellus, serif;
	letter-spacing: 0;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar select.nav:hover {
	color: #b08d57;
}

.ks-booking-form .gform-datepicker-calendar select.nav:focus-visible {
	outline: 2px solid #b08d57;
	outline-offset: 2px;
}

/* Tighten the two header rows; the defaults leave them as tall as form rows. */
.ks-booking-form .gform-datepicker-calendar .yearSelector td.year:not(.nav),
.ks-booking-form .gform-datepicker-calendar .monthSelector td.month:not(.nav) {
	padding: 0;
}

.ks-booking-form .gform-datepicker-calendar .yearSelector td,
.ks-booking-form .gform-datepicker-calendar .monthSelector td {
	background: transparent;
	border: 0;
}

.ks-booking-form .gform-datepicker-calendar .yearSelector td {
	padding-top: 4px;
}

/*
 * A hairline between the header and the grid, the way the design's own rules
 * separate the 01-04 steps (line 2298).
 *
 * Drawn on the WEEKDAY row's top edge, not on the month row's bottom edge.
 * The header row is three cells — arrow, a colspan-5 label, arrow — and they
 * are not contiguous: measured, they run 772-796, 808-1035, 1046-1070, so a
 * border on each renders as three separate dashes with two gaps. The weekday
 * row is seven adjacent cells spanning the full width, so one rule there is
 * one continuous line.
 */
.ks-booking-form .gform-datepicker-calendar .monthSelector td {
	padding-bottom: 10px;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar th.week {
	border-top: 1px solid rgba(28, 42, 51, 0.16);
}

/*
 * The year keeps no arrows — a year is picked, not cycled, and stepping to it
 * one press at a time is not a journey anyone wants. The select itself still
 * opens on click, so nothing is lost but the pair of controls.
 *
 * The BUTTON is hidden rather than its cell: this is the first row in a
 * `table-layout: fixed` table, so its cells are what establish the seven
 * column widths for the entire calendar underneath. Removing a cell here
 * would re-flow the day grid.
 */
/*
 * `visibility: hidden`, after two narrower attempts failed:
 *
 *   - `td.nav .btn` matches nothing. The `btn` class is on the TD itself
 *     (`td.nav.prev.btn.year`), not on a child.
 *   - Hiding the cell's children does not hide the arrow. All four nav spans
 *     are ALREADY `display: none` in Gravity Forms' own CSS — they hold
 *     fallback glyphs (⇐ ⇒ ← →) — and the arrow a visitor actually sees is
 *     drawn by a pseudo-element on the cell.
 *
 * `visibility: hidden` covers the cell, its children and its pseudo-elements
 * together, and takes the cell out of the tab order — which matters, since
 * the markup gives it `tabindex="0"` and `role="button"` and neither can be
 * removed from a stylesheet. The cell itself STAYS: this is the first row of
 * a `table-layout: fixed` table, so its cells establish the seven column
 * widths for the whole day grid below.
 */
.ks-booking-form .gform-datepicker-calendar .yearSelector td.nav {
	visibility: hidden;
}

/* Prev / next on the month, which IS what a visitor cycles. Small, quiet and
   square — navigation, not buttons. */
.ks-booking-form .gform-datepicker-calendar td.nav {
	width: 32px;
}

.ks-booking-form .gform-datepicker-calendar td.nav .btn,
.ks-booking-form .gform-datepicker-calendar .nav .btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	margin: 0 auto;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: #8c9099;
	cursor: pointer;
	transition: color 0.15s ease, background-color 0.15s ease;
}

.ks-booking-form .gform-datepicker-calendar td.nav .btn:hover {
	color: #b08d57;
	background: rgba(176, 141, 87, 0.12);
}

/* Weekday header, as the same micro-label used throughout the panel. */
.ks-booking-form .gform-datepicker-calendar th.week {
	background: transparent;
	border: 0;
	padding: 10px 0 6px;
	font: 500 10px/1 Jost, sans-serif;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #8c9099;
}

/* Day cells. The default alternates a grey row stripe, which reads as noise
   against a calm panel; the grid is legible without it. */
.ks-booking-form .gform-datepicker-calendar td.day,
.ks-booking-form .gform-datepicker-calendar td.empty {
	background: transparent;
	border: 0;
	padding: 0;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.day span,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.empty span {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 38px;
	font: 300 14px/1 Jost, sans-serif;
	color: #57616a;
	/* A transparent border on EVERY day, so the selected day's border below
	   changes only its colour and never the cell's size. */
	border: 1px solid transparent;
}

.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.day:hover span {
	background: rgba(176, 141, 87, 0.12);
	color: #1c2a33;
}

/* Today: marked by a hairline, so it stays distinguishable from the SELECTED
   day below without competing with it. */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.dayToday:not(.dayMarked) span {
	box-shadow: inset 0 0 0 1px rgba(176, 141, 87, 0.55);
	color: #1c2a33;
}

/*
 * The selected day. Gravity Forms' own is royal blue (rgb(32, 76, 229)),
 * which belongs to no part of this palette.
 *
 * `dayMarked` as well as `selected`: the chosen cell carries BOTH, plus
 * `dayToday` when it happens to be today, and it is dayMarked that Gravity
 * Forms paints. Selector prefixed with its own theme chain for the same
 * specificity reason as the controls above — measured, the span stayed blue
 * under a shorter selector.
 */
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.selected span,
.ks-booking-form .gform_wrapper.gform-theme.gform-theme--framework .gform-datepicker-calendar td.dayMarked span {
	background: #b08d57;
	/* Gravity Forms puts its royal blue on the border as well as the fill. */
	border-color: #b08d57;
	color: #16222a;
	font-weight: 400;
}

.ks-booking-form .gform-datepicker-calendar td.day:focus-visible span {
	outline: 2px solid #b08d57;
	outline-offset: -2px;
}

/* "Press F1 for help" — a keyboard hint the design has no room for, and
   which names a key most visitors will never press. Kept in the DOM for
   screen readers rather than removed. */
.ks-booking-form .gform-datepicker-calendar .monthMessage {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* The trigger icon inside the date control (design line 2372 draws the field
   plain; the icon is Gravity Forms' and is kept, toned to the palette). */
.ks-booking-form .gform-datepicker-toggle {
	color: #8c9099;
	background: transparent;
	border: 0;
}

.ks-booking-form .gform-datepicker-toggle:hover {
	color: #b08d57;
}

/* -------------------------------------------------------------------------
   THE PHONE — sizes, and the order things come in.

   /book/ was built with tablet overrides and no phone ones. Elementor's
   generated stylesheet for this page carries exactly two declarations inside
   `@media(max-width:767px)` — a container width and a side padding — and not
   one font size, so every heading arrives on a 390px screen at the size it was
   drawn for a 1320px one. The h1 is 56px. The section is 96px of padding above
   and 110px below. It is the same fault the home page had.

   FIXED HERE RATHER THAN IN THE BUILDER, deliberately. Post #20 is
   build-locked AND kitchensmiths_build_has_drifted() reports true, which means
   it has been edited in the Elementor editor since its last build. Releasing
   the lock to add `typography_font_size_mobile` settings to build-book.php
   would regenerate the document and discard those edits — the precise failure
   docs/build-locks.md exists to prevent. Overriding in CSS leaves the document
   untouched, so the hand edits survive and so do these rules.

   WHY THE SELECTORS CARRY `body .elementor`. Elementor scopes its own rules as
   `.elementor-20 .elementor-element.elementor-element-<id>`, and that id comes
   from uniqid() in tools/lib/elementor-helpers.php — it is regenerated on
   every build, so nothing here may name one or it would silently stop applying
   the next time the page is rebuilt. These anchor on the classes
   build-book.php authors instead (ks-book-form-section, ks-booking-panel,
   ks-booking-images), and `body` supplies the weight needed to outrank
   Elementor's three-class rules without reaching for !important.
   ------------------------------------------------------------------------- */

@media (max-width: 767px) {

	/* --- A short introduction, then the form ------------------------- */

	/* The row holds two children: a column of copy and the form panel. On a
	   phone they stack in that order, so a four-step explainer, a notice panel
	   and four reasons to choose us all came before the form — which is the
	   point of the page and the only thing on it a visitor has to reach. */
	.ks-book-form-section > .e-con-inner > .e-con {
		display: flex;
		flex-direction: column;
		flex-wrap: nowrap;
		/* The row's own 48px row-gap would fall between the panel and the
		   copy column. The copy column spaces itself with each widget's own
		   margins, so 0 keeps that rhythm and the only space this change
		   introduces is the form panel's own margin below. */
		gap: 0;
	}

	/* --- The hero scrim ---------------------------------------------- */

	/* MEASURED, NOT GUESSED. kitchensmiths_sec_hero() lays a 100deg gradient
	   over the photograph, from rgba(22,34,42,0.84) on the left to 0.1 on the
	   right. That was tuned for the design's own hero images, which are dark
	   kitchens. This page's is a bright, busy desk shot — white plans, a
	   window, a glass — and on a phone the copy spans the full width, so its
	   right-hand end lands on the 0.1 end of the gradient over the brightest
	   part of the picture.

	   Measured against the bare scrim with the text hidden: the standfirst
	   ran at 1.41:1 and the h1 at 2.89:1, against the 4.5:1 and 3:1 that
	   WCAG AA asks for. It was not subtly poor, it was unreadable in places.

	   A FLAT SCRIM IS NOT THE ANSWER, and this is the second attempt. The
	   weakest even wash that clears 4.5:1 over a white pixel is about 0.78,
	   and at 0.78 the photograph is gone — the hero reads as a dark grey
	   panel with type on it, which defeats the entire point of putting a
	   picture there. Anything light enough to see the photograph through
	   fails the standfirst.

	   So the text moves instead of the light. The copy is pushed to the
	   bottom of a taller hero and the scrim ramps to 0.82 beneath it, which
	   leaves the top HALF of the photograph almost untouched — and that is
	   the half with the two faces and the plans in it. Legible type and a
	   visible photograph, rather than a compromise that loses both. */
	/* Through the custom properties, not the properties themselves. An
	   Elementor container resolves its own layout as
	   `justify-content: var(--justify-content)`, so a direct declaration here
	   is simply overwritten by the variable — set `justify-content: flex-end`
	   and the copy does not move, which is exactly what happened first. */
	body .elementor .elementor-element.ks-book-hero {
		--min-height: 520px;
		--justify-content: flex-end;
		--padding-bottom: 34px;
	}

	body .elementor .elementor-element.ks-book-hero::before {
		background-image: linear-gradient(
			180deg,
			rgba(22, 34, 42, 0.12) 0%,
			rgba(22, 34, 42, 0.18) 34%,
			rgba(22, 34, 42, 0.82) 52%,
			rgba(22, 34, 42, 0.88) 100%
		);
	}

	/* THE FORM FIRST. This used to be an order scale across seven items: the
	   copy column was dissolved with `display: contents` so its six children
	   could interleave with the panel, which slotted in at 4 — after the
	   breadcrumb, the heading and the standfirst, and before the explainer.

	   The hero made all of that unnecessary. Those three now open the page
	   above this section, which leaves the copy column holding only the three
	   blocks that belong AFTER the form, so the panel simply comes first and
	   the column keeps its own box and its natural order. Counting nth-child
	   through a dissolved column was the fragile part — it silently pointed
	   at the wrong blocks the moment the column's length changed, which is
	   exactly what the hero did to it. Nothing here counts children now. */
	body .elementor .elementor-element.ks-booking-panel {
		order: -1;
		/* 32px clear of the explainer beneath. Nothing above: the section's
		   own 48px padding-top already separates it from the hero. */
		margin: 0 0 32px;
	}

	/* --- Sizes ------------------------------------------------------- */

	/* The page h1 used to be the first widget in this section and needed a
	   phone size, because build-book.php set 56px flat. It lives in the hero
	   now, and kitchensmiths_sec_hero() ships 58/44/34 across the three
	   breakpoints, so the override that stood here would apply to nothing.
	   Removed rather than repointed: the hero already answers it. */

	/* "Ask for an appointment", 30px desktop. */
	body .elementor .elementor-element.ks-booking-panel .elementor-widget-heading .elementor-heading-title {
		font-size: 24px;
	}

	/* --- Padding ----------------------------------------------------- */

	/* 96/110 is a desktop rhythm. On a 390px screen it is a third of the
	   viewport spent before the heading. */
	body .elementor .elementor-element.ks-book-form-section {
		--padding-top: 48px;
		--padding-bottom: 56px;
	}

	/* The .ks-booking-images rule that stood here went with the section: the
	   closing image strip was removed when its better photograph became the
	   hero. See tools/build-book.php. */

	/* The panel is 52px of side padding inside the page's own 24px, which
	   leaves 290px of a 390px screen for the fields. */
	body .elementor .elementor-element.ks-booking-panel {
		--padding-top: 28px;
		--padding-right: 20px;
		--padding-bottom: 28px;
		--padding-left: 20px;
	}

	/* The "Please note" panel, 34/36 desktop. It was the copy column's fifth
	   child while the breadcrumb, heading and standfirst sat above it; with
	   those three now in the hero it is the second.

	   FULLY ANCHORED FROM THE SECTION, and that is not tidiness. This began
	   `.ks-book-form-section .e-con > .e-con:not(.ks-booking-panel) > .e-con:nth-child(2)`,
	   whose leading descendant combinator let it match the second child of
	   ANY container in the section — so it also indented the text column of
	   every 01-04 step and the second column of "Why Kitchensmiths" by 22px.
	   At nth-child(5) that was rare enough to go unseen; at (2) it is
	   everywhere. The `>` chain below can only ever reach the copy column's
	   own second child. */
	body .elementor .ks-book-form-section > .e-con-inner > .e-con > .e-con:not(.ks-booking-panel) > .e-con:nth-child(2) {
		--padding-top: 24px;
		--padding-right: 22px;
		--padding-bottom: 24px;
		--padding-left: 22px;
	}

	/* --- The fields themselves --------------------------------------- */

	/* The name fields stack from 1024 down, in the block above — there is
	   nothing further to do for them here.

	   Preferred date, and the three other half-width fields with it.

	   Gravity Forms lays the panel out on a twelve-column grid and gives
	   `gfield--width-half` a six-column span, so a half field is 175px of a
	   390px viewport before the panel's padding is taken off it. Its own
	   responsive collapse does not arrive until 641px, which leaves the
	   fields halved across the whole 641-767px band this stylesheet treats as
	   a phone. `1 / -1` rather than `span 12` so the field starts at the
	   first line whichever column the previous one ended on — a half field
	   following another half field would otherwise begin at column seven and
	   overflow the row. */
	.ks-booking-form .gform_wrapper .gfield--width-half {
		grid-column: 1 / -1;
	}

}

/* --- Gravity Forms 3.2's row spacers ---------------------------------- */

/* Gravity Forms 3.2 (updated 2026-10-23, just before launch) puts an empty
   `div.spacer.gfield` after a half-width field that has no partner in its
   row, to fill the other six columns. This form never wanted that: email and
   telephone are two halves of one row on desktop and full-width rows on a
   phone (the 1 / -1 rule above). The spacers broke both. On desktop each one
   claimed a row's other half and pushed telephone down a row (+96px); on a
   phone each became a 0px row that still cost a 20px row gap (+40px). The
   update was caught by before/after screenshots. The spacer carries nothing,
   so it is removed from the grid rather than styled around (Dan, 2026-10-23). */
.ks-booking-form .gform_wrapper .gform_fields > .spacer.gfield {
	display: none;
}
