/* ============================================================
   FORM — site forms (site/src/components/Form.astro, docs/adr/0006-site-forms.md)
   Requires: tokens.css, page.css (--ink, .visually-hidden), components/button.css
   A field and the submit button share one height (--form-field-h) and the radius of controls (12, radii by role), so a
   field and the button beside it read as one row. The label floats inside the field (see «Field box» below). Text in fields is 16 — smaller makes iOS Safari zoom the page on focus.
   Fill follows the theme like a .card: Surface on light pages, Background/Grey on dark; on a card it steps once more
   (white on a Surface card, CTA Grey on a grey card), as a control on a card does elsewhere.
   States without JavaScript: the Worker redirects back to #form-<id>-sent / #form-<id>-failed, and :target shows them.
   ============================================================ */

/* the field height, shared with the form window (its close is as tall as the window's button) */
:is(.form-block, .form-window) {
  /* Field height from its parts: the small label and the value under it are one pair, centred by
     ink — measured 17.6 from the top edge to the label's caps and 17.6 from the value's baseline to the bottom edge —
     12 above the label (--form-pad, 8 + 4), the label line, 4, the value line, 12 below, the frame. The submit button
     takes the same height. */
  --form-pad: calc(var(--space-xs) + var(--space-xxs));
  --form-label-lh: calc(var(--text-eyebrow-size) * 1.2);
  --form-label-gap: var(--space-xxs); /* between the small label and the value (without it they touch) */
  --form-field-h: calc(var(--form-pad) * 2 + var(--form-label-lh) + var(--form-label-gap) + var(--text-btn-xs-size) * 1.2 + var(--border-thin) * 2);
}
.form-block {
  --form-fill: var(--color-surface);
  --form-text: var(--color-text-inverted);
  --form-hint: var(--color-text-grey-inverted);
  --form-focus: var(--color-accent-indigo);
  /* Errors (frame and message) are orange: Accent/Orange Deep on light pages, Accent/Orange on
     dark. On light the message reads 3.0:1 on white — under WCAG AA, chosen knowingly; on dark orange gives 7.3:1. */
  --form-error: var(--color-accent-orange-deep);
  /* the system look (.form-block--ds, below): the thank-you's panel, its grey lines, its link, the text on a chosen chip */
  --form-panel: var(--color-surface);
  --form-panel-hint: var(--color-text-grey-inverted);
  --form-link: var(--color-accent-indigo); /* Accent/Blue reads 3.7–4.2:1 on light fills — under AA */
  --form-on-text: var(--color-text);
  --motion-dur: var(--duration-hover);
  --motion-ease: var(--ease-hover);
  max-width: 100%;
}
.theme-dark .form-block {
  --form-fill: var(--color-bg-grey);
  --form-text: var(--color-text);
  --form-hint: var(--color-text-grey);
  --form-error: var(--color-accent-orange);
  --form-panel: var(--color-bg-grey);
  --form-panel-hint: var(--color-text-grey-on-grey); /* Text/Grey reads 4.50 on Background/Grey — on the edge */
  --form-link: var(--color-accent-light-blue); /* Accent/Blue and Indigo read 1.8–2.5:1 on dark fills */
  --form-on-text: var(--color-text-inverted);
}
/* A light surface inside a dark page (e.g. the white modal card of a guide page): the nearest theme wins. */
.theme-dark .theme-light .form-block {
  --form-fill: var(--color-surface);
  --form-text: var(--color-text-inverted);
  --form-hint: var(--color-text-grey-inverted);
  --form-error: var(--color-accent-orange-deep);
  --form-panel: var(--color-surface);
  --form-panel-hint: var(--color-text-grey-inverted);
  --form-link: var(--color-accent-indigo);
  --form-on-text: var(--color-text);
}
/* on a filled surface — a card or a whole panel (the /experts form block) — the fields step off the fill */
.theme-light :is(.card, .panel) .form-block { --form-fill: var(--color-bg-white); --form-panel: var(--color-bg-white); }
.theme-dark :is(.card, .panel) .form-block { --form-fill: var(--color-bg-cta-grey); --form-hint: var(--color-text-grey-on-grey); --form-panel: var(--color-bg-grey-hover); }

