/* ============================================================================
   RESB forms.

   Loaded after abridge.css (see `stylesheets` in config.toml), so these win.
   Kept separate from resb.css (colour), resb-layout.css (measure) and
   resb-fonts.css (typography).

   Forms post natively to our own /api/contact Worker. Abridge styles form
   controls but gives them `border: 0` and a Paper background, which is nearly
   invisible against the Document page colour; these rules give the fields a
   visible edge.
   ============================================================================ */

.resb-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  margin: 1.5rem 0;
  width: 60%;
}

/* 60% of a phone screen leaves the fields unusably narrow. */
@media (max-width: 40rem) {
  .resb-form {
    width: 100%;
  }
}

/* Markdown-adjacent: each field is a <p>, so the theme's paragraph margins
   would fight the flex gap. */
.resb-form .resb-field,
.resb-form p {
  margin: 0;
}

.resb-form label {
  font-weight: 600;
  margin-bottom: 0.3rem;
}

.resb-optional {
  font-weight: 400;
  color: var(--color-slate);
  font-size: 0.875em;
}

.resb-form input[type="text"],
.resb-form input[type="email"],
.resb-form input[type="tel"],
.resb-form input[type="url"],
.resb-form select,
.resb-form textarea {
  width: 100%;
  padding: 0.5rem 0.6rem;
  background: var(--color-paper);
  border: 1px solid var(--color-slate);
  border-radius: 0.25rem;
  color: var(--color-record-ink);
}

/* Select chevron, ported from Bootstrap 5.2's `.form-select` (MIT). Their
   "custom select" is not a component or a script - it is appearance:none plus
   this SVG as a background-image, so there is nothing to install. Vendoring
   the framework to obtain one rule would mean a second full stylesheet
   colliding with abridge's.

   Kept from Bootstrap verbatim: the path, stroke-width 2, round caps and
   joins, the 16x12 background-size, and the right-padding-x centre position.
   Changed for this site: the stroke is Slate rather than their #343a40, and
   the offsets follow our 0.6rem padding rather than their 0.75rem.

   -moz-padding-start compensates for the extra inline start padding Firefox
   adds to a select; the -3px is Bootstrap's figure.

   Slate is written out as #5c6570 because a data: URI is opaque to CSS and
   cannot read a custom property - same compromise as the checkbox tick. */
.resb-form select {
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.1rem;
  -moz-padding-start: calc(0.6rem - 3px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%235c6570' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 16px 12px;
}

.resb-form input:focus-visible,
.resb-form select:focus-visible,
.resb-form textarea:focus-visible {
  outline: 2px solid var(--color-board-blue);
  outline-offset: 1px;
  border-color: var(--color-board-blue);
}

/* Sections of a long form - used on /apply/, the only form here big enough to
   need dividing. A fieldset rather than a heading, so the grouping is carried
   by the markup: a screen reader announces the legend with every field inside
   it, which is the whole point of asking about an organization and a person on
   one page.

   Drawn as the box a fieldset is meant to be. The legend keeps its native
   placement in the top border, which every engine notches around it - the one
   piece of default form chrome on this site worth keeping, because it labels
   the enclosure instead of merely sitting above it.

   Board Blue Pale for the rule, not Slate: the inputs inside are already
   1px Slate, and a 2px rule in the same colour would make the box compete with
   its own contents instead of containing them. Pale can carry the extra weight
   precisely because it is quiet. No fill, for the same reason - the fields are
   Paper and need to stay the lightest thing in the frame. */
.resb-form .resb-section {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  margin: 0;
  padding: 1.1rem 1.25rem 1.3rem;
  border: 2px solid var(--color-board-blue-pale);
  border-radius: 0.25rem;
}

/* Indented from the corner so it clears the radius, and padded so the notch
   opens cleanly on both sides of the text. Board Blue: the palette's mark
   colour, which is what a section label is.

   Set small and uppercase, so it reads as a label on the frame rather than as
   a heading inside it. The 0.08em tracking is not optional at this size:
   uppercase loses the ascender and descender shapes that carry word
   recognition, and needs the extra letter separation to stay legible. Same
   figure as the record card's one uppercase element in resb-record.css. */
.resb-form .resb-section > legend {
  margin-left: 0.35rem;
  padding: 0 0.45rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--color-board-blue);
}

/* align-items: flex-start, not center - the declaration's label runs to
   several lines, and a centred box would float beside the middle of them. */
.resb-form .resb-check {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 0.6rem;
}

.resb-form .resb-check label {
  font-weight: 400;
  margin: 0;
}

/* The boxes themselves are drawn further down, by the same rules that draw
   ALTCHA's - see "Custom checkbox". */

