/* ==========================================================================
   Component: datpro_form
   The site-wide form language. Built for /lien-he/ but deliberately generic —
   any later page (Tuyển dụng, đăng ký demo, newsletter) should consume these
   classes rather than inventing a second input style.

   Every value comes from tokens.css. Controls deliberately match .dp-btn:
     · min-height 48px          (same as .dp-btn)
     · border-radius --r-md     (same as .dp-btn)
     · 1px border               (--dp-border-strong)
     · font: inherit            (Be Vietnam Pro / Noto Sans SC)
     · the SAME focus ring as :focus-visible in base.css
       (2px solid var(--dp-blue), 3px offset) — re-declared only so the base
       rule's `border-radius: 4px` cannot square off a rounded control.

   Markup
     <form class="dp-form" novalidate>
       <div class="dp-form__grid">
         <div class="dp-field">
           <label class="dp-field__label" for="x">
             <span>Label</span><span class="dp-field__req" aria-hidden="true">*</span>
           </label>
           <input class="dp-control" id="x" name="x" required>
           <p class="dp-field__error" id="x-error" hidden>…</p>
         </div>
         <div class="dp-field dp-field--full"> … </div>
       </div>
       <p class="dp-form__legend">* Trường bắt buộc</p>
       <div class="dp-form__actions"> …dp-btn… </div>
       <div class="dp-form-status" role="status" aria-live="polite" tabindex="-1" hidden> … </div>
     </form>

   Errors are never signalled by colour alone: an icon + a text message sit
   under the control, the control carries aria-invalid + aria-describedby, and
   the submit result is a polite live region.
   ========================================================================== */

.dp-form {
  display: block;
}

/* An explicit `display` beats the UA stylesheet's `[hidden] { display: none }`,
   so every element this component toggles with the hidden attribute has to say
   so itself. Without this the error rows and the result panel would be visible
   from first paint. */
.dp-field__error[hidden],
.dp-form-status[hidden],
.dp-form-status__channels[hidden] {
  display: none;
}

/* --------------------------------------------------------------------------
   Field grid — one column, two from 640px. --full spans the row.
   -------------------------------------------------------------------------- */

.dp-form__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5) var(--sp-4);
}

@media (min-width: 640px) {
  .dp-form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .dp-field--full {
    grid-column: 1 / -1;
  }
}

/* --------------------------------------------------------------------------
   Field
   -------------------------------------------------------------------------- */

.dp-field {
  min-width: 0;
}