/* Spacing by belonging: heading → its form 24; field → field 16; the button closes the fields
   group, 24 above it; in a thank-you or «not sent» the text sits under its heading at 8, the button 24 below the text.
   Default margins are dropped: a form also stands outside .section (in a modal), where page.css does not reset them. */
.form-block :where(h2, h3, p) { margin: 0; }
/* Headings of a form balance their lines, as page headings do (layout-rules): no «to» left at the end of a line.
   Phones: no single word on the last line instead (text-wrap: pretty). */
.form__heading { text-wrap: balance; }
@media (max-width: 47.9375rem) { .form__heading, .form__done p, .form__failed p { text-wrap: pretty; } }
/* centred state headings balance on phones too — centred, a balanced pair reads better than one long line + a word */
.form__done .form__heading, .form__failed .form__heading { text-wrap: balance; }
.form__main { display: grid; gap: var(--space); align-content: start; }
.form { display: grid; gap: var(--space-sm); margin: 0; }
.form__fields { display: grid; gap: var(--space-sm); }
.form--stacked .form__submit { margin-top: var(--space-xs); }
.form__field { display: grid; gap: var(--space-xs); min-width: 0; }
.form__optional { color: inherit; }

/* Field box: the control and its floating label. Empty and not focused — the label sits inside in the text size (16),
   grey. Focused or filled — it moves to the top and shrinks to 12.8 (--text-eyebrow-size), and the value takes the
   label's place in the same size. The room for the small label is the control's top padding. */
.form__box { position: relative; }
.form__control {
  box-sizing: border-box;
  width: 100%;
  min-height: var(--form-field-h);
  padding: calc(var(--form-pad) + var(--form-label-lh) + var(--form-label-gap)) var(--space-sm) var(--form-pad);
  border: var(--border-thin) solid transparent;
  border-radius: var(--radius-md);
  background: var(--form-fill);
  color: var(--form-text);
  font-family: var(--font); font-weight: 500; font-size: var(--text-btn-xs-size); line-height: 1.2;
  transition: border-color var(--motion-dur) var(--motion-ease);
}
/* The hint (e.g. «e.g. john.smith@company.com») appears only while the field is focused and empty, under the small label. */
.form__control::placeholder { color: var(--form-hint); opacity: 1; }
.form__control:not(:focus)::placeholder { color: transparent; }
.form__control:focus { outline: none; }
.form__control:focus-visible, .form__control:focus, .form__field.is-focus .form__control { border-color: var(--form-focus); } /* .is-focus: the review page's still of focus */
.form__field.is-invalid .form__control { border-color: var(--form-error); }
/* Browser autofill keeps our fill and text colour instead of its own yellow. */
.form__control:-webkit-autofill { -webkit-box-shadow: 0 0 0 100vmax var(--form-fill) inset; -webkit-text-fill-color: var(--form-text); }

.form__label {
  position: absolute;
  left: calc(var(--space-sm) + var(--border-thin));
  right: var(--space-md);
  top: 50%;
  transform: translateY(-50%);
  color: var(--form-hint);
  font-family: var(--font); font-weight: 500; font-size: var(--text-btn-xs-size); line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  transition: top var(--motion-dur) var(--motion-ease), transform var(--motion-dur) var(--motion-ease), font-size var(--motion-dur) var(--motion-ease);
}
.form__box:focus-within .form__label,
.form__field.is-focus .form__label,
input.form__control:not(:placeholder-shown) + .form__label,
.form__control:-webkit-autofill + .form__label,
.form__select:has(option:checked:not([value=""])) .form__label {
  top: calc(var(--form-pad) + var(--border-thin));
  transform: none;
  font-size: var(--text-eyebrow-size);
}
@media (prefers-reduced-motion: reduce) { .form__label { transition: none; } }

