/* ============================================================
   TrendiestStore — form primitives

   Used by sections/ts-contact-form.liquid. Nothing contact-specific
   belongs here: if a rule only makes sense for one section, it goes
   in that section's own stylesheet.

   Dawn's own .field / .field__input pair is not reused. It draws a
   floating label inside the input, which needs a fixed 5rem input
   height and a label that overlaps the border — neither survives the
   softer, larger TrendiestStore field, and overriding it costs more
   rules than the ~90 lines below.

   1  Panel
   2  Fields
   3  Messages + submit
   4  Validation + busy state
   ============================================================ */

/* ---------- 1. panel ------------------------------------------ */
.ts-form-panel {
  padding: clamp(1.7rem, 3vw, 2.6rem);
  border-radius: var(--ts-r-lg);
  border: 1px solid var(--ts-line);
  background: var(--ts-panel-grad);
}

.ts-form-panel__h {
  margin: 0 0 0.5rem;
  font-size: clamp(1.8rem, 2vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ts-text);
}

.ts-form-panel__sub {
  margin: 0 0 1.6rem;
  font-size: 1.35rem;
  line-height: 1.55;
  color: var(--ts-muted);
}

/* ---------- 2. fields ----------------------------------------- */
.ts-form {
  display: block;
}

.ts-form__row {
  display: grid;
  gap: 1rem;
}

@media screen and (min-width: 600px) {
  .ts-form__row {
    grid-template-columns: 1fr 1fr;
  }
}

.ts-field {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin: 0 0 1.1rem;
}

.ts-field > label {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ts-muted-2);
}

.ts-field input[type='text'],
.ts-field input[type='email'],
.ts-field input[type='tel'],
.ts-field select,
.ts-field textarea {
  width: 100%;
  font-family: inherit;
  font-size: 1.45rem;
  line-height: 1.5;
  color: var(--ts-text);
  padding: 0.85em 1em;
  border-radius: var(--ts-r-sm);
  border: 1px solid var(--ts-line-2);
  background: var(--ts-surface-2);
  transition: border-color 0.2s, box-shadow 0.2s;
  -webkit-appearance: none;
  appearance: none;
}

.ts-field select {
  /* the caret the appearance reset just removed. Tokenised because a
     data URI cannot read currentColor, so the arrow would otherwise
     stay on the light-mode brown in dark mode. */
  background-image: var(--ts-caret);
  background-repeat: no-repeat;
  background-position: right 1em center;
  background-size: 16px 16px;
  padding-right: 3em;
}

/* The open dropdown list is drawn by the browser in its own layer, with
   no page behind it — so it cannot inherit the translucent
   --ts-surface-2 the closed control sits on. In dark mode that
   rgba(255,255,255,.09) composited against the popup's own ground and
   came out near-white, carrying near-white --ts-text on top of it:
   invisible. The list therefore gets the OPAQUE --ts-select-* pair,
   while the closed control keeps --ts-surface-2 so it still matches the
   text inputs beside it. `color-scheme` in ts-tokens.css does the rest
   (popup chrome, scrollbar, hover highlight). */
.ts-field select option,
.ts-field select optgroup {
  background-color: var(--ts-select-bg);
  color: var(--ts-select-text);
}

.ts-field textarea {
  resize: vertical;
  min-height: 9rem;
}

.ts-field input::placeholder,
.ts-field textarea::placeholder {
  color: var(--ts-muted-2);
  opacity: 0.75;
}

.ts-field input:focus,
.ts-field select:focus,
.ts-field textarea:focus {
  outline: none;
  border-color: var(--ts-brand);
  box-shadow: 0 0 0 3px var(--ts-brand-wash);
}

/* opt-in checkboxes — label beside the box, not stacked above it */
.ts-field--check {
  flex-direction: row;
  align-items: center;
  gap: 0.7rem;
}

.ts-field--check input {
  width: 18px;
  height: 18px;
  flex: none;
  accent-color: var(--ts-brand);
}

.ts-field--check > label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--ts-muted);
}

/* ---------- 3. messages + submit ------------------------------ */
.ts-form button[type='submit'] {
  width: 100%;
  margin-top: 0.4rem;
}

.ts-form__note {
  margin: 0.9rem 0 0;
  font-size: 1.2rem;
  line-height: 1.5;
  color: var(--ts-muted-2);
  text-align: center;
}

.ts-form__msg {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1.2rem;
  padding: 1em 1.2em;
  border-radius: var(--ts-r-sm);
  font-size: 1.35rem;
  line-height: 1.5;
  font-weight: 600;
}

.ts-form__msg:focus {
  outline: none;
}

.ts-form__msg svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the success message replaces the whole form, so it carries no
   bottom margin of its own */
.ts-form__msg--ok {
  margin: 0;
  color: var(--ts-mint);
  background: rgba(47, 138, 78, 0.12);
}

.ts-form__msg--err {
  color: var(--ts-brand-600);
  background: var(--ts-brand-wash);
}

/* ---------- 4. validation + busy state ------------------------ */
/* The asterisk is decorative — aria-required on the control is what
   carries the meaning — so it is aria-hidden in the markup and only
   needs to read as a mark rather than as part of the label text. */
.ts-req {
  color: var(--ts-brand);
  font-weight: 700;
}

/* Field-level errors, filled in by ts-contact-form.js. The slot is
   always in the DOM and empty until then, so showing a message never
   reflows the panel: the space is already reserved by the field it
   belongs to, and an empty span occupies nothing. */
.ts-field__err {
  display: none;
  font-size: 1.2rem;
  line-height: 1.45;
  font-weight: 600;
  color: var(--ts-brand-600);
}

.ts-field--invalid .ts-field__err {
  display: block;
}

.ts-field--invalid input,
.ts-field--invalid textarea {
  border-color: var(--ts-brand);
}

.ts-field--invalid input:focus,
.ts-field--invalid textarea:focus {
  box-shadow: 0 0 0 3px var(--ts-brand-wash);
}

/* Submitting posts a form and navigates, which on a slow connection is
   a second or two of a page that looks like it ignored the click. The
   button says otherwise and stops taking clicks, because the handler
   counts every send against an hourly allowance and a double submit
   spends two of them on one message. */
.ts-form button[type='submit'][aria-busy='true'] {
  pointer-events: none;
  opacity: 0.75;
}

.ts-form button[type='submit'][aria-busy='true'] svg {
  animation: ts-form-nudge 0.9s var(--ts-ease) infinite;
}

@keyframes ts-form-nudge {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(4px); }
}

@media (prefers-reduced-motion: reduce) {
  .ts-form button[type='submit'][aria-busy='true'] svg {
    animation: none;
  }
}
