/* ============================================================
   BOZA v7 — Formidable Forms, dressed in the house's clothes.

   The adapter the prototype left open. It maps Formidable's class names onto
   the field styles in base.css and adds nothing of its own: every value here
   is either a token or a measurement taken off `.fld` on the prototype's
   contact page, which is the target that page was drawn to be.

   WHAT LOADS THIS, AND AFTER WHAT
     inc/forms.php, with `boza-adapter` and `formidable` declared as
     dependencies, so this file is always last of the three and never has to
     shout. There are two `!important`s in it and both are answering one.
     The first is the same one `.fld` and `.nl-form` already carry: base.css
     declares the focus ring unconditionally and with `!important`, on purpose,
     and a text field is the one control that opts out of it. The second undoes
     the plugin's `width: 100% !important` in the one place the fields are a
     flex row rather than its grid. Everything else wins on order alone.

   WHY THE PLUGIN'S OWN LOOK IS NOT HERE TO FIGHT
     inc/forms.php takes `with_frm_style` off the wrapper, and every visual
     rule the plugin has is scoped to that class. What survives is the
     plugin's structure: the twelve-column grid, `frm_half` as a span of it,
     `.frm_hidden` for conditional logic, `.frm_screen_reader` for the legend.
     Those keep working and are not restated here.

   THE MAPPING, IN ONE PLACE
     .frm_fields_container   the field grid, gutter 20px  → .fld-grid .fld-row
     .frm_form_field         one labelled field           → .fld
     .frm_primary_label      its label                    → .fld > span
     .frm_description        help under a field           → .note
     .frm_submit             the button row               → .btn-row
     .frm_button_submit      the button itself            → .btn.btn-green
     .frm_error_style        the form failed              → .alert.a-err
     .frm_message            the form worked              → .alert.a-ok
   ============================================================ */

/* ============================================================
   1 · THE TWO RULES THE PLUGIN LOSES WHEN ITS LOOK IS TAKEN OFF

   Neither is decoration. Both were measured on a real form after the style
   class was removed, and without them the page is wrong rather than plain.
   ============================================================ */

/* The honeypot. Formidable's spam trap is a real text input labelled "If you
   are human, leave this field blank", in a container with no class of its own,
   and the plugin hides it in the half of its stylesheet we just declined. Left
   alone it renders: ten words wrapped down a single grid column, on top of the
   real fields, because its wrapper is zero by zero and its children overflow.
   The container is found by what it holds, since it carries nothing else. */
.frm_fields_container div:has( > .frm_verify ) {
	display: none;
}

/* The label above the field rather than beside it. */
.frm_form_field .frm_primary_label {
	display: block;
}

/* ============================================================
   2 · THE FRAME
   ============================================================ */

/* The plugin's wrapper and form element carry nothing. The section they sit in
   has already decided the ground and the width. */
.frm_forms,
.frm-show-form,
.frm_form_fields {
	margin: 0;
}

/* A fieldset is a grouping element here, not a drawn box: the legend is the
   form's accessible name and is already off-screen. */