/* List: the browser's own arrow is replaced by Lucide's chevron-down in the text colour (icons/chevron-down.svg, as the
   close and the check — line 2, round ends; the border-drawn one looked off).
   Empty and not focused, «Choose…» is hidden behind the label; on focus it shows under the small label. */
.form__select .form__control { appearance: none; padding-right: calc(var(--space-sm) + var(--space) + var(--space-xs)); cursor: pointer; } /* the text stops 8 before the chevron */
.form__select:has(option[value=""]:checked) .form__control { color: var(--form-hint); }
.form__select:not(:focus-within):has(option[value=""]:checked) .form__control { color: transparent; }
.form__field.is-focus .form__select .form__control { color: var(--form-hint); }
.form__select option { color: initial; }
.form__select::after {
  content: "";
  position: absolute;
  top: 50%;
  right: var(--space-sm);
  width: var(--space); height: var(--space); /* the icon at its own 24 grid, as the close and the check */
  background: var(--form-text);
  mask: url("../icons/chevron-down.svg") center / contain no-repeat;
  transform: translateY(-50%);
  pointer-events: none;
}

/* «Other» in a list shows its text field — :has() works without JavaScript. */
.form__other { display: none; }
.form__field:has(option[value="Other"]:checked) .form__other { display: block; }

/* Chips (several answers, e.g. the formats on /experts): the question above them in the fields' text, the chips in the
   field fill and size of an XS control; a ticked chip takes Primary with dark text. The tick box inside covers the chip,
   so the whole chip is the touch area and the keyboard reaches each. «Other» ticked shows its text field (:has, no JS). */
.form__question { display: grid; }
.form__question > * { grid-area: 1 / 1; }
.form__legend { color: var(--form-text); font-family: var(--font); font-weight: 500; font-size: var(--text-btn-xs-size); line-height: 1.2; }
.form__field--choices .form__error { position: static; }
.form__field--choices.is-invalid .form__legend { opacity: 0; }
.form__chips { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.form__chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: var(--space-xs) var(--space-sm);
  border: var(--border-thin) solid transparent;
  border-radius: var(--radius-md); /* controls 12 */
  background: var(--form-fill);
  color: var(--form-text);
  font-family: var(--font); font-weight: 500; font-size: var(--text-btn-xs-size); line-height: 1.2;
  cursor: pointer;
  transition: background-color var(--motion-dur) var(--motion-ease), border-color var(--motion-dur) var(--motion-ease);
}
.form__chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
@media (hover: hover) { .form__chip:hover { border-color: var(--form-hint); } }
.form__chip:has(input:focus-visible) { border-color: var(--form-focus); }
.form__chip:has(input:checked) { background: var(--color-primary); color: var(--color-text-inverted); }
.form__field--choices.is-invalid .form__chip { border-color: var(--form-error); }
.form__field--choices:has(input[value="Other"]:checked) .form__other { display: block; }

/* Tick box: a box of the field fill, ticked — Primary with a dark check; the sentence beside it in the fields' text. */
.form__check { display: flex; align-items: flex-start; gap: var(--space-xs); color: var(--form-text); font-family: var(--font); font-size: var(--text-btn-xs-size); line-height: 1.3; cursor: pointer; }
.form__tick {
  flex: none;
  width: 1.3em; height: 1.3em; /* one line of the sentence tall, so it sits on the first line */
  margin: 0;
  appearance: none;
  border: var(--border-thin) solid var(--form-hint);
  border-radius: var(--radius-xs);
  background: var(--form-fill);
  cursor: pointer;
  transition: background-color var(--motion-dur) var(--motion-ease), border-color var(--motion-dur) var(--motion-ease);
}
.form__tick:checked {
  border-color: var(--color-primary);
  background: var(--color-primary) url("../icons/check.svg") center / 80% no-repeat;
}
.form__tick:focus-visible { outline: var(--border-thin) solid var(--form-focus); outline-offset: var(--border-thin); }
.form__field--checkbox.is-invalid .form__tick { border-color: var(--form-error); }