/* Triad Rose, the same object as a.resb-button in resb.css. Submitting is the
   call to action on a form page, so it takes Rose. The ALTCHA checkbox below
   stays Board Blue: it is a control state rather than something to act on. */
.resb-form button[type="submit"] {
  align-self: flex-start;
  padding: 0.55rem 1.4rem;
  background: var(--color-triad-rose);
  color: var(--color-paper);
  border: 2px solid var(--color-triad-rose);
  border-radius: 0.25rem;
  font-weight: 600;
  cursor: pointer;
}

.resb-form button[type="submit"]:hover,
.resb-form button[type="submit"]:focus-visible {
  background: var(--color-triad-rose-deep);
  border-color: var(--color-triad-rose-deep);
  opacity: 1;                       /* abridge fades buttons to .75 on hover */
}

/* Pressed. Must follow :hover - same specificity, so source order decides. */
.resb-form button[type="submit"]:active {
  background: var(--color-triad-rose-press);
  border-color: var(--color-triad-rose-press);
  opacity: 1;
}

/* ALTCHA widget. Self-hosted from /js/altcha.min.js - no third-party request,
   no cookies, no tracking, so the CSP can stay 'self'.

   The widget injects its stylesheet into document.head rather than a shadow
   root, so its internals are reachable with ordinary CSS. Its own structure is:

     .altcha            flex column, bordered box, max-width 260px
       .altcha-main     flex row - .altcha-checkbox + .altcha-label + a link
                        wrapping the ALTCHA roundel
       .altcha-error    validation message
       .altcha-footer   "Protected by ALTCHA"

   Left alone that stacks into three rows and uses the raw browser checkbox,
   which sits oddly beside the rest of the form.

   We keep two rows: the box holds only the checkbox line, and the ALTCHA
   attribution sits beneath it, unboxed. The bordered box then reads as one
   more form control alongside the inputs above it, and its width no longer
   swings by ~90px as the label goes from "I'm not a robot" to "Verified". */

/* Selectors are scoped to .resb-form and target ALTCHA's own class names
   directly, rather than hanging off the .resb-captcha class we set on the
   host element - that anchor proved unreliable once the widget renders. Two
   class levels (0,2,0) also outrank the widget's own single-class rules,
   which matters because it injects its stylesheet at runtime, after ours. */

.resb-form altcha-widget {
  display: block;
  --altcha-color-border: var(--color-slate);
  --altcha-color-base: var(--color-paper);
  --altcha-color-text: var(--color-record-ink);
  --altcha-border-radius: 0.25rem;
}

/* The outer element carries no chrome of its own - it is just the stack that
   puts the attribution under the box. The border, radius and fill live on
   .altcha-main below, so the box wraps the checkbox line only.

   The border, background and radius are zeroed rather than simply omitted.
   The widget's own `.altcha` rule paints all three, and our earlier version of
   this block happened to override them by setting its own; moving them to
   .altcha-main let the stock ones back in, and the widget drew a full-width
   box around our box. Anything dropped from here has to be turned off, not
   left out.

   Full width rather than fit-content, so the box's percentage min-width below
   resolves against the form instead of against its own content. */
.resb-form .altcha {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: none;
  width: 100%;
  border: 0;
  border-radius: 0;
  background: none;
}

/* The checkbox must not shrink. In a nowrap row it is the only item without a
   min-content floor, so it collapses to a sliver while the text holds its
   width. */
.resb-form .altcha-checkbox {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
}

/* One line, and the bordered box. Set explicitly rather than through the
   --altcha-* custom properties, so it does not depend on the widget's own
   theming plumbing. */
.resb-form .altcha-main {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.6rem;
  width: fit-content;
  min-width: 50%;
  max-width: 100%;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--color-slate);
  border-radius: 0.25rem;
  background: var(--color-paper);
}

/* Same breakpoint the form itself widens at. Half of an already-narrow form
   is a stub, and fit-content would win there anyway once the label is wider
   than 50%, so take the whole width. */
@media (max-width: 40rem) {
  .resb-form .altcha-main {
    width: 100%;
  }
}

/* The widget puts its roundel in the checkbox line, in a bare <div> after the
   label - but only paints it once verified, so the row visibly gains a glyph
   mid-interaction. Drop it and let the footer's "ALTCHA" link carry the
   attribution. The wrapper goes too, or its flex gap leaves a hole. */
.resb-form .altcha-main > div:has(> .altcha-logo),
.resb-form .altcha-logo {
  display: none;
}

/* The form's own labels are 600 with a bottom margin; this one sits inline. */
.resb-form .altcha-label {
  flex-grow: 0;
  font-weight: 400;
  margin: 0;
  white-space: nowrap;
}

