/* ============================================================
   components.css - de onderdelen die op elke klantsite terugkomen
   Vereist tokens.css en base.css.
   ============================================================ */

@layer components {

  /* ---- Knoppen ---------------------------------------------
     button voor acties, a voor navigatie. Een .btn-klasse op
     een <a> is prima, een <div onclick> nooit.                */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2xs);
    min-height: 48px;              /* raakdoel, ruim boven 44px */
    padding: var(--sp-2xs) var(--sp-m);
    border: 1px solid transparent;
    border-radius: var(--r-m);
    font-weight: 600;
    font-size: var(--step-0);
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;           /* label past op een regel   */
    cursor: pointer;
    transition: background-color var(--dur) var(--ease),
                border-color var(--dur) var(--ease),
                transform var(--dur-fast) var(--ease);
  }
  .btn:active { transform: translateY(1px); }

  .btn--primary {
    background: var(--accent);
    color: var(--on-accent);
  }
  .btn--primary:hover { background: var(--accent-strong); }

  .btn--secondary {
    background: transparent;
    color: var(--text-strong);
    border-color: var(--n-4);
  }
  .btn--secondary:hover { border-color: var(--text-strong); background: var(--n-1); }

  .btn[aria-disabled="true"], .btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
  }

  /* Spinner verschijnt pas als het verzoek loopt, de knop
     blijft tot dan klikbaar.                                   */
  .btn[data-busy="true"]::before {
    content: "";
    width: 1em; height: 1em;
    border: 2px solid currentColor;
    border-block-start-color: transparent;
    border-radius: var(--r-full);
    animation: spin 700ms linear infinite;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  @media (prefers-reduced-motion: reduce) {
    .btn[data-busy="true"]::before { animation-duration: 2s; }
  }

  /* ---- Telefoon: het meest ingedrukte element op mobiel ---- */
  .tel-link {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* ---- Header en navigatie ---------------------------------
     Een regel op desktop. Twee regels is stuk.                 */
  .site-header {
    position: sticky;
    inset-block-start: 0;
    z-index: 50;
    background: color-mix(in srgb, var(--bg) 92%, transparent);
    backdrop-filter: blur(8px);
    border-block-end: 1px solid var(--rule);
  }
  .site-header__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-m);
    min-height: var(--nav-h);
  }
  .site-header__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2xs);
    font-weight: 700;
    font-size: var(--step-1);
    color: var(--text-strong);
    text-decoration: none;
    letter-spacing: -0.01em;
  }
  .site-nav { display: flex; align-items: center; gap: var(--sp-m); }
  .site-nav a {
    color: var(--text);
    text-decoration: none;
    font-size: var(--step-0);
    white-space: nowrap;
  }
  .site-nav a:hover { color: var(--accent-strong); }
  .site-nav a[aria-current="page"] {
    color: var(--text-strong);
    font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--accent);
  }

  .nav-toggle { display: none; }

  /* Het uitklapmenu bestaat alleen als er JS is om het te
     bedienen. enhance.js zet data-js op <html>. Zonder dat
     attribuut valt de navigatie op smalle schermen terug op een
     gewone doorlopende rij links: minder mooi, maar wel volledig
     bruikbaar. Een vast paneel dat niemand kan sluiten zou dat
     niet zijn.                                                 */
  @media (max-width: 860px) {
    .site-header__row { flex-wrap: wrap; row-gap: var(--sp-2xs); }
    .site-nav { flex-wrap: wrap; gap: var(--sp-s); padding-block-end: var(--sp-2xs); }

    [data-js] .nav-toggle {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 48px; height: 48px;
      background: transparent;
      border: 1px solid var(--n-4);
      border-radius: var(--r-s);
      cursor: pointer;
    }
    .nav-toggle[hidden] { display: none; }

    [data-js] .site-nav {
      position: fixed;
      inset: var(--nav-h) 0 auto 0;
      flex-direction: column;
      flex-wrap: nowrap;
      align-items: stretch;
      gap: 0;
      background: var(--bg);
      border-block-end: 1px solid var(--rule);
      padding: var(--sp-s) var(--gutter) var(--sp-m);
      box-shadow: var(--shadow-m);
      overscroll-behavior: contain;
      max-height: calc(100dvh - var(--nav-h));
      overflow-y: auto;
    }
    [data-js] .site-nav[hidden] { display: none; }
    [data-js] .site-nav a {
      padding-block: var(--sp-xs);
      border-block-end: 1px solid var(--rule);
    }
    [data-js] .site-nav a:last-of-type { border-block-end: 0; }
    [data-js] .site-nav .btn { margin-block-start: var(--sp-s); }
  }

  /* ---- Hero -------------------------------------------------
     Past in het eerste scherm. Kop maximaal 2 regels, subtekst
     maximaal 20 woorden, CTA zichtbaar zonder scrollen.
     Maximaal 4 tekstelementen. Referentielogos staan eronder,
     nooit erin.                                                */
  .hero {
    padding-block: var(--hero-pad-top) var(--sp-2xl);
    position: relative;
  }
  .hero__title {
    font-size: var(--step-5);
    max-width: 18ch;
  }
  .hero__sub {
    font-size: var(--step-1);
    line-height: var(--lh-snug);
    color: var(--text-muted);
    max-width: 46ch;
    margin-block-end: var(--sp-l);
  }
  .hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-xs); }

  .hero--split {
    display: grid;
    gap: var(--sp-xl);
    align-items: center;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  }
  @media (max-width: 860px) {
    .hero--split { grid-template-columns: 1fr; gap: var(--sp-l); }
  }

  .hero__media {
    border-radius: var(--r-l);
    overflow: hidden;
    box-shadow: var(--shadow-m);
  }
  .hero__media img { width: 100%; height: 100%; object-fit: cover; }

  /* ---- Media met tekst, asymmetrisch ------------------------
     Maximaal twee van deze op een rij, daarna een andere
     layoutfamilie. Zie de controle in tools/check.py.          */
  .duo {
    display: grid;
    gap: var(--sp-xl);
    align-items: center;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }
  .duo--flip > :first-child { order: 2; }
  @media (max-width: 860px) {
    .duo { grid-template-columns: 1fr; gap: var(--sp-l); }
    .duo--flip > :first-child { order: 0; }
  }

  /* ---- Kaarten ---------------------------------------------- */
  .card {
    background: var(--bg);
    border: 1px solid var(--rule);
    border-radius: var(--r-l);
    padding: var(--sp-m);
  }
  .card--tinted { background: var(--accent-tint); border-color: transparent; }
  .card--media { padding: 0; overflow: hidden; }
  .card--media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
  .card--media .card__body { padding: var(--sp-m); }

  /* Horizontale rij, alternatief voor drie gelijke kaarten. */
  .rail {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(16rem, 22rem);
    gap: var(--sp-m);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    padding-block-end: var(--sp-2xs);
  }
  .rail > * { scroll-snap-align: start; }

  /* ---- Openingsuren, de meest bekeken inhoud ---------------- */
  .hours { width: 100%; border-collapse: collapse; }
  .hours th, .hours td {
    text-align: start;
    padding-block: var(--sp-3xs);
    font-variant-numeric: tabular-nums;
  }
  .hours th { font-weight: 500; color: var(--text-muted); padding-inline-end: var(--sp-m); }
  .hours [data-today] { color: var(--text-strong); font-weight: 700; }
  .hours .closed { color: var(--text-muted); }

  /* ---- Formulieren, de omzetkritische kant ----------------- */
  .field { margin-block-end: var(--sp-m); }
  .field > label {
    display: block;
    font-weight: 600;
    font-size: var(--step--1);
    color: var(--text-strong);
    margin-block-end: var(--sp-3xs);
    cursor: pointer;
  }
  .field__hint {
    display: block;
    font-size: var(--step--1);
    color: var(--text-muted);
    margin-block-end: var(--sp-3xs);
  }
  .input, .textarea, .select {
    width: 100%;
    min-height: 48px;
    padding: var(--sp-2xs) var(--sp-xs);
    background: var(--bg);
    color: var(--text-strong);
    border: 1px solid var(--n-4);
    border-radius: var(--r-m);
    transition: border-color var(--dur-fast) var(--ease);
  }
  .textarea { min-height: 8rem; resize: vertical; }
  .input::placeholder, .textarea::placeholder { color: var(--text-muted); }
  .input:hover, .textarea:hover, .select:hover { border-color: var(--n-6); }

  /* Een native select zonder eigen kleuren wordt onleesbaar in
     de donkere modus van Windows.                              */
  .select {
    background-color: var(--bg);
    color: var(--text-strong);
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
                      linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
    background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
    padding-inline-end: var(--sp-xl);
  }

  .field[data-invalid] .input,
  .field[data-invalid] .textarea,
  .field[data-invalid] .select { border-color: var(--danger); }

  .field__error {
    display: none;
    margin-block-start: var(--sp-3xs);
    font-size: var(--step--1);
    color: var(--danger);
  }
  .field[data-invalid] .field__error { display: block; }

  /* Selectievakje en label delen een raakdoel. */
  .check {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2xs);
    cursor: pointer;
    padding-block: var(--sp-3xs);
  }
  .check input {
    width: 1.25rem; height: 1.25rem;
    margin-block-start: 0.15rem;
    flex: none;
    accent-color: var(--accent);
  }
  .check span { font-size: var(--step--1); max-width: 60ch; }

  .form-status {
    padding: var(--sp-xs) var(--sp-s);
    border-radius: var(--r-m);
    margin-block-end: var(--sp-m);
  }
  .form-status[data-state="ok"]    { background: var(--accent-tint); color: var(--text-strong); }
  .form-status[data-state="fout"]  { background: var(--danger-tint); color: var(--danger); }
  .form-status[data-state="bezig"] { background: var(--bg-panel); color: var(--text); }
  .form-status:empty { display: none; }

  /* ---- Voettekst -------------------------------------------
     Bedrijfsnaam, adres, KBO/BTW, telefoon en openingsuren.
     Dat is een wettelijke verplichting, geen versiering.       */
  .site-footer {
    background: var(--bg-sunken);
    border-block-start: 1px solid var(--rule);
    padding-block: var(--sp-xl) var(--sp-l);
    padding-block-end: max(var(--sp-l), env(safe-area-inset-bottom));
    font-size: var(--step--1);
  }
  .site-footer__grid {
    display: grid;
    gap: var(--sp-l);
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  }
  .site-footer h2 {
    font-size: var(--step-0);
    margin-block-end: var(--sp-2xs);
  }
  .site-footer a { color: var(--text); }
  .site-footer address { font-style: normal; }
  .site-footer__legal {
    margin-block-start: var(--sp-l);
    padding-block-start: var(--sp-s);
    border-block-start: 1px solid var(--rule);
    color: var(--text-muted);
  }

  /* ---- Rustige inkomst, alleen transform en opacity --------
     Het verbergen hangt aan [data-js], net als het uitklapmenu.
     Laadt enhance.js niet, of struikelt het, dan staat de inhoud
     er gewoon. Onzichtbare inhoud is een veel ergere fout dan een
     overgeslagen animatie: de tekst is het product.             */
  [data-js] .reveal {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity var(--dur-slow) var(--ease),
                transform var(--dur-slow) var(--ease);
  }
  [data-js] .reveal[data-shown] { opacity: 1; transform: none; }
  @media (prefers-reduced-motion: reduce) {
    [data-js] .reveal { opacity: 1; transform: none; }
  }
}