/* Error: takes the small label's place inside its field, so the field never grows. The text names
   the field («Enter your work email»), because the label is hidden while it shows; screen readers get it through
   aria-describedby. It goes as soon as the field is fixed and the label comes back. */
.form__error {
  position: absolute;
  left: calc(var(--space-sm) + var(--border-thin));
  right: var(--space-md);
  top: calc(var(--form-pad) + var(--border-thin));
  margin: 0;
  color: var(--form-error);
  font-family: var(--font); font-weight: 500; font-size: var(--text-eyebrow-size); line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.form__error:empty { display: none; }
.form__field.is-invalid .form__label { opacity: 0; }

/* Stacked forms: the button is as wide as the fields. */
.form__submit { --btn-h: var(--form-field-h); justify-self: stretch; width: 100%; }
.form__submit[aria-busy="true"] { opacity: 0.6; cursor: progress; }

/* Inline: one field and the button in a row (blog subscribe); on phones the button goes under the field, full width. */
.form--inline .form__fields { grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: var(--space-xs); }
.form--inline .form__submit { width: auto; }
@media (max-width: 47.9375rem) {
  .form--inline .form__fields { grid-template-columns: 1fr; }
  .form--inline .form__submit { width: 100%; }
}

/* Spam trap: never shown; bots that fill every field in the HTML still fill it. */
.form__trap { display: none; }

/* Sent and not sent take the form's own place: the form, the thank-you and «not sent» share one grid cell, so the
   block keeps the form's height in every state (no height jump). The hidden ones stay in the
   cell (visibility, not display) — the tallest sets the height, which is the form. Shown by form.js (.is-sent /
   .is-failed) or, without it, by #form-<id>-sent / -failed (:target) after the Worker's redirect. */
.form-block { display: grid; }
.form-block > .form__main, .form__done, .form__failed { grid-area: 1 / 1; }
.form__done, .form__failed {
  visibility: hidden;
  opacity: 0;
  align-self: center;
  display: grid;
  gap: var(--space-xs);
  justify-items: center; /* the thank-you and «not sent» are centred both ways in the form's place */
  text-align: center;
} /* the form and its states swap at once, no fade */
.form__done .btn, .form__failed .btn { margin-top: var(--space-sm); }
.form__failed a:not(.btn) { color: inherit; }
.form__done:target, .form-block.is-sent .form__done,
.form__failed:target, .form-block.is-failed .form__failed { visibility: visible; opacity: 1; }
.form-block:has(.form__done:target, .form__failed:target) .form__main, .form-block.is-sent .form__main, .form-block.is-failed .form__main { visibility: hidden; }
.form-block:has(.form__done:target, .form__failed:target) .form__main > *, .form-block.is-sent .form__main > *, .form-block.is-failed .form__main > * { opacity: 0; }
.form__done:focus, .form__failed:focus { outline: none; }
/* Inline (subscribe): «not sent» fits the one row — message and «Try again» side by side, no title. */
.form-block--inline .form__failed { grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-sm); justify-items: start; text-align: left; }
.form-block--inline .form__done { justify-items: start; text-align: left; }
.form-block--inline .form__failed .form__heading { display: none; }
.form-block--inline .form__failed .btn { margin-top: 0; }

/* ============================================================
   The system look (.form-block--ds) — every form takes it unless its page keeps its own (the blog's forms:
   Form look="custom"; they inherit the fields only). Tuned on /experts, then made the default
   for the site's forms. Colours follow the theme through the --form-* variables above.
   ============================================================ */
/* the question over the chips in Paragraph LG, set apart from the field above it and close to its chips; on the
   question's cell, so its error, which takes the same place, sits where the question was */
.form-block--ds .form__question { padding-top: var(--space-sm); padding-bottom: var(--space-xs); }
.form-block--ds .form__legend { font-size: var(--text-para-lg-size); line-height: var(--text-para-lg-lh); letter-spacing: var(--text-para-lg-ls); font-weight: 600; }
/* chips: outlined as the site's .chip (patterns.css), Paragraph SM; the chosen one in the text colour — the yellow is
   the button's */
