/* ==========================================================================
   ShopFront — Form system
   --------------------------------------------------------------------------
   Field, label, control, hint, error, error summary and success panel.
   Lifted out of contact.css, which is where it was written and which
   predicted this move in its own header: the checkout and the account pages
   want exactly this and should not invent a second one.

   Loaded by contact.html, checkout.html and addresses.html — in that order
   of appearance on the site — and by nothing else. login.css deliberately
   keeps its own .field: an auth field wraps its control in a bordered shell
   with an icon, a reveal toggle and a validity tick, which is a different
   component that happens to share a name. Two pages never load both.

   Same rules as styles.css, and they are not negotiable:
     · no raw colour, no raw shadow, no off-grid spacing — tokens only;
     · logical properties throughout (dir="rtl", so inline-start = right);
     · the design is FLAT. Surfaces separate by border and tone.

   Contents
     01 · FIELDS
     02 · STATES, SUMMARY & SUCCESS
     03 · RESPONSIVE, CONTRAST
   ========================================================================== */


/* ==========================================================================
   01 · FIELDS
   --------------------------------------------------------------------------
   One field is a stack: label, control, then a slot that holds either the
   hint or the error. The slot is always present in the DOM even when
   empty, so validating a field cannot shift the fields beneath it.
   ========================================================================== */

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5) var(--gap-grid);
}

/* An author `display` beats the UA's `[hidden] { display: none }`, so a grid
   that is hidden stays on screen without this. The checkout hides the
   new-address block whenever a saved address is the one selected. */
.form-grid[hidden] {
  display: none;
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-inline-size: 0;
}

/* A field that must not share its row: the message box and the consent. */
.field--full {
  grid-column: 1 / -1;
}

.field__label {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--fg-default);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
}

/* Required is marked in words, not with a bare asterisk: a lone * is not
   announced usefully and means nothing to a first-time visitor. */
.field__req {
  color: var(--danger-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.field__optional {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-normal);
}

.field__control {
  inline-size: 100%;
  min-block-size: var(--btn-height);
  padding: var(--space-3) var(--space-4);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--fg-default);
  font-size: var(--text-lg);
  transition: var(--transition-colors);
}
.field__control::placeholder {
  color: var(--fg-subtle);
}
.field__control:hover {
  border-color: var(--border-strong);
}
.field__control:focus-visible {
  border-color: var(--brand);
}

/* Latin-only values — email, order code, phone — are typed and read
   left-to-right even inside an RTL form. Leaving them to inherit rtl puts
   the @ and the digits in the wrong visual order as they are typed. */
.field__control--ltr {
  direction: ltr;
  text-align: start;
}

textarea.field__control {
  min-block-size: 9rem;
  line-height: var(--leading-normal);
  resize: vertical;
}

/* The platform's own arrow is kept. It already mirrors with the writing
   direction, it is the affordance the visitor's OS has taught them, and a
   redrawn one cannot inherit the theme's colour without hard-coding a fill
   — which this system does not allow. The padding is the reserve it needs
   so a long option label never runs underneath it. */
select.field__control {
  padding-inline-end: var(--space-8);
  cursor: pointer;
}

.field__hint {
  color: var(--fg-subtle);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.field__error {
  display: none;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--danger-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}
.field__error .icon {
  flex: none;
  font-size: var(--icon-sm);
}

/* Checkbox row. The input keeps its native box — a custom one buys nothing
   here and loses the platform's own indeterminate and forced-colors
   handling. */
.field--check {
  flex-direction: row;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  padding: var(--space-4) var(--space-5);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--bg-surface-2);
}

.field--check input {
  flex: none;
  inline-size: var(--space-5);
  block-size: var(--space-5);
  margin-block-start: 0.15em;
  accent-color: var(--brand);
}

.field--check span {
  color: var(--fg-body);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
}
.field--check a {
  color: var(--brand-text);
  font-weight: var(--weight-bold);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-5);
  border-block-start: var(--border-hairline) solid var(--border-subtle);
}

.form-foot__note {
  flex: 1 1 16rem;
  color: var(--fg-subtle);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}


/* ==========================================================================
   02 · STATES, SUMMARY & SUCCESS
   ========================================================================== */

/* Invalid is carried by aria-invalid, not by a class: the attribute is what
   assistive technology reads, so styling the same hook keeps the visual and
   the announced state from ever disagreeing. */
.field__control[aria-invalid="true"] {
  border-color: var(--danger);
  background: var(--danger-subtle);
}
.field__control[aria-invalid="true"] ~ .field__hint {
  display: none;
}
.field__control[aria-invalid="true"] ~ .field__error {
  display: flex;
}

/* The consent row is laid out as input + text block, so its error message
   lives inside that block rather than beside the input. The sibling
   combinator above cannot reach it; this one can. */
.field--check input[aria-invalid="true"] ~ span .field__error {
  display: flex;
  margin-block-start: var(--space-2);
}

/* Summary above the form, filled in and focused when a submit fails. */
.form-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  margin-block-end: var(--space-6);
  padding: var(--space-4) var(--space-5);
  border: var(--border-hairline) solid var(--danger);
  border-radius: var(--radius-lg);
  background: var(--danger-subtle);
  color: var(--danger-text);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
}
.form-alert[hidden] {
  display: none;
}
.form-alert .icon {
  flex: none;
  margin-block-start: 0.15em;
  font-size: var(--icon-md);
}
.form-alert b {
  font-weight: var(--weight-bold);
}
.form-alert a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* Replaces the form on success. Not a toast: a submitted enquiry needs a
   reference number and a next step, and a toast that disappears after four
   seconds cannot carry either. */
.form-success {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-12) var(--space-8);
  border: var(--border-hairline) solid var(--border-brand);
  border-radius: var(--card-radius);
  background: var(--bg-brand-subtle);
  text-align: center;
}
.form-success[hidden] {
  display: none;
}

.form-success .icon-tile {
  inline-size: var(--space-16);
  block-size: var(--space-16);
  border-radius: var(--radius-circle);
  background: var(--brand);
  color: var(--fg-on-brand);
  font-size: var(--icon-xl);
}

.form-success__title {
  color: var(--fg-default);
  font-size: var(--text-4xl);
  font-weight: var(--weight-black);
}

.form-success__text {
  max-inline-size: 48ch;
  color: var(--fg-body);
  font-size: var(--text-lg);
  line-height: var(--leading-normal);
}

.form-success__ref {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  padding: var(--space-2) var(--space-5);
  border: var(--border-hairline) solid var(--border-brand);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--brand-text);
  font-size: var(--text-lg);
  font-weight: var(--weight-black);
  font-variant-numeric: tabular-nums;
}

.form-success__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-2);
}


/* ==========================================================================
   03 · RESPONSIVE, CONTRAST
   ========================================================================== */

@media (max-width: 800px) {
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .form-foot .btn { flex: 1 1 100%; }
  .form-success { padding: var(--space-8) var(--space-5); }
}

@media (prefers-contrast: more) {
  .field__control,
  .field--check {
    border-color: var(--fg-muted);
  }
}