.frm-show-form fieldset {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

/* The field grid. Formidable lays fields on twelve columns and spans them with
   frm_half, frm_third and frm_full; that is a good system and it is kept. Only
   the gutter changes -- 2% of an unknown width becomes the house's 20px, which
   is the figure the two-up row on the prototype's form was drawn with. */
.frm_form_fields .frm_fields_container,
.frm_form_fields .frm_section_heading,
.frm_combo_inputs_container,
.frm_grid_container {
	column-gap: 20px;
	row-gap: 0;
}

/* Below the two-up breakpoint every field is full width. The house's own
   `.fld-row` collapses at exactly this width, and a form is the one place where
   two half-width fields on a phone is not a tighter layout but an unusable one. */
@media (max-width: 640px) {
	.frm_fields_container > .frm_form_field,
	.frm_fields_container > .frm_submit {
		grid-column: 1 / -1;
	}
}

/* ============================================================
   3 · ONE FIELD  →  .fld
   ============================================================ */

/* The 16px under every field, which with the label's 6px is the rhythm `.fld`
   sets. `div` and not the bare class: Formidable puts `frm_form_field` on the
   honeypot's input as well as on every field's container.

   The field is left as a block. It is tempting to make it a grid with a 6px gap
   -- that is literally what `.fld` is -- but the plugin already grids these
   containers on twelve columns so that a combo field can put First and Last
   side by side inside one field, and a Section can lay its children out. Making
   it a grid here would take that away from every form that ever needs it, to
   arrive at the same six pixels a margin gives. */
div.frm_form_field {
	margin-bottom: 16px;
}

/* No size and no weight: the label inherits the body, which is what the
   prototype's own field label does. Setting `1rem` here made it 16px against
   the target's 17. */
.frm_form_field .frm_primary_label {
	color: var(--ink);
	margin: 0 0 6px;
	padding: 0;
}

/* The asterisk. It is aria-hidden and paired with a real `required`, so it is a
   mark for the eye only: amber, the house's one flourish colour, at the weight
   the rest of the label is not. */
.frm_form_field .frm_required {
	color: var(--amber-ink);
	font-weight: 500;
	margin-left: 2px;
}

/* Help text under a field, which is `.note` everywhere else on the site. */
.frm_form_field .frm_description {
	font-size: 0.92rem;
	line-height: 1.5;
	color: var(--ink-soft);
	margin: 6px 0 0;
	max-width: 54rem;
}

/* ============================================================
   4 · THE CONTROLS  →  .fld input, .fld textarea, .fld select

   Restated rather than inherited: base.css scopes these to `.fld`, and this
   markup has no `.fld` in it anywhere. The values are the same values.

   WHY `:where()` IS ROUND ALL OF IT

   This is the *default* dress for a form control, and a named context must be
   able to take it off. base.css has two such contexts and they are opposites:
   `.fld` is a paper field and `.nl-form` is a dark pill with a white focus
   border. The footer's newsletter is a Formidable form inside `.nl-form`, so a
   rule at `.frm_form_field input[type=email]` -- two classes' worth -- would
   beat `.nl-form input` and paint a paper field on the ink band.

   `:where()` costs nothing, so these land at one element's worth of
   specificity: enough to beat the browser, and enough to lose to any named
   context that has an opinion. Which is exactly the relationship they should
   have. Formidable itself has no unscoped rule that dresses an ordinary
   control -- checked, the whole of its look is behind `.with_frm_style`.
   ============================================================ */
:where( .frm_form_field )
	input:where(
		[type='text'],
		[type='email'],
		[type='tel'],
		[type='url'],
		[type='number'],
		[type='password'],
		[type='date'],
		[type='time']
	),
:where( .frm_form_field ) textarea,
:where( .frm_form_field ) select {
	font: inherit;
	width: 100%;
	padding: 12px 16px;
	border-radius: var(--r-inner);
	border: var(--line-w) solid var(--line);
	background: #fff;
	color: var(--ink);
	outline: none;
	transition: border-color 0.2s, box-shadow 0.2s;
}

/* The same choice base.css makes and for the same reason: a text field is the
   one control where the shared amber focus ring is wrong, because it floats off
   the box while you are typing inside it and it appears on a mouse click as
   well as a Tab. The border goes green and doubles instead.

   `!important` because the ring it is opting out of is `!important`: base.css
   made the ring unconditional after nine of nine controls came back with an
   outline width of zero, and an opt-out from it has to say so as loudly. `.fld`
   and `.nl-form` both do exactly this.

   Found on the error state, not by reading: a field that failed validation is
   focused, so it wore the amber ring and the red border at once, and read as
   two different warnings about the same field. */
:where( .frm_form_field ) input:focus,
:where( .frm_form_field ) textarea:focus,
:where( .frm_form_field ) select:focus {
	border-color: var(--green);
}

:where( .frm_form_field ) input:focus-visible,
:where( .frm_form_field ) textarea:focus-visible,
:where( .frm_form_field ) select:focus-visible {
	outline: none !important;
	box-shadow: 0 0 0 var(--line-w) var(--green);
}

:where( .frm_form_field ) textarea {
	resize: vertical;
	min-height: 110px;
}

/* A select is a control with a mark on it, not a box with a system arrow: the
   arrow is drawn in the house's line colour at the house's weight, and the
   right padding leaves room for it. */
:where( .frm_form_field ) select {
	appearance: none;
	padding-right: 44px;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2317251F' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 16px center;
}

/* Radios and checkboxes: the box keeps the browser's own control, because a
   redrawn one has to reimplement focus, disabled and indeterminate to gain a
   corner radius. What the house sets is the rhythm and the accent. */
.frm_form_field .frm_opt_container {
	display: grid;
	gap: 8px;
}

.frm_form_field .frm_radio,
.frm_form_field .frm_checkbox {
	margin: 0;
}

.frm_form_field .frm_radio label,
.frm_form_field .frm_checkbox label {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 1rem;
	line-height: 1.5;
	color: var(--ink);
	cursor: pointer;
}

.frm_form_field .frm_radio input,
.frm_form_field .frm_checkbox input {
	accent-color: var(--green);
	width: 1.1em;
	height: 1.1em;
	margin: 0.2em 0 0;
	flex: none;
}

/* ============================================================
   5 · THE BUTTON ROW  →  .btn-row

   The button itself is not restyled here. inc/forms.php adds `btn btn-green`
   to it through the plugin's own class filter, so it is the house's button
   rather than a copy of one, and it stays right when the button changes.

   What is here is the icon and the loading state, which the house draws with
   child elements a plugin's button does not have.
   ============================================================ */
.frm_submit {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	align-items: center;
	margin-top: 8px;
}

/* The arrow. A real `.btn` carries an `<svg>`; this one carries a mask of the
   same drawing, so nothing has to be injected into the plugin's markup and
   nothing can be stripped out of it by kses. The hover nudge is the house's. */
.frm_button_submit::after {
	content: '';
	width: 14px;
	height: 14px;
	flex: none;
	margin-right: -0.25em;
	background: currentColor;
	mask: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E" )
		center / contain no-repeat;
	transition: transform var(--t-fast) var(--ease-out), width var(--t-fast) var(--ease-out),
		opacity var(--t-fast), margin var(--t-fast) var(--ease-out);
}

.frm_button_submit:hover::after {
	transform: translateX(4px);
}

/* The loading state, which base.css calls `.btn.is-loading` and says in as many
   words is "shared by buttons and, later, forms". This is later. Formidable
   puts `frm_loading_form` on the form the moment it submits; the arrow folds
   away and the spinner grows in, exactly as it does on a button the theme
   drives itself. */
.frm_loading_form .frm_button_submit {
	pointer-events: none;
	opacity: 0.85;
}

.frm_loading_form .frm_button_submit::after {
	width: 0;
	opacity: 0;
	margin-left: -10px;
	margin-right: 0;
}

.frm_loading_form .frm_button_submit::before {
	content: '';
	width: 1.05em;
	height: 1.05em;
	flex: none;
	margin-left: -0.25em;
	border: var(--line-w-strong) solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	animation: btn-spin 0.7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
	.frm_loading_form .frm_button_submit::before {
		animation-duration: 2.4s;
	}
}

/* ============================================================
   6 · WHEN IT GOES WRONG, AND WHEN IT GOES RIGHT

   Both are the Alerts family, because a form that failed and a notice that
   something is wrong are the same thing said in two places, and the site has
   one drawing for it.
   ============================================================ */

/* The summary at the top of a form that would not send. */
.frm_error_style {
	background: var(--err-bg);
	color: var(--err-fg);
	border: var(--line-w) solid var(--err-line);
	border-radius: var(--r-card);
	padding: 16px 20px;
	margin-bottom: 20px;
	font-size: 0.96rem;
	line-height: 1.5;
}

/* The message under the field that caused it. */
.frm_form_field .frm_error {
	font-size: 0.92rem;
	line-height: 1.5;
	color: var(--err-fg);
	margin: 6px 0 0;
}

/* The field itself. A colour is not the only signal -- the border also doubles
   in weight -- because a red hairline against a grey one is the difference two
   people in twenty cannot see. */
.frm_blank_field input,
.frm_blank_field textarea,
.frm_blank_field select,
.frm_form_field input[aria-invalid='true'],
.frm_form_field textarea[aria-invalid='true'],
.frm_form_field select[aria-invalid='true'] {
	border-color: var(--err-fg);
	box-shadow: inset 0 0 0 var(--line-w) var(--err-fg);
}

/* And when it sends. */
.frm_message,
.frm_success_style {
	background: var(--ok-bg);
	color: var(--ok-fg);
	border: var(--line-w) solid var(--ok-line);
	border-radius: var(--r-card);
	padding: 20px 24px;
	font-size: 1rem;
	line-height: 1.6;
}

.frm_message p,
.frm_success_style p {
	color: inherit;
	margin: 0;
}

.frm_message p + p,
.frm_success_style p + p {
	margin-top: 10px;
}

/* ============================================================
   7 · ON A DARK GROUND

   A form can stand on the green or the ink band -- the newsletter one does --
   and there the paper-coloured field is right but the words around it are not.
   The section sets the ground; the form reads it. `.ft` is in the list because
   the footer is a dark band that does not carry any of the section classes:
   it is its own family and paints its own ground.
   ============================================================ */
.sec-green .frm_form_field .frm_primary_label,
.sec-ink .frm_form_field .frm_primary_label,
.on-ink .frm_form_field .frm_primary_label,
.ft .frm_form_field .frm_primary_label {
	color: #fff;
}

.sec-green .frm_form_field .frm_description,
.sec-ink .frm_form_field .frm_description,
.on-ink .frm_form_field .frm_description,
.ft .frm_form_field .frm_description {
	color: var(--on-ink-dim);
}

.sec-green .frm_form_field .frm_required,
.sec-ink .frm_form_field .frm_required,
.on-ink .frm_form_field .frm_required,
.ft .frm_form_field .frm_required {
	color: var(--amber-soft);
}

/* The one that was measured rather than assumed. `--err-fg` is a paper colour
   and reads 2.3:1 against the ink, which is a fault nothing in this build could
   have caught: the state only exists after somebody presses a button, so no
   checker will ever load a page that has it. Both the message and the ring the
   failed field wears take the dark-ground red. */
.sec-green .frm_form_field .frm_error,
.sec-ink .frm_form_field .frm_error,
.on-ink .frm_form_field .frm_error,
.ft .frm_form_field .frm_error {
	color: var(--err-on-ink);
}

.sec-green .frm_blank_field :is( input, textarea, select ),
.sec-ink .frm_blank_field :is( input, textarea, select ),
.on-ink .frm_blank_field :is( input, textarea, select ),
.ft .frm_blank_field :is( input, textarea, select ) {
	border-color: var(--err-on-ink);
	box-shadow: inset 0 0 0 var(--line-w) var(--err-on-ink);
}

/* A form on a light surface on a dark ground, in a tile or a popup, is the
   paper's form again, as the words around it are (14.13, D84; the surfaces are
   base.css's list). */
:is(.sec-green,.sec-ink,.on-ink) :is(.card:not(.c-ink,.c-green,.qcards>*),.alert:not(.al-ink),.pop,.ibox,.mini,.loc-card,.map-split,.cta-frame,.cta-split) .frm_form_field .frm_primary_label {
	color: var(--ink);
}

:is(.sec-green,.sec-ink,.on-ink) :is(.card:not(.c-ink,.c-green,.qcards>*),.alert:not(.al-ink),.pop,.ibox,.mini,.loc-card,.map-split,.cta-frame,.cta-split) .frm_form_field .frm_description {
	color: var(--ink-soft);
}

:is(.sec-green,.sec-ink,.on-ink) :is(.card:not(.c-ink,.c-green,.qcards>*),.alert:not(.al-ink),.pop,.ibox,.mini,.loc-card,.map-split,.cta-frame,.cta-split) .frm_form_field .frm_required {
	color: var(--amber-ink);
}

:is(.sec-green,.sec-ink,.on-ink) :is(.card:not(.c-ink,.c-green,.qcards>*),.alert:not(.al-ink),.pop,.ibox,.mini,.loc-card,.map-split,.cta-frame,.cta-split) .frm_form_field .frm_error {
	color: var(--err-fg);
}

:is(.sec-green,.sec-ink,.on-ink) :is(.card:not(.c-ink,.c-green,.qcards>*),.alert:not(.al-ink),.pop,.ibox,.mini,.loc-card,.map-split,.cta-frame,.cta-split) .frm_blank_field :is( input, textarea, select ) {
	border-color: var(--err-fg);
	box-shadow: inset 0 0 0 var(--line-w) var(--err-fg);
}

/* ============================================================
   8 · THE SECTION THE FORM SITS IN

   `.ask-grid` and `.ask` are in base.css: the form and a rail beside it, which
   is the shape all three of the prototype's form pages were drawn in. Only the
   two pieces the block adds are here.
   ============================================================ */

/* The form's own cell. `min-width: 0` because a grid cell's automatic minimum
   is its content, and a form with a long placeholder in it would otherwise push
   the rail off the side rather than wrap. */
.ask-grid > .frm-house {
	min-width: 0;
}

/* A form with no rail beside it. Nobody reads a text field eleven hundred
   pixels wide, so it keeps the width it has when the rail is there. */
.form-solo {
	max-width: 640px;
}

/* ============================================================
   9 · THE INLINE NEWSLETTER

   One field and a button on one row, on the ink band at the foot of every
   page. `.nl-form` is base.css's, drawn there and described there; the block
   wraps the form in it and this section only rearranges Formidable's own
   structure to fit. The field's colours are base.css's and are not restated
   -- see why the control rules above are wrapped in `:where()`.
   ============================================================ */

/* The plugin's four wrappers -- container, form, fields, fieldset -- are
   transparent here. As a flex item the outermost one sizes to its content, so
   the row was laid out inside 357 of the 480 pixels it had been given and the
   button wrapped onto a line of its own. Measured, after the first guess
   (the plugin's `width: 100% !important` on the field) changed nothing. */
.nl-form .frm_forms,
.nl-form .frm-show-form,
.nl-form .frm_form_fields,
.nl-form fieldset {
	width: 100%;
}

/* The twelve-column grid becomes the row. */
.nl-form .frm_form_fields .frm_fields_container {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	/* the top, not the centre: a field that grows its message under it keeps
	   the button level with the field instead of dropping it (13.5) */
	align-items: flex-start;
	column-gap: 12px;
}

/* `width: 100% !important` is the plugin's, on `.frm_full`, and it is right in
   the plugin's twelve-column grid: a full-width field fills its twelve tracks.
   In this row there is no grid, and a field at a hundred per cent puts the
   button on a line of its own. Undone with the only weapon that beats an
   `!important`, which is why this is the second and last one in the file. */
.nl-form div.frm_form_field {
	flex: 1 1 220px;
	min-width: 0;
	width: auto !important;
	margin-bottom: 0;
}

/* The label is hidden from the eye and not from a screen reader.
   Formidable's own "no label" position is `display:none`, which would leave
   the input with no accessible name at all -- the placeholder is not one. So
   the label stays in the DOM, associated by `for`, and is clipped. */
.nl-form .frm_form_field .frm_primary_label {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset( 50% );
	white-space: nowrap;
}

.nl-form .frm_submit {
	flex: none;
	margin-top: 0;
}
/* A one-line Form block keeps the footer's measure, 480 at most, where the
   newsletter closer keeps base.css's 520 (13.2d). */
.form-line .nl-form {
	max-width: 480px;
}

/* On a phone the button runs the width of the row, which base.css already says
   -- `.nl-form .btn{width:100%}` at this breakpoint. It had no effect, because
   the button's width is a share of the wrapper Formidable puts around it and
   that wrapper was sized to its contents. The wrapper takes the row instead. */
@media (max-width: 640px) {
	.nl-form .frm_submit {
		flex: 1 1 100%;
	}
}

/* And the same in a column too narrow for the field and its button side by
   side, whatever the screen (14.7): base.css asks the one-line form its own
   width for the button, and the button's wrapper has to take the row for it. */
@container (max-width: 420px) {
	.nl-form .frm_submit {
		flex: 1 1 100%;
	}
}

/* The success message replaces the form, so on the ink band it is a light
   panel in the middle of a dark one. That is the right way round -- it is the
   one thing on the row somebody needs to see -- but it wants the row's width
   rather than the column's. */
.nl-form .frm_message,
.nl-form .frm_success_style {
	max-width: 100%;
	padding: 14px 18px;
	font-size: 0.96rem;
}