/* Second line, under the box and flush with its left edge. The widget's own
   rule is justify-content:end, which pushed it right when this sat inside the
   row; as a block below the box that would strand it under the label. */
.resb-form .altcha-footer {
  justify-content: flex-start;
  padding: 0.35rem 0 0;
  font-size: 0.7rem;
  white-space: nowrap;
}

/* Same left edge. No nowrap here - an error message is a sentence. */
.resb-form .altcha-error {
  padding: 0.35rem 0 0;
}

/* Custom checkbox. Board Blue, NOT the submit button's Rose - this is a
   control state rather than a call to action, and Rose is for CTAs only.
   appearance:none removes the platform control so the box can be drawn here;
   the tick is an inline SVG (data: is permitted by img-src in _headers).

   Shared with the .resb-check boxes on /apply/, so the two kinds of checkbox
   on that page are the same object. Extend these selector lists rather than
   copying the block. */
.resb-form .resb-check input,
.resb-form .altcha-checkbox input {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  min-width: 20px;
  margin: 0;
  padding: 0;
  border: 2px solid var(--color-slate);
  border-radius: 0.25rem;
  background-color: var(--color-paper);
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

/* Sits on the label's first line rather than its box top, for the multi-line
   labels in a .resb-check. After the base rule, which zeroes margin. */
.resb-form .resb-check input {
  margin-top: 0.15rem;
}

.resb-form .resb-check input:hover,
.resb-form .altcha-checkbox input:hover {
  border-color: var(--color-board-blue);
}

.resb-form .resb-check input:checked,
.resb-form .altcha-checkbox input:checked {
  background-color: var(--color-board-blue);
  border-color: var(--color-board-blue);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23FAFAFA' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.5 3.5L13 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 13px 13px;
}

.resb-form .resb-check input:focus-visible,
.resb-form .altcha-checkbox input:focus-visible {
  outline: 2px solid var(--color-board-blue);
  outline-offset: 2px;
}

/* While verifying, the widget swaps the box for a spinning circle: it adds
   .altcha-checkbox-verifying (opacity:0 on the input) and absolutely positions
   an animated .altcha-spinner SVG over the same 20px. Keep the box instead -
   only the label should change ("I'm not a robot" -> "Verifying..." ->
   "Verified").

   Both rules are (0,2,x) and so outrank the widget's own single-class ones.
   pointer-events:none is left alone: the box must stay inert mid-check. */
.resb-form .altcha-checkbox .altcha-spinner {
  display: none;
}

/* Pending - clicked, not yet cleared. The widget ties `checked` to the
   VERIFIED state alone, so without this the box would sit empty for the whole
   check and the click would read as not having registered.

   Three steps, each unambiguous at 20px: slate outline and empty -> blue
   outline, pale fill and a dash -> blue fill and a white tick. The dash is the
   usual indeterminate-checkbox idiom, which is exactly the meaning here.

   Board Blue is written out as #2e5a8c rather than taken from the token: a
   data: URI is an opaque string to CSS and cannot read a custom property. The
   tick above hard-codes Paper the same way. If the palette moves, both move. */
.resb-form .altcha-checkbox-verifying input {
  opacity: 1;
  border-color: var(--color-board-blue);
  background-color: var(--color-board-blue-pale);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%232e5a8c' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M4 8h8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 13px 13px;
}

@media (prefers-reduced-motion: reduce) {
  .resb-form .resb-check input,
  .resb-form .altcha-checkbox input {
    transition: none;
  }
}

/* Inline validation messages, written by /js/resb-forms.js. Firefox for
   Android blocks an invalid submit but shows nothing at all for it, so the
   messages are rendered here rather than left to the browser. See that file.

   --cr is the palette's error colour (#a3352f), not Triad Rose. Rose now
   carries buttons and inline links, so an error in Rose would be a third
   meaning for one colour on a page that already has both. The halo repeats
   --cr as a literal rgba because a custom property cannot carry the alpha. */
.field-error {
  display: block;
  margin-top: 0.35rem;
  color: var(--cr);
  font-size: 0.9rem;
}

/* Element-qualified so these outrank the field rules above, which are also two
   levels and would otherwise hold the border on source order. */
.resb-form input[aria-invalid="true"],
.resb-form select[aria-invalid="true"],
.resb-form textarea[aria-invalid="true"] {
  border-color: var(--cr);
  outline: 2px solid rgba(163, 53, 47, 0.25);
}

/* Spam honeypot. Bots fill every field they find in the DOM; people never see
   this one. Hidden with display:none rather than a visually-hidden pattern -
   a screen reader should not be asked to skip a decoy field. */
.resb-honeypot {
  display: none;
}
