/* ----------------------------------------------------------------- field
 * templates/ui/field.html. A label over its control, an optional hint
 * under it, and a validation message at the field itself - never only at
 * the top of the form (owner brief B, Formular).
 *
 * The element defaults below carry no specificity (:where): they are what
 * a bare input looks like, and any component or page rule overrides them
 * without a fight over selector weight or load order. One height for every
 * single-line control (--ctl-h), 2.6rem before (owner brief A).
 *
 * Every field - text, number, search, date, file, textarea, the select and
 * its button - has a silver frame (web.field.border) and a 1 px graphite
 * bottom edge (web.field.border-bottom, 5.07:1), so it reaches 3:1 without
 * changing the look (WEB-BAR-10, ENT-434 no. 33). Hover turns the other
 * three edges steel; focus turns the frame corum. */
@layer base {
:where(label) { display: block; font-size: var(--t-micro); color: var(--text-secondary); margin-bottom: var(--s-2); }
:where(input:not([type]), input[type="text"], input[type="email"], input[type="password"], input[type="date"],
       input[type="number"], input[type="search"], input[type="url"], input[type="tel"],
       input[type="file"], select, textarea) {
  box-sizing: border-box; width: 100%; font: inherit; font-size: var(--t-small); font-weight: 300;
  padding: 0 var(--ctl-px); color: var(--text-primary); background: var(--surface-page);
  /* web.field.border = rule-control, web.field.border-bottom = graphite (WEB-BAR-10) */
  border: 1px solid var(--rule-control); border-bottom-color: var(--rule-medium); border-radius: 0;
  transition: border-color var(--motion-fast) var(--ease);
}
:where(input:not([type]), input[type="text"], input[type="email"], input[type="password"], input[type="date"],
       input[type="number"], input[type="search"], input[type="url"], input[type="tel"], select) {
  height: var(--ctl-h);
}
:where(input[type="file"]) { height: var(--ctl-h); padding: var(--s-1) var(--ctl-px); }
:where(input:not(:disabled), select:not(:disabled), textarea:not(:disabled)):hover { border-color: var(--steel); border-bottom-color: var(--rule-medium); }
:where(input, select, textarea):focus {
  border-color: var(--rule-brand); outline: none; box-shadow: inset 0 -2px 0 var(--corum);
}
:where(input, select, textarea)::placeholder { color: var(--text-secondary); opacity: 1; }
/* Disabled (WEB-ZUS-07, ENT-346): the value in text-disabled (silver), no
   fill, full opacity; frame and graphite bottom edge stay (WEB-BAR-10) and
   do not answer the pointer. */
:where(input, select, textarea):disabled { background: var(--surface-page); color: var(--text-disabled); cursor: default; }
/* iOS gives date inputs an intrinsic width and centres their value; both make
   them fall out of line with the text fields around them. */
:where(input[type="date"]) { -webkit-appearance: none; appearance: none; min-width: 0; display: block; }
:where(input[type="date"])::-webkit-date-and-time-value { text-align: left; }
/* The clear cross of a search field: a drawn graphite cross like the
   chevron, not the browser's blue one (WEB-KOM-15). */
:where(input[type="search"])::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none; width: 10px; height: 10px; margin-left: .4em; cursor: pointer;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'%3E%3Cpath d='M1 1l8 8M9 1 1 9' fill='none' stroke='%236b6f72' stroke-width='1.3'/%3E%3C/svg%3E") center / 10px 10px no-repeat;
}
/* A native select before controls.js has turned it into the portal's
   dropdown (and where no script runs): the same chevron. */
:where(select) {
  appearance: none; padding-right: 2rem;
  /* A drawn chevron (graphite, 1.3 stroke), not two gradients. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b6f72' stroke-width='1.3'/%3E%3C/svg%3E");
  background-position: calc(100% - 10px) 50%; background-size: 10px 6px; background-repeat: no-repeat;
}
:where(textarea) { min-height: calc(3 * var(--ctl-h)); padding: var(--s-2) var(--ctl-px); resize: vertical; line-height: 1.5; }
:where(fieldset) { border: 0; padding: 0; margin: 0 0 var(--s-5); min-width: 0; }
:where(legend) { padding: 0; font-size: var(--t-micro); color: var(--text-secondary); margin-bottom: var(--s-3); }
}  /* @layer base */

@layer ui {
/* The component. */
.field { margin-bottom: var(--s-5); min-width: 0; }
.field__label { display: block; margin: 0 0 var(--s-2); font-size: var(--t-micro); color: var(--text-secondary); }
/* Required: an asterisk in the label, explained once by .field-legend. */
.field__req { margin-left: .15em; color: var(--text-secondary); }
.field__hint { font-size: var(--t-micro); color: var(--text-secondary); margin-top: var(--s-2); max-width: var(--measure); }
.field__error { display: block; font-size: var(--t-micro); color: var(--text-accent); margin-top: var(--s-2); max-width: var(--measure); }
.field.is-invalid :where(input, select, textarea), .field.is-invalid .cc-dd__btn { border-color: var(--rule-brand); }
.field-legend { font-size: var(--t-micro); color: var(--text-secondary); margin: 0 0 var(--s-4); }

/* Fields side by side; one column on a phone. */
.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 0 var(--s-5); }
/* A grid that is one row on the desktop: its fields zero their own bottom
   margin to line up (input beside its button). On the phone the grid folds
   to one column and those fields sat flush against each other - the grid
   supplies the vertical gap the fields gave up. Harmless on the desktop,
   where a single row has no row gap to show. */
.field-grid--row { row-gap: var(--s-4); }
.field--flush { margin-bottom: 0; }
}  /* @layer ui */