.form-block--ds .form__chip {
  padding: var(--chip-pad-y, var(--space-sm)) var(--chip-pad-x, var(--space)); /* the chip's size (patterns.css): M, S on phones */
  border-color: currentColor;
  background: none;
  font-size: var(--text-para-sm-size); line-height: 1; letter-spacing: var(--text-para-sm-ls); font-weight: 600;
}
.form-block--ds .form__chip:has(input:checked) { background: var(--form-text); border-color: var(--form-text); color: var(--form-on-text); }
.form-block--ds .form__chip:has(input:focus-visible) { outline: var(--border-thick) solid var(--form-focus); outline-offset: var(--border-thin); }
/* the tick box: the fields' fill with the chips' outline, ticked — Primary with the check in ink, no outline; the
   sentence in Paragraph SM */
.form-block--ds .form__check { align-items: center; font-size: var(--text-para-sm-size); line-height: var(--text-para-sm-lh); letter-spacing: var(--text-para-sm-ls); font-weight: 600; }
.form-block--ds .form__tick { width: var(--space); height: var(--space); color: inherit; border-color: currentColor; border-radius: var(--radius-sm); }
.form-block--ds .form__tick:checked { border-color: var(--color-primary); }
.form-block--ds .form__tick:focus-visible { outline: var(--border-thick) solid var(--form-focus); outline-offset: var(--border-thin); }
/* a required tick box left empty: the message under its sentence, small, in the error colour */
/* its line is kept from the start, so the block does not grow when the message comes; a tick box that is not required
   never shows one and keeps no line */
.form-block--ds .form__error--check { position: static; min-height: 1.2em; padding-left: calc(var(--space) + var(--space-xs)); color: var(--form-error); font-size: var(--text-eyebrow-size); line-height: 1.2; white-space: normal; }
.form-block--ds .form__field--checkbox:not([data-required]) .form__error--check { display: none; }
/* hover on a chip: its fill a step lighter, the outline stays the text colour — as the site's chip buttons; a chosen
   chip keeps its fill */
@media (hover: hover) {
  .form-block--ds .form__chip:hover { border-color: currentColor; background: color-mix(in srgb, var(--form-text) 8%, transparent); }
  .form-block--ds .form__chip:has(input:checked):hover { background: var(--form-text); }
}
/* sending: the button keeps its label and three dots pulse in it (the thank-you's bubble, in small) */
.form-block--ds .form__submit[aria-busy="true"] { opacity: 1; position: relative; }
.form-block--ds .form__submit[aria-busy="true"] .form__submit-label { visibility: hidden; } /* keeps its width, the dots take its place */
.form-block--ds .form__submit[aria-busy="true"]::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: calc(var(--space-xs) * 6); height: var(--space-xs); /* three dots, each in a 16 cell */
  background: radial-gradient(circle closest-side, var(--form-dots, var(--color-text-inverted)) 90%, transparent) 0 50% / calc(var(--space-xs) * 2) var(--space-xs) repeat-x;
  animation: form-sending 1.2s ease-in-out infinite;
}
.form-block--ds .btn-dark.form__submit { --form-dots: var(--color-text); }
@keyframes form-sending { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .form-block--ds .form__submit[aria-busy="true"]::after { animation: none; } }
/* the thank-you and «not sent»: the heading in H3, the first line in Paragraph LG, further lines in SM grey, no full
   stops at line ends, the link in the theme's readable blue. They take the form's place and keep its height, so a
   window or a card does not jump. On the wrapper's own fill (a window, a card holding only the form —
   a panel inside them would read as a stray frame); a panel only where the form sits beside other content
   (the form card, below). */
