/* ================================================================
   FORMULIERSTANDAARD — dé opmaak voor elk klantformulier
   (afrekenen, Mijn account, inloggen/registreren, wachtwoord, MFA).

   Vastgelegd op wens van Wian (2026-09-12): "de invoervelden en validatie
   van de afrekenpagina wil ik als standaard doorvoeren" en "borg deze
   styling ook ergens gedeeld". Dit bestand is die ene plek; de markup komt
   uit templates/partials/formulier-macros.html en het gedrag (veldcontrole,
   foutregels, 422-fouten) uit static/js/formulier.js. Zie CLAUDE.md ›
   Conventions › Formulieren. Geen pagina-specifieke kopieën van deze regels
   in pages.css maken — een afwijking hoort hier, als variant.
   ================================================================ */

/* ── Formulier als geheel ─────────────────────────────────────────────── */

/* Eén kolom, vaste afstand tussen de velden. */
.formulier {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Variant: in een kaart (afrekenen). */
.formulier--kaart {
  background: var(--color-surface-container);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-lg);
  padding: 24px;
}

/* Variant: leesbare breedte op een brede pagina (Mijn account). Een veld
   van 1150px breed leest niet; 560px is ruim genoeg voor een adres. */
.formulier--smal { max-width: 560px; }

/* Variant: een beheerformulier (Admin › Materialen). De velden staan in
   `.admin-form-row`-rijen naast elkaar in plaats van in één kolom, en het
   label volgt de admin-opmaak (`.form-label` in pages.css: mono, kapitaal)
   zodat macro-velden en gewone admin-velden in één rij hetzelfde ogen. */
.formulier--admin { gap: 0; }
.formulier--admin .veld-label {
  font-family: var(--font-mono);
  font-size: var(--text-13);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
}
.formulier--admin .veld-toelichting { text-transform: none; letter-spacing: var(--tracking-normal); }
.formulier--admin .veld input:not([type="checkbox"]):not([type="radio"]),
.formulier--admin .veld select {
  padding: 10px 14px;
  border-radius: var(--radius-lg);
}
.formulier--admin .formulier-fout { margin-bottom: 16px; }

/* Tussenkop in een formulier ("Afleveradres", "Factuuradres"). */
.formulier-kop {
  font-size: var(--text-16);
  font-weight: 700;
  color: var(--color-on-surface);
  margin: 0 0 -4px;
}
.formulier-kop:not(:first-child) { margin-top: 8px; }

/* Uitlegregel onder de kop ("Velden met een * zijn verplicht"). */
.formulier-uitleg {
  font-size: var(--text-12);
  color: var(--color-on-surface-variant);
  margin: -8px 0 -2px;
}

/* Geneste groep (bv. het afwijkende factuuradres onder zijn vinkje):
   dezelfde afstand als de rest, met een rand zodat het als één blok leest. */
.formulier-blok {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
}
.formulier-blok[hidden] { display: none; }

/* Knoppenrij onderaan. */
.formulier-acties {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 4px;
}

/* ── Veld: label boven, invoer, foutregel eronder ─────────────────────── */

.veld {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--text-13);
  font-weight: 500;
  color: var(--color-on-surface-variant);
}

/* Labeltekst, sterretje en toelichting op één regel (het label zelf is een
   kolom: tekst, invoer, foutregel). */
.veld-label { display: block; }

.veld input:not([type="checkbox"]):not([type="radio"]),
.veld select,
.veld textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-size: var(--text-14);
  font-family: var(--font-sans);
  outline: none;
  transition: border-color 0.15s;
}
.veld textarea { resize: vertical; min-height: 120px; }

.veld input:focus,
.veld select:focus,
.veld textarea:focus {
  outline: 2px solid var(--color-primary);
  border-color: transparent;
}

/* Vaste waarde (bv. Land = Nederland): leesbaar maar duidelijk niet te wijzigen. */
.veld input:disabled,
.veld select:disabled {
  background: var(--color-surface-container);
  color: var(--color-on-surface-variant);
  cursor: not-allowed;
}

/* ── Oogje bij wachtwoordvelden (issue #371) ──────────────────────────────
   static/js/wachtwoord-oogje.js wikkelt elk input[type=password] in
   `.veld-invoer--wachtwoord` en zet er een knop naast. De wikkel is de
   positie-context; het veld krijgt rechts ruimte zodat de tekst niet onder
   het icoon doorloopt. */
.veld-invoer--wachtwoord {
  position: relative;
  display: block;
  width: 100%;
}

