/* =========================================================================
   Component — forms
   Every input has a <label>; errors are associated with aria-describedby.
   ========================================================================= */

.field {
  margin-bottom: 16px;
}

.field > label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--doc-ink);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: 9px 12px;
  border: 1px solid var(--sd-border);
  border-radius: var(--radius);
  background: var(--sd-surface);
  color: var(--sd-text);
  font: inherit;
  font-size: 14px;
}

.field textarea {
  min-height: calc(var(--control-h) * 2.5);
  resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--doc-ink-soft);
}

/* A field the role may read but not change (`readonly`, set from the WRITE scope
   — profile, app editor). It must not look like one that takes input: on the
   white of an editable field it promised a permission the page does not grant
   (U-1086). The sunk surface is the one `.form-message` already uses for
   "this is information, not a control". */
.field input[readonly],
.field textarea[readonly] {
  background: var(--sd-sunk);
  border-style: dashed;
  cursor: default;
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--sd-secondary);
  outline: 3px solid color-mix(in srgb, var(--sd-secondary) 45%, transparent);
  outline-offset: 0;
}

.field-hint {
  margin: 6px 0 0;
  font-size: 12.5px;
  color: var(--doc-ink-soft);
}

/* A hint that is one sentence about a whole card, not running text: the reading
   measure every <p> gets from base.css would break it at half the card (U-1130). */
.field-hint-wide {
  max-width: none;
}

/* And at the hint's own size (U-1167): as a card's direct child it is matched by
   `.card > p` (0,1,1), which sets 14 px and beat `.field-hint`'s 12.5 px (0,1,0)
   — before U-1130 as well. This selector is (0,2,0), and only this hint carries the
   class. */
.card > .field-hint-wide {
  font-size: 12.5px;
}

.field-error {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--sd-error);
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--sd-error);
}

/* A fixed prefix the control's value does not contain (`https://`, U-915). */
.field-affix {
  display: flex;
  align-items: stretch;
}

.field-prefix {
  display: flex;
  align-items: center;
  padding: 0 10px;
  border: 1px solid var(--sd-border);
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--sd-surface-alt);
  color: var(--sd-text-soft);
  font-size: 14px;
  white-space: nowrap;
}

.field-affix input {
  min-width: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* --- Search / filter bar: parameters go to the server -------------------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 20px;
}

.filter-bar .field {
  margin-bottom: 0;
  flex: 1 1 200px;
}

/* --- Form-level message (error summary, notice) -------------------------- */

/* --- THE NEUTRAL FORM MESSAGE IS A ROLE, AND U-507 GAVE IT ITS GROUND ------ *
 * U-725 left this open: *".form-message needs a role the token set does not
 * have"*. It does have one, and eleven callers had already found it — every
 * bare `.form-message` in this frontend carries `role="status"` and says some
 * version of *"you may only read here"* or *"this state does not allow that"*.
 * That is not an error, not a success and not a warning: it is **a note that
 * explains a state which is not a failure**, and `--sd-sunk` is exactly its
 * ground — a recess inside a surface (DESIGN_TOKENS §9.1).
 *
 * It was `--sd-surface-alt`, and that token INVERTS its role between the themes
 * (L-FE-44): measured, it is 1.10:1 BELOW the panel in light and 1.14:1 ABOVE it
 * in dark, so the same note read as "set back" in one theme and "raised" in the
 * other. `--sd-sunk` is 1.10:1 below in both.
 *
 * **In light nothing changes at all** — both tokens are `#F4F4F4` — which is
 * what a correct fix to a one-theme defect looks like, and the same shape
 * `badge.css` records for the same token. Ink is unaffected: `--sd-text`
 * measures 13.76:1 light and 12.82:1 dark on the new ground, up from 10.16:1.
 * -------------------------------------------------------------------------- */

.form-message {
  margin: 0 0 16px;
  padding: 11px 13px;
  font-size: 13.5px;
  border: 1px solid var(--sd-border);
  border-radius: var(--radius);
  background: var(--sd-sunk);
  color: var(--sd-text);
}

.form-message[hidden] {
  display: none;
}

.form-message-error {
  background: var(--sd-error-bg);
  border-color: var(--sd-error-bd);
}

.form-message-success {
  background: var(--sd-success-bg);
  border-color: var(--sd-success-bd);
}

/* Done, and something the reader must still act on: a partner decision whose
   notice to the company was not mailed (U-980). */
.form-message-warning {
  background: var(--sd-warning-bg);
  border-color: var(--sd-warning-bd);
}

/* --- A grid of fields, for a form with more than a handful ---------------- */

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0 20px;
}

/* --- Grouped sections ----------------------------------------------------- */

.form-section {
  margin: 0 0 24px;
  padding: 0;
  border: 0;
}

.form-section > legend {
  padding: 0;
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--doc-ink);
}

/* --- The error summary ---------------------------------------------------- */
/* A failed submit moves focus here, so it needs a visible ring of its own —
   `:focus-visible` in base.css does that, and the outline offset keeps it clear
   of the panel's border. What this file adds is the list of failed fields, each
   a link into its control, so the summary is a way in and not a report. */

.error-summary-title {
  margin: 0;
  font-weight: 600;
}

.error-summary-list {
  margin: 8px 0 0;
  padding-left: 20px;
  font-size: 13px;
}

.error-summary-list li + li {
  margin-top: 4px;
}

/* --- Consent checkboxes, and any other list of choices -------------------- */
/* Each consent names the document AND the version it is recorded against,
   because that is what the consent ledger stores and a person is entitled to
   see what they are agreeing to. The `choice-*` names share the rules: the
   portal's language control (U-808) is a list of radios with the same layout. */

.consent-list,
.choice-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.consent-option,
.choice-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13.5px;
  cursor: pointer;
}

.consent-check,
.choice-input {
  flex: 0 0 auto;
  margin-top: 3px;
  width: 18px;
  height: 18px;
}

.consent-version {
  display: block;
  font-size: 12px;
  color: var(--doc-ink-soft);
}

.consent-row .field-error {
  margin-left: 28px;
}

/* --- The honeypot --------------------------------------------------------- */
/* Off the page rather than `display: none`: it must stay a control a script
   fills, and only be out of a person's sight (`buildHoneypot`, U-1037). The
   compound selector outranks `.field`, whatever order the two are read in. */

.field.field-trap {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Compact inline forms (invite, upload) -------------------------------- */

.invite-form,
.upload-form {
  margin: 0 0 20px;
}

.invite-form .filter-bar .btn,
.upload-form .filter-bar .btn {
  flex: 0 0 auto;
}

/* --- File input ----------------------------------------------------------- */
/* Left as the browser's own control. A styled replacement is a label plus a
   visually-hidden input, and every such construct in the wild loses either the
   keyboard or the file name; the native control has both. */

.field input[type="file"] {
  padding: 8px 12px;
}