.form-block--ds :is(.form__done, .form__failed) { color: var(--form-text); gap: 0; container-type: inline-size; }
/* spacing by belonging: heading → its text 16, text line → text line 16, the text → the button 32 */
.form-block--ds :is(.form__done, .form__failed) .form__heading + p { margin-top: var(--space-sm); }
.form-block--ds :is(.form__done, .form__failed) .btn { margin-top: var(--space-md); }
.form-block--ds :is(.form__done, .form__failed) .form__heading { font-size: var(--text-h3-size); line-height: var(--text-h3-lh); letter-spacing: var(--text-h3-ls); }
.form-block--ds :is(.form__done, .form__failed) p:not(.form__heading) { max-width: var(--measure-lead); text-wrap: balance; }
/* the state's text colours outweigh a page's grey-on-card rule (.text-grey on a .card, e.g. /experts) */
.form-block--ds :is(.form__done, .form__failed) p.text-grey:not(.form__heading) { color: var(--form-text); }
.form-block--ds :is(.form__done, .form__failed) .form__heading + p { font-size: var(--text-para-lg-size); line-height: var(--text-para-lg-lh); letter-spacing: var(--text-para-lg-ls); }
.form-block--ds .form__done .form__heading + p.text-grey ~ p.text-grey { margin-top: var(--space-sm); color: var(--form-panel-hint); font-size: var(--text-para-sm-size); line-height: var(--text-para-sm-lh); letter-spacing: var(--text-para-sm-ls); }
.form-block--ds .form__failed-help { display: block; margin-top: var(--space-sm); font-size: var(--text-para-sm-size); line-height: var(--text-para-sm-lh); letter-spacing: var(--text-para-sm-ls); color: var(--form-panel-hint); }
.form-block--ds .form__stop { display: none; }
/* a narrow form (its state under 28rem wide — a window, a phone): the first line in Body, not LG, so it does not fill
   the width edge to edge. No Paragraph M in the scale: Body (14.4) is the nearest, the colour
   (text, not grey) keeps it apart from the lines under it. By the state's own width, so any wrapper takes it. */
@container (max-width: 28rem) {
  .form-block--ds :is(.form__done, .form__failed) .form__heading + p { font-size: var(--text-body-size); line-height: var(--text-body-lh); letter-spacing: var(--text-body-ls); }
}
.form-block--ds .form__failed a:not(.btn) { color: var(--form-link); }
/* the thank-you with a picture — a template any form takes (from /experts): the page puts its
   picture into the slot «success-art» with class form__art (an <img>, or an inline SVG when it moves); the text stands
   at the top, the picture at the bottom of the form's place, about two thirds of the panel wide (/experts' mock: 391 of
   the 480 inside the panel's padding). A page may set another width on its own class. */
.form-block--ds .form__done:has(.form__art) { display: flex; flex-direction: column; align-items: center; }
.form-block--ds .form__art { display: block; width: 81.5%; margin-top: auto; }
.form-block--ds .form__art :is(svg, img) { display: block; width: 100%; height: auto; }
@media (max-width: 47.9375rem) {
  .form-block--ds :is(.form__done, .form__failed) p:not(.form__heading) { text-wrap: pretty; }
  .form-block--ds .form__art { margin-top: var(--space-md); }
}

/* ============================================================
   Form split (site/src/components/FormSplit.astro) — a form beside its intro. Wide screens: the intro on the left (its
   heading at the top, the aside — a note — at the bottom, on the button's line), the form on the right filling its
   column, its button at the bottom with at least 64 over it (48 + the fields' 16). In a .card, or bare (card={false},
   e.g. /demo). Tablets and phones (under 992, the site's tablet line): the intro, then the form; the aside leaves the
   card and stands as its own block under it; the states take their content's height.
   ============================================================ */