.veld-invoer--wachtwoord input {
  /* 12px basispadding + 26px knop + 6px lucht */
  padding-right: 44px !important;
}

.veld-oogje {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-on-surface-variant);
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}

.veld-oogje:hover {
  color: var(--color-on-surface);
  background: var(--color-surface-container);
}

.veld-oogje:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.veld-oogje .material-symbols-outlined {
  font-size: var(--text-20);
  line-height: var(--leading-none);
}

/* Klein toelichtinkje in het label, bv. "(min. 8 tekens)". */
.veld-toelichting {
  font-weight: 400;
  color: var(--color-outline);
  margin-left: 4px;
}

/* Postcode + huisnummer naast elkaar: samen één opzoekactie (adres.js). */
.veld-rij {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 12px;
}
/* Twee gelijke kolommen (bv. voornaam/achternaam). */
.veld-rij--gelijk { grid-template-columns: 1fr 1fr; }

/* Korte statusmelding onder de postcode/huisnummer-rij ("Adres opzoeken…"). */
.veld-hint {
  margin: -6px 0 -4px;
  font-size: var(--text-13);
  color: var(--color-on-surface-variant);
}
.veld-hint[hidden] { display: none; }
/* Een veld dat pas na een JS-check mag verschijnen (bv. de routekeuze van
   label-ble.js) — `display: flex` hierboven zou [hidden] anders overrulen. */
.veld[hidden] { display: none; }

/* Sterretje bij verplichte velden. Voor het oog; schermlezers krijgen
   `aria-required` op het veld zelf. */
.verplicht {
  color: var(--color-error);
  font-weight: 700;
  margin-left: 2px;
}

/* De foutregel houdt zijn plek ook als hij leeg is. Zonder gereserveerde
   ruimte schoof het formulier omlaag zodra een melding verscheen — en dat
   gebeurde precies tussen mousedown en mouseup van de eerste klik na het
   verlaten van een veld (blur → melding), waardoor die klik verloren ging. */
.veld-fout {
  display: block;
  min-height: 1.15em;
  line-height: var(--leading-tight);
  color: #b71c1c;
  font-size: var(--text-12);
  font-weight: 500;
}
.veld-fout:empty { visibility: hidden; }

.veld input[aria-invalid="true"],
.veld select[aria-invalid="true"],
.veld textarea[aria-invalid="true"] {
  border-color: #b71c1c;
}
.veld input[aria-invalid="true"]:focus,
.veld select[aria-invalid="true"]:focus,
.veld textarea[aria-invalid="true"]:focus {
  outline-color: #b71c1c;
}

/* ── Vinkje: hokje naast tekst (geen label-boven-invoer) ──────────────── */

.vinkje {
  display: flex;
  flex-direction: row;
  gap: 10px;
  align-items: flex-start;
  line-height: var(--leading-normal);
  cursor: pointer;
  font-size: var(--text-14);
  font-weight: 400;
  color: var(--color-on-surface);
}
/* Eigen vakje, om dezelfde reden als het keuzerondje hieronder: het native
   vinkje is 13x13 px met een vaag randje en valt op de crèmekleurige
   achtergrond nauwelijks op — aan en uit zijn dan slecht uit elkaar te
   houden. Nu 18 px met een duidelijke rand, en aangevinkt een gevuld vlak in
   de merkkleur met een wit vinkje erin (achtergrondafbeelding, want een
   pseudo-element werkt niet op een input). */
.vinkje input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  flex-shrink: 0;
  border: 2px solid var(--color-on-surface-variant);
  border-radius: 4px;
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.vinkje input[type="checkbox"]:hover {
  border-color: var(--color-primary);
}

.vinkje input[type="checkbox"]:checked {
  border-color: var(--color-primary);
  background: var(--color-primary)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3 8.5 6.5 12 13 4.5'/%3E%3C/svg%3E")
    center / 14px 14px no-repeat;
}

.vinkje input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
/* Een vinkje heeft geen rand die rood kan worden; de omlijning doet dat werk. */
.vinkje input[type="checkbox"][aria-invalid="true"] {
  outline: 2px solid #b71c1c;
  outline-offset: 1px;
}
.vinkje a { color: var(--color-primary); }

/* Keuzerondjes (radio) voor een klein vast lijstje, bv. de bedplaat van een
   printer. Een fieldset zonder rand, de rondjes onder elkaar met dezelfde
   tekstopmaak als een vinkje. */