.dp-field__label {
  display: block;
  margin-bottom: 0.4375rem;
  color: var(--dp-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
}

.dp-field__req {
  margin-left: 0.1875rem;
  color: var(--dp-red);
  font-weight: var(--fw-bold);
}

.dp-field__hint {
  margin-top: 0.375rem;
  color: var(--dp-text-subtle);
  font-size: var(--fs-xs);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Controls — input / select / textarea share one look
   -------------------------------------------------------------------------- */

.dp-control {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 0.6875rem 0.875rem;
  background: var(--dp-bg);
  border: 1px solid var(--dp-border-strong);
  border-radius: var(--r-md);
  color: var(--dp-text);
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: 1.5;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}

.dp-control::placeholder {
  color: var(--dp-text-subtle);
  opacity: 1;
}

.dp-control:hover:not(:disabled) {
  border-color: var(--dp-blue-200);
}

/* Same ring as base.css :focus-visible — restated so the control keeps its own
   radius instead of the generic 4px, and gains a matching border colour. */
.dp-control:focus-visible {
  outline: 2px solid var(--dp-blue);
  outline-offset: 3px;
  border-radius: var(--r-md);
  border-color: var(--dp-blue);
}

.dp-control:disabled {
  background: var(--dp-surface);
  color: var(--dp-text-subtle);
  cursor: not-allowed;
}

/* Select — native arrow removed, replaced with the sprite chevron as an image
   (a <use> reference cannot live inside a <select>). */
.dp-control--select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364768c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9375rem center;
  background-size: 17px 17px;
  cursor: pointer;
  /* A <select> hard-clips text that does not fit. Keep option strings short
     enough to avoid it, and let anything that slips through degrade to an
     ellipsis instead of a truncated word. */
  text-overflow: ellipsis;
}

/* The unselected first option reads as a placeholder, not as a value. */
.dp-control--select:invalid,
.dp-control--select[data-empty="true"] {
  color: var(--dp-text-subtle);
}

.dp-control--textarea {
  min-height: 9.5rem;
  resize: vertical;
}

/* --------------------------------------------------------------------------
   Invalid state — border + icon + message, never colour alone
   -------------------------------------------------------------------------- */

.dp-control[aria-invalid="true"] {
  border-color: var(--dp-red);
  background: #fff8f7;
}

.dp-control[aria-invalid="true"]:focus-visible {
  outline-color: var(--dp-red);
  border-color: var(--dp-red);
}

.dp-field__error {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  margin-top: 0.4375rem;
  color: #b31812;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.5;
}

.dp-field__error::before {
  content: "";
  flex: none;
  width: 14px;
  height: 14px;
  margin-top: 0.1875rem;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-1 5h2v7h-2V7Zm0 9h2v2h-2v-2Z'/%3E%3C/svg%3E")
    center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-1 5h2v7h-2V7Zm0 9h2v2h-2v-2Z'/%3E%3C/svg%3E")
    center / contain no-repeat;
}

/* --------------------------------------------------------------------------
   Footer of the form
   -------------------------------------------------------------------------- */

.dp-form__legend {
  margin-top: var(--sp-4);
  color: var(--dp-text-subtle);
  font-size: var(--fs-xs);
  line-height: 1.5;
}

.dp-form__legend .dp-field__req {
  margin-left: 0;
  margin-right: 0.1875rem;
}

.dp-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-5);
}

@media (max-width: 559px) {
  .dp-form__actions .dp-btn {
    flex: 1 1 100%;
  }
}

.dp-form__note {
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--dp-border);
  color: var(--dp-text-muted);
  font-size: var(--fs-xs);
  line-height: 1.6;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   Submit result — one polite live region, three variants
     (default)   neutral / informational
     --error     validation summary
     --pending   the honest "not connected yet" state
   -------------------------------------------------------------------------- */

.dp-form-status {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  background: var(--dp-blue-50);
  border: 1px solid var(--dp-blue-100);
  border-left: 3px solid var(--dp-blue);
  border-radius: var(--r-md);
}

.dp-form-status:focus-visible {
  outline: 2px solid var(--dp-blue);
  outline-offset: 3px;
  border-radius: var(--r-md);
}

.dp-form-status__icon {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-top: 0.0625rem;
  color: var(--dp-blue);
}

.dp-form-status__icon svg {
  width: 20px;
  height: 20px;
}

.dp-form-status__body {
  min-width: 0;
}

.dp-form-status__title {
  color: var(--dp-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.45;
}

.dp-form-status__desc {
  margin-top: 0.25rem;
  color: var(--dp-text-body);
  font-size: var(--fs-sm);
  line-height: 1.6;
  text-wrap: pretty;
}

.dp-form-status__channels {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-3);
}

.dp-form-status__channel {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  color: var(--dp-blue);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.dp-form-status__channel svg {
  flex: none;
  width: 16px;
  height: 16px;
}

.dp-form-status__channel:hover {
  color: var(--dp-blue-700);
  text-decoration: underline;
}

/* Validation summary */
.dp-form-status--error {
  background: #fdf3f2;
  border-color: #f6d5d3;
  border-left-color: var(--dp-red);
}

.dp-form-status--error .dp-form-status__icon {
  color: var(--dp-red);
}

/* Honest "the form is not wired to a backend yet" state */
.dp-form-status--pending {
  background: #fffaf0;
  border-color: #f6e3bd;
  border-left-color: var(--dp-gold);
}

.dp-form-status--pending .dp-form-status__icon {
  color: #b57a06;
}