.form-split__intro { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-lg); }
.form-split__lead { display: grid; gap: var(--space); align-content: start; }
.form-split__aside { display: grid; gap: var(--space-xs); }
.form-split__aside--note { max-width: var(--measure-lead); } /* a title and a line of text; a slotted aside (a quote card) takes the column */
.form-split__aside--own { display: none; }
.theme-dark .form-split__aside .text-grey { color: var(--color-text-grey-on-grey); } /* the aside's grey on a grey card: Text/Grey reads 4.50 there; only the aside — the states set their own colours */
.form-split__form { display: flex; }
.form-split__form .form-block { flex: 1; }
.form-split__form :is(.form__main, .form, .form__fields) { display: flex; flex-direction: column; flex: 1; }
.form-split__form :is(.form, .form__fields) { gap: var(--space-sm); }
.form-split__form .form__submit { margin-top: auto; }
.form-split__form .form__field:has(+ .form__submit) { margin-bottom: var(--space-lg); }
/* the states on a panel over the form's whole place, a step off the card or page around it */
.form-split__form .form-block--ds :is(.form__done, .form__failed) { align-self: stretch; align-content: center; padding: var(--space-lg); border-radius: var(--radius-md); background: var(--form-panel); }
@media (max-width: 61.9375rem) {
  .form-split__grid { row-gap: var(--block-gap); }
  .form-split__intro { display: contents; }
  .form-split__grid > *, .form-split__intro > * { grid-column: 1 / -1; }
  .form-split__intro .form-split__aside { display: none; }
  .form-split__aside--own { display: grid; margin-top: var(--grid-gap); max-width: none; }
  .form-split__aside--own.form-split__aside--note > p { max-width: var(--measure-lead); } /* the card spans the width, its text keeps a reading line */
  .form-split__form .form__field:has(+ .form__submit) { margin-bottom: 0; }
  /* the states take their content's height (48 above and below, a card's 24 at the sides, so the text keeps its lines);
     the form and the state not shown leave the cell */
  .form-split__form .form-block--ds:is(.is-sent, .is-failed, :has(.form__done:target, .form__failed:target)) .form__main { display: none; }
  .form-split__form .form-block--ds:not(.is-sent, :has(.form__done:target)) .form__done,
  .form-split__form .form-block--ds:not(.is-failed, :has(.form__failed:target)) .form__failed { display: none; }
  .form-split__form .form-block--ds :is(.form__done, .form__failed) { align-self: start; }
}
/* phones: a card's 24 at the panel's sides, so the text keeps its lines; 48 above and below stays */
@media (max-width: 47.9375rem) { .form-split__form .form-block--ds :is(.form__done, .form__failed) { padding-inline: var(--pad-card-fluid); } }

/* ============================================================
   Form card (site/src/components/FormCard.astro) — a form in its own card inside a column of text (/opt-out): the card
   takes the text column's width; the form keeps its own heading (from Sanity); the states lie on the card's fill and
   keep the form's height at every width.
   ============================================================ */
.form-card { width: 100%; }

/* ============================================================
   Form window (site/src/components/FormWindow.astro) — a form in a window over the page (the AdQuantum guide). The
   window itself — the dimmed page, white or grey, the corner, the close, opening — is the site's window (window.css);
   here the form's: narrow (window--narrow), as tall as the form, the fields in CTA Grey in a grey window, the form's heading clear of
   the close; the states lie on the window's fill and keep the form's height; choosing «Other» grows the window by its
   field. Phones: the window's sheet (window.css).
   ============================================================ */
.form-window {
  z-index: 1101; position: fixed; inset: 0; margin: auto; height: fit-content;
  max-height: calc(100dvh - var(--space-lg)); overflow: auto;
}
.form-window.theme-dark .form-block { --form-fill: var(--color-bg-cta-grey); --form-hint: var(--color-text-grey-on-grey); --form-panel: var(--color-bg-grey); }
/* the close as tall as an XS button; the form's heading is the window's top row, centred on
   the close and clear of it (window.css, .window__clear-close) */
.window.form-window { --window-close: var(--btn-h-xs); } /* an XS button's height — the form's button made the heading row too tall; .window too: window.css loads after this file */
.form-window .form__main .form__heading { display: flex; align-items: center; min-height: var(--window-close); margin-top: calc(var(--space-xs) - var(--window-pad)); padding-right: calc(var(--window-close) + 2 * var(--space-xs) - var(--window-pad)); }
@media (max-width: 47.9375rem) { .window.form-window { inset: auto 0 0 0; margin: 0; max-height: 90dvh; } } /* the sheet (window.css); .window too: this file loads first */