.keuzerondjes { border: 0; padding: 0; margin: 0; min-width: 0; }
.keuzerondjes legend { padding: 0; }
.keuzerondje {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  line-height: var(--leading-normal);
  cursor: pointer;
  font-size: var(--text-14);
  font-weight: 400;
  color: var(--color-on-surface);
  margin-top: 6px;
}

/* Eigen rondje i.p.v. het rondje van de browser (Wian, 14-09-2026: "radiobutton
   unchecked missed, wat checked ook"). Het native rondje is 13x13 px en tekent
   zichzelf met een dun, lichtgrijs randje; op onze crèmekleurige achtergrond
   (#fef9f0) viel dat zó weinig op dat je niet zag wélke optie aanstond — en
   een niet-aangevinkt rondje was bijna onzichtbaar. `accent-color` alleen
   kleurt de gevulde stip, niet de rand eromheen, dus dat loste het niet op.

   Nu: 18 px, een duidelijke rand in de tekstkleur, en een aangevinkt rondje
   dat helemaal in de merkkleur vult met een uitgespaarde kern. Zo is het
   verschil tussen aan en uit op afstand te zien. `appearance: none` schakelt
   de eigen tekening van de browser uit; zonder die regel stapelt ons rondje
   er bovenop. */
.keuzerondje input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  flex-shrink: 0;
  border: 2px solid var(--color-on-surface-variant);
  border-radius: 50%;
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.keuzerondje input[type="radio"]:hover {
  border-color: var(--color-primary);
}

/* De gevulde kern via een inzet-schaduw en niet via ::before: een input is een
   vervangen element (replaced), dus pseudo-elementen zijn daar niet betrouwbaar. */
.keuzerondje input[type="radio"]:checked {
  border-color: var(--color-primary);
  box-shadow: inset 0 0 0 3px var(--color-surface), inset 0 0 0 10px var(--color-primary);
}

.keuzerondje input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.keuzerondje-uitleg { color: var(--color-on-surface-variant); }
.keuzerondjes[aria-invalid="true"] .keuzerondje input[type="radio"] {
  outline: 2px solid #b71c1c;
  outline-offset: 1px;
}

/* ── Meldingen op formulierniveau ─────────────────────────────────────── */

/* Fout die niet bij één veld hoort (server, netwerk, "onbekend e-mailadres
   of wachtwoord"). `.auth-error` is dezelfde melding zoals de auth-routes
   'm via htmx terugsturen (routes/auth.rs, routes/mfa.rs). */
.formulier-fout,
.auth-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 14px;
  background: color-mix(in srgb, #b71c1c 10%, transparent);
  color: #b71c1c;
  border: 1px solid color-mix(in srgb, #b71c1c 25%, transparent);
  border-radius: var(--radius-md);
  font-size: var(--text-14);
  line-height: var(--leading-normal);
}
.formulier-fout[hidden] { display: none; }
.formulier-fout .material-symbols-outlined,
.auth-error .material-symbols-outlined { font-size: var(--text-18); flex-shrink: 0; }

/* Neutrale of geslaagde melding ("Adressen opgeslagen", "check je inbox").
   `.auth-notice` is dezelfde melding uit routes/auth.rs. */
.formulier-melding,
.auth-notice {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--color-primary);
  border: 1px solid color-mix(in srgb, var(--color-primary) 25%, transparent);
  border-radius: var(--radius-md);
  font-size: var(--text-14);
  line-height: var(--leading-normal);
}
.formulier-melding[hidden] { display: none; }
.formulier-melding .material-symbols-outlined { font-size: var(--text-18); flex-shrink: 0; }

/* Waarschuwing die geen fout is (herroepingsrecht, "we kijken elke
   bestelling na"): rustig vlak, geen rood. */
.formulier-let-op {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-size: var(--text-13);
  line-height: var(--leading-normal);
  color: var(--color-on-surface-variant);
}
.formulier-let-op[hidden] { display: none; }
.formulier-let-op .material-symbols-outlined {
  font-size: var(--text-20);
  color: var(--color-primary);
  flex-shrink: 0;
}
.formulier-let-op a { color: var(--color-primary); }

/* Knop bezig ("Bezig…"): niet klikbaar, wel leesbaar. */
.formulier button[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Smal scherm ───────────────────────────────────────────────────────── */
@media (max-width: 600px) {
  .formulier--kaart { padding: 16px; }
  .veld-rij { grid-template-columns: 120px 1fr; }
}
