
  :root {
    --brand: #0000a4;         /* merkkleur, actieve navigatie */
    --action: #2e6bff;        /* knop die iets doet */
    --action-hover: #1d4ed8;
    --page: #f5f6f8;
    --card: #ffffff;
    --line: #eaecf0;
    --line-strong: #e5e7eb;
    --text: #101828;
    --body: #374151;
    --muted: #6b7280;
    --faint: #9ca3af;
    --nav: #475467;
    --nav-icon: #667085;
    --label: #98a2b3;
    --ok-text: #065f46; --ok-bg: #d1fae5; --ok-line: #a7f3d0;
    --bad-text: #991b1b; --bad-bg: #fee2e2; --bad-line: #fecaca;
    --warn-text: #92400e; --warn-bg: #fef3c7; --warn-line: #fde68a;
    --info-bg: #eef1ff;
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--page);
    color: var(--text);
    font-size: 14px;
  }

  /* ── De schil ──────────────────────────────────────────────────────────── */
  .shell { display: flex; min-height: 100vh; }
  .sidebar {
    width: 248px; flex-shrink: 0; background: var(--card);
    border-right: 1px solid var(--line); display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh;
  }
  .brand {
    padding: 24px 24px 20px; display: flex; align-items: baseline; gap: 10px;
    font-size: 24px; font-weight: 800; color: var(--brand); letter-spacing: -0.03em;
    text-decoration: none;
  }
  /* De toevoeging achter de merknaam (omgeving of klant) breekt als geheel naar
     de tweede regel en niet middenin een naam: "WDM / Brands" leest als een
     fout. */
  .brand { flex-wrap: wrap; }
  .brand span { font-size: 13px; font-weight: 600; color: var(--muted); letter-spacing: 0;
                white-space: nowrap; }
  nav { display: flex; flex-direction: column; gap: 4px; padding: 8px 14px; flex: 1;
        overflow-y: auto; }
  nav a {
    display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px;
    text-decoration: none; font-size: 14px; font-weight: 600; color: var(--nav);
  }
  /* Het teken kleurt mee met de regel, zodat de actieve regel één ding is en
     niet een gekleurd woord naast een grijs plaatje. */
  nav a svg { flex: none; stroke: var(--nav-icon); }
  nav a:hover { background: var(--page); }
  nav a.active, nav a[aria-current] { color: var(--brand); background: var(--info-bg); }
  nav a.active svg, nav a[aria-current] svg { stroke: var(--brand); }
  nav .group { font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
               text-transform: uppercase; color: var(--faint); padding: 14px 12px 4px; }
  .sidebar-foot, .foot { padding: 16px; border-top: 1px solid var(--line); }
  .who {
    background: #f9fafb; border-radius: 12px; padding: 14px 16px;
    display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: var(--muted);
    overflow-wrap: anywhere;
  }
  .who .label { font-size: 11px; font-weight: 600; color: var(--label);
                text-transform: uppercase; letter-spacing: 0.04em; }
  .who strong { color: var(--text); font-weight: 700; font-size: 14px; }
  .who .role { font-size: 12px; color: var(--muted); }
  .spacer { flex: 1; }

  main { flex: 1; padding: 28px 36px; min-width: 0; }
  body.plain main { max-width: 40rem; margin: 0 auto; }
  header { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
           flex-wrap: wrap; margin-bottom: 20px; }
  h1 { font-size: 28px; font-weight: 700; margin: 0; letter-spacing: -0.02em; }
  h2 { font-size: 14px; font-weight: 600; margin: 0; color: var(--body); }
  .sub, .lede { font-size: 14px; color: var(--muted); margin: 6px 0 0; }
  .page-head { margin: 0 0 20px; }
  .page-head .back, .back { font-size: 13px; display: inline-block; margin-bottom: 10px;
                            color: var(--action); text-decoration: none; }

  /* ── Bouwstenen ────────────────────────────────────────────────────────── */
  .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
           gap: 12px; margin-bottom: 20px; }
  .stat { background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px;
          padding: 16px 20px; display: flex; flex-direction: column; gap: 4px; }
  .stat .label { font-size: 12px; color: var(--muted); font-weight: 500; }
  .stat .value { font-size: 24px; font-weight: 700; color: var(--brand); line-height: 1.1; }
  .stat .sub { font-size: 11.5px; color: var(--faint); margin: 0; }

  .card { background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px;
          overflow: hidden; margin: 0 0 16px; }
  .card > .head { padding: 14px 16px 12px; border-bottom: 1px solid var(--line); }
  .card > .head .sub, .card > .head p { margin: 4px 0 0; font-size: 12.5px; }
  .card > .body { padding: 16px; }
  .card > .body.tightpad { padding: 12px 16px; }

  table { border-collapse: collapse; width: 100%; }
  th { padding: 10px 12px 8px; font-size: 12px; font-weight: 600; color: var(--muted);
       text-align: left; white-space: nowrap; background: #f9fafb;
       border-bottom: 1px solid var(--line-strong); }
  td { padding: 9px 12px; font-size: 13px; color: var(--body);
       border-bottom: 1px solid var(--line); vertical-align: top; }
  tr:last-child td { border-bottom: none; }
  td.num, th.num, td.right, th.right { text-align: right; font-variant-numeric: tabular-nums; }
  td.tight, th.tight { white-space: nowrap; }
  /* Een link in een tabel is een rij om op te klikken, geen voetnoot: kleur en
     gewicht zijn genoeg, een streep eronder maakt de tabel rommelig. */
  td a { text-decoration: none; font-weight: 600; }
  td a:hover { text-decoration: underline; }
  .scroll { overflow-x: auto; }
  .empty { padding: 22px; font-size: 13px; color: var(--faint); text-align: center;
           font-style: normal; }
  /* Diezelfde klasse wordt ook inline gebruikt: een streepje in een lege cel,
     of "reden niet leesbaar" naast een retour. Dan is die padding van 22 pixels
     geen ruimte om een leeg vak maar een inspringing, en 'text-align' doet op
     een inline element niets. Gemeten op Monthly issues: "reden niet leesbaar"
     stond 22 pixels naar rechts ten opzichte van de datum erboven, en elk
     streepje in een getalkolom stond scheef. */
  span.empty { padding: 0; }

  .pill { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 8px;
          white-space: nowrap; display: inline-block; color: var(--muted);
          background: #f3f4f6; border: 1px solid var(--line-strong); }
  .pill.ok  { color: var(--ok-text);  background: var(--ok-bg);  border-color: var(--ok-line); }
  .pill.bad { color: var(--bad-text); background: var(--bad-bg); border-color: var(--bad-line); }
  .pill.work { color: var(--warn-text); background: var(--warn-bg); border-color: var(--warn-line); }

  button, .btn {
    background: var(--action); border: none; border-radius: 10px; padding: 10px 18px;
    font-size: 13px; font-weight: 600; color: #fff; cursor: pointer; font-family: inherit;
  }
  button:hover { background: var(--action-hover); }
  button.plain, button.small {
    background: var(--card); border: 1px solid var(--line-strong); color: var(--body);
  }
  button.plain:hover, button.small:hover { background: var(--page); }
  button.small { padding: 7px 12px; font-size: 12px; }
  button.primary { background: var(--action); color: #fff; border: none; }
  button.primary:hover { background: var(--action-hover); }
  button.danger { background: var(--card); color: var(--bad-text);
                  border: 1px solid var(--bad-line); }
  button.danger:hover { background: var(--bad-bg); }
  button[disabled] { opacity: .5; cursor: default; }

  label { display: block; font-size: 12px; color: var(--muted); font-weight: 500;
          margin: 0 0 5px; }
  input, select, textarea {
    padding: 8px 10px; font-size: 13px; border: 1px solid var(--line-strong);
    border-radius: 10px; color: var(--text); background: var(--card); font-family: inherit;
    max-width: 100%;
  }
  input:focus, select:focus, textarea:focus { outline: 2px solid var(--info-bg);
                                              border-color: var(--brand); }
  textarea { width: 100%; min-height: 4.5rem; }
  input[type=checkbox] { width: auto; }

  .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
  form.inline { display: inline-flex; gap: 8px; align-items: center; margin: 0; }
  .note { background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px;
          padding: 14px 16px; font-size: 13px; color: var(--body); margin: 0 0 16px; }
  .note.warn { background: var(--bad-bg); border-color: var(--bad-line); color: var(--bad-text); }
  .note.good { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-text); }
  .note ul { margin: 8px 0 0; padding-left: 18px; }
  .notice { background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px;
            padding: 20px 22px; font-size: 13px; color: var(--body); }
  .notice.bad { background: var(--bad-bg); border-color: var(--bad-line); color: var(--bad-text); }

  /* Team-scherm. Een uitgezet account blijft leesbaar maar mag de aandacht niet
     trekken: het staat er voor de historie, niet om iets mee te doen. */
  tr.uit td { color: var(--faint); }
  label.vink { display: flex; gap: 8px; align-items: center; font-weight: 400; }
  /* Een wachtwoord dat één keer getoond wordt, moet in één oogopslag over te
     nemen zijn, en niet te verwarren met de tekst eromheen. */
  code.wachtwoord { display: inline-block; font-size: 15px; letter-spacing: 0.5px;
                    background: var(--page); border: 1px solid var(--line-strong);
                    border-radius: 8px; padding: 8px 12px; user-select: all; }

  /* ── Team-scherm, opmaak ────────────────────────────────────────────────
   *
   * Dit scherm stond als twee kale '.card's op de pagina, met de inhoud er
   * rechtstreeks in. Dat werkte niet: '.card' zet zelf geen padding - die zit op
   * '> .head' en '> .body' - dus de tekst plakte tegen de rand en de marge van de
   * 'h2' viel dwars door de bovenrand heen. Vandaar dat het nu dezelfde
   * paneelopbouw gebruikt als het overzicht, waar die twee delen wél bestaan.
   */

  /* Een rij per lid: naam en adres links, de rest in vaste kolommen rechts.
     Een tabel gaf hier scheve kolommen zodra één naam lang was; een grid met
     vaste maten zet elke rij op dezelfde plek, ook als een cel leeg is. */
  .leden { display: flex; flex-direction: column; }
  .lid { display: grid; align-items: center; gap: 16px;
         grid-template-columns: minmax(0, 1fr) 132px 104px 108px auto;
         padding: 14px 20px; border-bottom: 1px solid rgb(16 24 40 / .055); }
  .lid:last-child { border-bottom: none; }
  .lid .wie { min-width: 0; }
  .lid .naam { font-weight: 600; font-size: 13.5px; color: var(--text);
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .lid .adres { font-size: 12px; color: var(--faint); margin-top: 2px;
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .lid .sinds { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
  /* De knoppen staan rechts en op één regel; bij een smal scherm mogen ze
     doorlopen naar de volgende in plaats van de kolom op te rekken. */
  .lid .acties { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
  .lid .acties form { margin: 0; }
  /* Een uitgezet lid: leesbaar, maar niet het eerste waar je oog op valt. */
  .lid.uit .naam, .lid.uit .adres { color: var(--faint); }
  .lid .zelf { font-size: 12px; color: var(--faint); text-align: right; }

  @media (max-width: 900px) {
    .lid { grid-template-columns: 1fr; gap: 8px; }
    .lid .acties, .lid .zelf { justify-content: flex-start; text-align: left; }
  }

  /* Het formulier: labels bóven de velden, in kolommen die meebewegen. Ze
     stonden ernaast doordat het label het veld omsloot - dan zet 'display:
     block' op het label niets recht, want het veld staat binnen die regel. */
  .veldrij { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
             gap: 14px 16px; margin-bottom: 14px; }
  .veld { display: flex; flex-direction: column; min-width: 0; }
  .veld label { margin: 0 0 6px; }
  .veld input { width: 100%; }

  /* ── Feedbackbord ──────────────────────────────────────────────────────── */
  .tabs { display: flex; gap: 6px; margin: 0 0 14px; }
  .tabs a { padding: 6px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
            text-decoration: none; color: var(--muted); border: 1px solid var(--line-strong);
            background: var(--card); }
  .tabs a.aan { color: #fff; background: var(--brand); border-color: var(--brand); }

  .post { display: flex; gap: 14px; background: var(--card); border: 1px solid var(--line-strong);
          border-radius: 12px; padding: 14px 16px; margin: 0 0 10px; }
  .post-body { flex: 1; min-width: 0; }
  .post-kop { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .post-kop .titel { font-size: 14px; font-weight: 700; color: var(--text); text-decoration: none; }
  .post-kop .titel:hover { text-decoration: underline; }
  .post-meta { font-size: 11.5px; color: var(--faint); margin-top: 3px; }
  .post-tekst { font-size: 13px; color: var(--body); margin: 8px 0 0; white-space: pre-wrap; }
  /* De stemknop is een knop en geen getal met een pijltje ernaast: waar je op
     kunt drukken moet eruitzien als iets waar je op drukt. */
  .stem { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 46px;
          padding: 6px 8px; border-radius: 10px; font-weight: 700; font-size: 13px;
          background: var(--card); border: 1px solid var(--line-strong); color: var(--body); }
  .stem span { font-size: 11px; line-height: 1; }
  .stem.aan { color: #fff; background: var(--brand); border-color: var(--brand); }
  .reacties { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
  /*
   * pre-wrap hoort op de tekst en niet op het blok eromheen.
   *
   * Stond hij op .reactie, dan telde de opmaak van de sjabloon zelf mee: de
   * regeleindes en de inspringing tússen de twee div's werden als witruimte
   * getekend, en dan staat er een gat van drie regels tussen een naam en wat
   * die persoon schreef. Zichtbaar zodra je de pagina in een browser opent, en
   * onzichtbaar zolang je alleen naar de code kijkt.
   */
  .reactie { margin-bottom: 10px; font-size: 13px; color: var(--body); }
  .reactie .tekst { white-space: pre-wrap; }
  .reactie .wie { font-size: 11px; color: var(--faint); margin-bottom: 2px; }

  .muted { color: var(--muted); }
  .small { font-size: 12.5px; }
  .mono, code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
  .link, a { color: var(--action); }
  .source { font-size: 11.5px; color: var(--faint); margin-top: 10px; }
  .source a { color: var(--action); text-decoration: none; }
  .icon { display: inline-flex; }
  .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: none; }
  .check { color: var(--ok-text); }
  .picker { display: flex; gap: 8px; align-items: center; }

  /* ── Beelden: varianten om uit te kiezen, en het afgemaakte resultaat ──── */
  .variants { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
              gap: 12px; }
  .variant { margin: 0; border: 1px solid var(--line-strong); border-radius: 12px;
             overflow: hidden; }
  /* De gekozen variant valt op met een rand en niet met een vinkje ergens:
     je kijkt naar de plaatjes, niet naar de tekst eronder. */
  .variant.chosen { border-color: var(--brand); box-shadow: 0 0 0 2px var(--info-bg); }
  .variant img { width: 100%; display: block; aspect-ratio: 1; object-fit: cover;
                 background: #f3f4f6; }
  .variant figcaption { padding: 10px; text-align: center; }
  .renders { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
             gap: 16px; }
  .render { border: 1px solid var(--line-strong); border-radius: 12px; overflow: hidden; }
  .render.chosen { border-color: var(--ok-text);
                   box-shadow: 0 0 0 2px var(--ok-bg); }
  .render .shot img { width: 100%; display: block; aspect-ratio: 1; object-fit: contain;
                      background: #f3f4f6; }
  .render .body { padding: 12px 14px; }
  .missing { aspect-ratio: 1; display: grid; place-items: center; color: var(--faint);
             font-size: 12px; background: #f3f4f6; }
  pre.brief { white-space: pre-wrap; font-family: ui-monospace, Menlo, monospace;
              font-size: 12.5px; line-height: 1.5; max-height: 26rem; overflow: auto;
              margin: 0; color: var(--body); }

  /* ── Het intakeformulier ───────────────────────────────────────────────── */
  /* Eén koppeling per blok, met de uitkomst van de controle eronder. */
  .block { border: 1px solid var(--line-strong); border-radius: 12px;
           padding: 4px 16px 16px; margin: 16px 0; }
  .hint { font-size: 12.5px; color: var(--muted); }
  /* Op het intakeformulier staat elk veld op een eigen regel en plakt de klant
     er lange waarden in: een shopdomein, een API-sleutel van veertig tekens. De
     browserstandaard is ongeveer twintig tekens breed, en dan zie je nooit wat
     je geplakt hebt. In de Console blijft de standaard gelden: daar staan
     invoervelden in tabellen, naast elkaar. */
  .block input { width: 100%; }
  .block label { display: block; margin-top: 14px; font-weight: 600; font-size: 13px; }
  .block .hint { margin: 2px 0 6px; }
  .block .error { margin-top: 6px; }

  /* Het merkje naast de naam van een koppeling: een letter in de kleur van die
     dienst. Geen nagetekend logo; zie de uitleg bij merk in providers.ts. */
  .blockhead { display: flex; align-items: center; gap: 10px; margin: 12px 0 2px; }
  .blockhead h2 { margin: 0; }
  .merk {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 8px; flex: 0 0 auto;
    color: #fff; font-size: 11px; font-weight: 700; letter-spacing: -.02em;
  }
  /* De uitleg binnen een blok heeft geen eigen streep nodig: het blok heeft al
     een rand, en twee lijnen onder elkaar leest als een fout. */
  .block .info { border-top: none; }
  .block .info > summary { padding: 4px 0 6px; }
  .block .info > p { padding: 0 0 8px; }
  .info.standalone { border: 1px solid var(--line-strong); border-radius: 12px; margin: 16px 0; }

  /* De achtergrond bij een kaart: dicht tenzij je hem opent.
     Geen script nodig; het details-element doet dit zelf. */
  .info { border-top: 1px solid var(--line); }
  .info > summary {
    cursor: pointer; list-style: none;
    padding: .5rem 1rem; font-size: 12.5px; color: var(--muted);
    display: flex; align-items: center; gap: .45rem;
  }
  .info > summary::-webkit-details-marker { display: none; }
  .info > summary:hover { color: var(--text); }
  .info > summary .i {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.05rem; height: 1.05rem; border-radius: 50%;
    border: 1px solid var(--line); font-size: 10.5px; font-style: italic;
    line-height: 1; flex: 0 0 auto;
  }
  .info[open] > summary { color: var(--text); }
  .info > p {
    margin: 0; padding: 0 1rem .9rem;
    font-size: 12.5px; line-height: 1.55; color: var(--muted); max-width: 62ch;
  }
  ul.results { list-style: none; padding: 0; margin: 0; }
  ul.results li { padding: 10px 0; border-bottom: 1px solid var(--line); }
  ul.results li:last-child { border-bottom: 0; }
  /* Los van .pill: hier staat de uitslag als woord in een zin, niet als label. */
  .ok { color: var(--ok-text); font-weight: 600; }
  .bad { color: var(--bad-text); font-weight: 600; }

  /* ── Inloggen ──────────────────────────────────────────────────────────── */
  .login-page { display: flex; align-items: center; justify-content: center;
                min-height: 100vh; padding: 24px; }
  .login { width: 100%; max-width: 360px; background: var(--card);
           border: 1px solid var(--line-strong); border-radius: 12px; padding: 28px; }
  .login .brand { padding: 0 0 16px; }
  /*
   * Een logo krijgt een donkere plaat onder zich.
   *
   * In de menubalk staat een logo op het verloop van de klant, en daar is het
   * op ontworpen: RX group levert een wit logo aan. Het inlogscherm is de enige
   * plek waar datzelfde bestand op de witte kaart terechtkomt, en dan staat er
   * een leeg vak waar zijn naam hoort. De plaat neemt de kleur van zijn menu
   * over (zie themeStyle); dit is de bodem voor wie geen menukleuren heeft.
   *
   * Alleen bij een logo: een merknaam als tekst gaat hier juist zwart op wit.
   */
  .login .brand.plaat { background: #101014; border-radius: 10px;
                        padding: 18px 20px; margin-bottom: 20px;
                        display: flex; justify-content: center; }
  .login button { width: 100%; margin-top: 20px; }
  .login label { margin-top: 16px; }
  .login input { width: 100%; }
  .error { background: var(--bad-bg); color: var(--bad-text); border: 1px solid var(--bad-line);
           border-radius: 10px; padding: 10px 14px; font-size: 13px; margin-top: 16px; }

  /*
   * De kolomkiezer van Main data, en het versheidsblok eronder.
   *
   * Een details-element en niet een uitklapmenu met script: het dashboard is
   * server-gerenderde HTML, en een kiezer die alleen werkt als er JavaScript
   * laadt, is een kiezer die soms niet werkt. Dichtgeklapt is het één regel;
   * open is het een formulier met vinkjes per groep.
   */
  .kiezer { margin: 0 0 14px; border: 1px solid var(--line-strong); border-radius: 10px;
            background: var(--card); }
  .kiezer > summary { padding: 10px 14px; cursor: pointer; font-size: 13px; font-weight: 600; }
  .kiezer > form, .kiezer > table { padding: 4px 14px 14px; }
  .kiezer > table { width: calc(100% - 28px); }
  .kiezer-groep { padding: 8px 0; border-top: 1px solid var(--line); }
  .kiezer-groep h4 { margin: 0 0 6px; font-size: 11.5px; text-transform: uppercase;
                     letter-spacing: .04em; color: var(--faint); }
  .vinkje { display: inline-flex; align-items: center; gap: 6px; margin: 0 14px 6px 0;
            font-size: 12.5px; white-space: nowrap; }
  .vinkje input { margin: 0; }
  .bijgewerkt { font-size: 12px; color: var(--faint); white-space: nowrap; margin-right: 10px; }

  /*
   * De filterbalk boven Main data.
   *
   * Zoeken doe je vaak en verwacht je meteen; kolommen kies je één keer. Vandaar
   * het zoekveld open in beeld en de kolommen achter een uitklapblok.
   */
  .filterbalk { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
  .filterbalk input[type="search"] { min-width: 280px; }
  .filterbalk input[type="text"] { min-width: 220px; }
  .filter-telling { font-size: 12.5px; color: var(--faint); }
  .presets { display: inline-flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
  .knoppenrij { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
  /*
   * Het gereedschap van Main data: vijf laatjes naast elkaar.
   *
   * Onder elkaar waren het vijf identieke regels die de tabel wegdrukten, en dan
   * leest "Columns (19 selected...)" als een kop boven de tabel in plaats van als
   * een knop die iets opent. 'auto-fit' zorgt dat ze op een smal scherm vanzelf
   * onder elkaar zakken; er is geen breekpunt dat iemand moet onderhouden.
   *
   * 'align-items: start' staat er omdat een open laatje anders zijn buren
   * even hoog maakt: vier lege vakken naast het ene dat je opendeed.
   */
  .kiezer-rij { display: grid; align-items: start; gap: 12px; margin-top: 16px;
                grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); }
  .kiezer-rij > .kiezer { margin: 0; }
  /* Een open laatje mag over zijn buren heen breed worden, anders past een
     kolomkiezer met vijftig vinkjes niet in een kolom van 250 pixels. */
  .kiezer-rij > .kiezer[open] { grid-column: 1 / -1; }
  .kop-sorteer { color: inherit; text-decoration: none; }
  .kop-sorteer:hover { color: var(--brand); }
  .eigen-kolom { display: flex; align-items: center; gap: 10px; padding: 4px 0;
                 font-size: 12.5px; }
  .eigen-kolom code { background: var(--page); padding: 2px 6px; border-radius: 4px; }
  button.link { background: none; border: 0; padding: 0; color: var(--bad-text);
                font-size: 12.5px; cursor: pointer; text-decoration: underline; }
  .kiezer select, .kiezer input[type="text"] { margin-right: 6px; }
  /*
   * Een link die zich als knop voordoet, hoort er ook uit te zien als een knop.
   *
   * Er stond alleen een '.ghost'-variant, dus 'Fill in or update keys' op
   * Settings was al die tijd een onderstreepte regel tekst tussen twee alinea's
   * in - precies de knop die het meest gedrukt moet worden op dat scherm.
   */
  .button { display: inline-block; padding: 9px 16px; border-radius: 9px;
            border: 1px solid var(--action); background: var(--action); color: #fff;
            font-size: 13px; font-weight: 600; text-decoration: none; cursor: pointer; }
  .button:hover { background: var(--action-hover); border-color: var(--action-hover);
                  text-decoration: none; }
  .button.ghost { background: var(--card); color: var(--body);
                  border: 1px solid var(--line-strong); }
  .button.ghost:hover { border-color: var(--brand); color: var(--brand); }

  /*
   * Eén rij is één regel.
   *
   * Een producttitel van tachtig tekens brak een rij in drieën, en dan loopt je
   * oog bij vijftig kolommen niet meer recht. De tabel schuift al horizontaal,
   * dus afkappen kost niets: de hele waarde staat in de tooltip van de cel en in
   * de export.
   */
  .card.rijen td, .card.rijen th { white-space: nowrap; vertical-align: middle; }
  .card.rijen td { max-width: 320px; overflow: hidden; text-overflow: ellipsis; }
  /*
   * De periodeknoppen boven het overzicht. Links en geen vinkjes: één klik moet
   * genoeg zijn, en het adres draagt de staat zodat een scherm deelbaar blijft.
   */
  .periodes { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
  .periodes-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;
                    color: var(--faint); margin-right: 2px; }
  .periode-knop { display: inline-block; padding: 5px 12px; border-radius: 999px;
                  border: 1px solid var(--line-strong); background: var(--card);
                  font-size: 12.5px; font-weight: 600; text-decoration: none;
                  color: var(--faint); }
  .periode-knop:hover { border-color: var(--brand); color: var(--text); }
  .periode-knop.aan { background: var(--brand); border-color: var(--brand); color: #fff; }

  /*
   * De weekpresentatie: de knop boven het overzicht en het paneel eronder.
   *
   * Het paneel staat er alleen als het adres erom vraagt, dus hier hoeft niets
   * verborgen te worden. Wat hier wel toe doet is de uitlijning: de vinkjes
   * staan in een raster dat meebeweegt (twee kolommen op een laptop, één op een
   * telefoon) in plaats van in blokjes van 48% die op een halve regel eindigen.
   * De labels staan bóven hun veld, zoals op het Team-scherm, zodat de kolom
   * links van de velden niet elke regel een andere breedte heeft.
   */
  .presentatie { margin: -6px 0 18px; }
  /*
   * De downloadknop staat in de periodenrij, rechts van "Custom range".
   *
   * Hij hoort bij die keuze: wat je downloadt is de periode die daar aanstaat.
   * Als eigen blok eronder las hij als een losse actie, en dan is niet te zien
   * dat de knop ernaast bepaalt wat erin komt. Vandaar dezelfde vorm als de
   * periodeknoppen, met een streep ervoor die de twee groepen scheidt.
   */
  .periodes .periode-knop.dl { margin-left: 10px; border-left-width: 1px;
                               background: var(--action); border-color: var(--action);
                               color: #fff; }
  .periodes .periode-knop.dl:hover { background: var(--action-hover);
                                     border-color: var(--action-hover); color: #fff; }

  .pres-dagen { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
                margin-top: 10px; }
  .pres-dag { display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px;
              border: 1px solid var(--line-strong); border-radius: 999px;
              font-size: 12.5px; color: var(--body); }
  .pres-dag input { margin: 0; }
  .pres-tijd { margin-left: 8px; font-size: 12.5px; color: var(--faint); }
  .pres-dagen input[type=time] { padding: 5px 8px; border-radius: 8px;
                                 border: 1px solid var(--line-strong);
                                 background: var(--card); color: var(--text);
                                 font-size: 12.5px; }
  .presentatie-paneel textarea { width: 100%; padding: 8px 10px; border-radius: 8px;
                                 border: 1px solid var(--line-strong); background: var(--card);
                                 color: var(--text); font: inherit; font-size: 13px;
                                 resize: vertical; }

  .presentatie-paneel { margin-top: 12px; padding: 18px 20px 16px; border-radius: 12px;
                        border: 1px solid var(--line); background: var(--card);
                        max-width: 620px; }
  /*
   * De titel met het i-knopje erin, en niet ernaast in een flexrij.
   *
   * Dat scheelde een fout die alleen zichtbaar was mét de uitleg open: de
   * uitklaptekst is een blok, en als flex-item duwde die de titel in drie
   * smalle regels. Binnen de titel valt het blok gewoon onder de kop, over de
   * volle breedte van het paneel.
   */
  .pres-kop { margin: 0 0 16px; }
  .pres-kop h3 { margin: 0; font-size: 13px; font-weight: 650; color: var(--text); }

  .pres-veld { border: 0; padding: 0; margin: 0 0 16px; }
  /*
   * Alleen de veldnamen in kapitalen, niet elk label.
   *
   * Een vinkje binnen een veldblok is ook een label, en dat kreeg dezelfde
   * behandeling: "STUUR DE PRESENTATIE AUTOMATISCH" leest als een kop terwijl
   * het een keuze is. Vandaar de uitzondering op de vinkjes.
   */
  .pres-veld > label:not(.pres-vink), .pres-veld > legend {
    display: block; padding: 0 0 6px; font-size: 11.5px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .04em; color: var(--faint); }
  .pres-veld > .pres-vink { margin-bottom: 2px; }
  .pres-veld select { width: 100%; max-width: 260px; padding: 7px 10px; border-radius: 8px;
                      border: 1px solid var(--line-strong); background: var(--card);
                      color: var(--text); font-size: 13px; }

  /*
   * Twee kolommen die van boven naar beneden lopen, en niet van links naar
   * rechts. De volgorde van de vinkjes is de volgorde van de dia's; bij
   * rijgewijs vullen staat pagina 2 rechtsboven naast pagina 1, en dan is aan
   * de lijst niet meer af te lezen in welke volgorde de presentatie komt.
   */
  .pres-vinkjes { display: grid; grid-auto-flow: column;
                  grid-template-columns: repeat(2, minmax(0, 1fr));
                  grid-template-rows: repeat(4, auto); gap: 8px 20px; }
  .pres-vink { display: flex; align-items: center; gap: 8px; font-size: 13px;
               color: var(--body); min-width: 0; }
  .pres-vink input { flex: none; margin: 0; }
  .pres-vink span { min-width: 0; overflow: hidden; text-overflow: ellipsis;
                    white-space: nowrap; }

  .pres-voet { display: flex; justify-content: flex-end;
               border-top: 1px solid var(--line); padding-top: 14px; }

  @media (max-width: 42rem) {
    .pres-vinkjes { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr);
                    grid-template-rows: none; }
    .pres-voet { justify-content: stretch; }
    .pres-voet .button { width: 100%; text-align: center; }
  }

  /* Eén blok per periode op het overzicht: kop, tegels, tabel. */
  .periode { margin: 0 0 26px; }
  .periode > h2 { display: flex; align-items: baseline; gap: 10px; margin: 0 0 10px; }
  .periode-dagen { font-size: 12px; font-weight: 500; color: var(--faint); }
  .kiezer button { margin-top: 12px; }

  @media (max-width: 52rem) {
    .shell { display: block; }
    .sidebar { width: auto; height: auto; position: static; border-right: 0;
               border-bottom: 1px solid var(--line); }
    nav { flex-direction: row; flex-wrap: wrap; }
    .spacer { display: none; }
    main { padding: 20px 16px 40px; }
  }

  /* ── Glas ──────────────────────────────────────────────────────────────
   *
   * Een laag glas op een gekleurde ondergrond. Kaarten op vlak grijs lezen als
   * losse vellen papier, kaarten op een kleurverloop als één scherm - dus dit
   * hoort bij een scherm dat uit kaarten bestaat, en niet bij een scherm dat uit
   * een tabel bestaat, waar het alleen leesbaarheid kost.
   *
   * Dit stond op '.overzicht' en gold daarmee voor precies één scherm. Het is nu
   * een eigen klasse omdat het Team-scherm er ook om vroeg, en de keuze die
   * eronder ligt is niet veranderd: een scherm krijgt dit doordat het zichzelf
   * '.glas' noemt, nooit doordat het toevallig in de buurt staat. Dat is dezelfde
   * grendel als eerst, alleen niet langer aan één schermnaam vastgeknoopt.
   *
   * De ondergrond zit op '.glas::before' en niet op 'body': zo raakt hij geen
   * enkel scherm dat er niet om vraagt, en blijft de menubalk zijn eigen
   * achtergrond houden.
   */
  .glas { position: relative; }
  .glas::before {
    content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
      radial-gradient(900px 520px at 12% -6%, rgb(46 107 255 / .10), transparent 62%),
      radial-gradient(760px 460px at 92% 4%, rgb(122 90 248 / .09), transparent 60%),
      radial-gradient(700px 500px at 60% 100%, rgb(18 183 106 / .06), transparent 60%),
      #eef1f6;
  }

  /* Eén definitie voor alles wat op zo'n scherm van glas is. Zonder
     'backdrop-filter' (oudere browsers) blijft er een lichte kaart staan: de
     achtergrond is dan minder mooi, nooit onleesbaar. */
  /*
   * Een tabel op glas blijft ondoorzichtig.
   *
   * De rest van een glasscherm is halfdoorzichtig; een tabel met vijftig
   * kolommen is dat met opzet niet. Daar is de leesbaarheid van een cel het
   * enige dat telt, en een verloop dat er doorheen schijnt kost precies dat.
   */
  .glas .card { background: var(--card); border-color: rgb(255 255 255 / .75);
                border-radius: 16px;
                box-shadow: 0 1px 2px rgb(16 24 40 / .04), 0 8px 24px rgb(16 24 40 / .055); }
  .glas .kiezer { background: rgb(255 255 255 / .66); border-color: rgb(255 255 255 / .75);
                  border-radius: 12px; }

  .glas .stat-kaart,
  .glas .paneel-kaart,
  .glas .kanaal,
  .glas .merkstand > div,
  .glas .lijst {
    background: rgb(255 255 255 / .66);
    border: 1px solid rgb(255 255 255 / .75);
    border-radius: 16px;
    box-shadow: 0 1px 2px rgb(16 24 40 / .04), 0 8px 24px rgb(16 24 40 / .055);
    backdrop-filter: blur(18px) saturate(165%);
    -webkit-backdrop-filter: blur(18px) saturate(165%);
  }

  /* ── De periodekiezer ─────────────────────────────────────────────────
   *
   * Eén periode tegelijk. Elke knop is een link met de hele staat in het adres,
   * dus een scherm blijft deelbaar en de terugknop doet wat je verwacht. Het
   * eigen bereik is het enige dat je invult in plaats van aanwijst, en staat
   * daarom als formulier achteraan.
   */
  .periodes { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 0 0 20px; }
  .periode-knop { display: inline-block; padding: 7px 13px; border-radius: 9px;
                  border: 1px solid rgb(255 255 255 / .75); background: rgb(255 255 255 / .6);
                  font-size: 13px; font-weight: 500; text-decoration: none;
                  color: var(--body); cursor: pointer; font-family: inherit;
                  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
  .periode-knop:hover { border-color: var(--action); color: var(--text); }
  .periode-knop:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; }
  .periode-knop.aan { background: var(--action); border-color: var(--action); color: #fff; }
  /* De twee datumvelden mogen vouwen, net als de knoppenrij eromheen.
   *
   * De rij .periodes wrapt al, maar dit formulier is één flexregel die dat niet
   * deed: gemeten op 2026-09-12 is hij 377 punten breed, en op een scherm van
   * 390 duwde hij de hele pagina naar 397 -- een horizontale schuifbalk op het
   * scherm dat het vaakst geopend wordt. Dezelfde fout als de tabbladenbalk en
   * de knoppenrij van de promotie-update op 2026-09-07: een rij die niet kan
   * vouwen.
   *
   * Let op: geen backticks in dit commentaar. Het staat in de template-string
   * waar de hele stylesheet in zit, en een backtick sluit hem -- dat staat in
   * CLAUDE.md en het is hier meteen gebeurd.
   *
   * De min-width van nul is nodig omdat een flex-item standaard niet kleiner
   * wordt dan zijn inhoud; zonder dat blijft een datumveld zijn eigen breedte
   * opeisen en helpt het vouwen niets. */
  .eigen-periode { display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
                   margin-left: 4px; min-width: 0; }
  .eigen-periode input[type=date] { min-width: 0; }
  .eigen-periode input[type=date] {
    font: inherit; font-size: 13px; color: var(--body);
    background: rgb(255 255 255 / .6); border: 1px solid rgb(255 255 255 / .75);
    border-radius: 9px; padding: 6px 9px;
  }
  .eigen-periode .tot { font-size: 12px; color: var(--faint); }
  /* Voor een schermlezer moet er een label staan; op het scherm zegt de knop
     ernaast al waar de twee velden voor zijn. */
  .visueel-verborgen { position: absolute; width: 1px; height: 1px; overflow: hidden;
                       clip-path: inset(50%); white-space: nowrap; }

  /* ── Uitleg en feedback achter één 'i' ────────────────────────────────
   *
   * Een 'details' en geen dialoogvenster: dit scherm laadt geen JavaScript, en
   * open-en-dicht is precies waar dat element voor is.
   */
  .scherm-info { position: relative; margin: -6px 0 14px; }
  /*
   * Naast de titel, niet eronder.
   *
   * Elk scherm zette de i als eerste element in zijn eigen body, en dan hangt
   * hij onder de kop -- op elk scherm net iets anders ingesprongen, en boven de
   * eerste kaart als een losse letter zonder aanleiding. Hij hoort bij de naam
   * van het scherm; in de kop staat hij op elke pagina op dezelfde plek.
   *
   * De marge gaat hier terug naar nul: die -6px was er om het gat onder de kop
   * dicht te trekken, en in de kop zelf duwt hij de i scheef.
   */
  .kop-titel { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .kop-titel h1 { margin: 0; }
  .kop-titel .scherm-info { margin: 0; }
  .scherm-info > summary { display: inline-flex; align-items: center; justify-content: center;
       width: 22px; height: 22px; border-radius: 50%; background: rgb(255 255 255 / .6);
       border: 1px solid rgb(255 255 255 / .75); color: var(--muted);
       font-size: 12px; font-weight: 700; font-style: italic; cursor: pointer;
       list-style: none; }
  .scherm-info > summary::-webkit-details-marker { display: none; }
  .scherm-info > summary:hover { color: var(--action); border-color: var(--action); }
  .scherm-info > summary:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; }
  /*
   * Het uitklapvenster draagt zijn eigen achtergrond.
   *
   * Hij hing aan de glas-variant van deze klasse, en dat werkte zolang de i binnen
   * het scherm stond. Sinds hij in de kop staat -- buiten die laag -- viel die
   * regel weg en was het venster doorzichtig: de tabel eronder las dwars door
   * de uitleg heen. Een venster dat over de pagina heen komt te staan, hoort
   * zijn ondergrond niet van zijn omgeving te lenen.
   */
  .scherm-info .paneel { position: absolute; z-index: 20; margin-top: 8px;
       width: min(560px, calc(100vw - 60px)); padding: 18px 20px;
       background: rgb(255 255 255 / .92); border: 1px solid var(--line);
       border-radius: 16px;
       box-shadow: 0 1px 2px rgb(16 24 40 / .04), 0 12px 32px rgb(16 24 40 / .12);
       backdrop-filter: blur(18px) saturate(165%);
       -webkit-backdrop-filter: blur(18px) saturate(165%); }
  .scherm-info .paneel h3 { font-size: 14px; font-weight: 600; margin: 0 0 6px; }
  .scherm-info .paneel h3 + p { margin-top: 0; }
  .scherm-info .paneel p { font-size: 13px; color: var(--body); line-height: 1.6; margin: 0 0 14px; }
  .scherm-info .paneel dl { margin: 0 0 16px; font-size: 13px; }
  .scherm-info .paneel dt { font-weight: 600; color: var(--text); }
  .scherm-info .paneel dd { margin: 2px 0 10px; color: var(--body); line-height: 1.55; }
  .scherm-info .paneel label { display: block; font-size: 12px; font-weight: 500;
       color: var(--muted); margin: 0 0 4px; }
  .scherm-info .paneel input[type=text], .scherm-info .paneel textarea {
       font: inherit; font-size: 13px; width: 100%; margin-bottom: 12px;
       border: 1px solid var(--line-strong); border-radius: 9px; padding: 8px 10px;
       background: rgb(255 255 255 / .7); color: var(--text); }
  .scherm-info .paneel button { font: inherit; font-size: 13px; font-weight: 600; color: #fff;
       background: var(--action); border: 1px solid var(--action); border-radius: 9px;
       padding: 9px 16px; cursor: pointer; }
  .scherm-info .paneel button:hover { background: var(--action-hover); }

  /* ── De statkaarten ───────────────────────────────────────────────────
   *
   * Vijf totalen boven de kanalen: de eerste vraag is "hoeveel", de tweede
   * "waar vandaan". Het verschil met de vorige periode staat eronder, want een
   * bedrag zonder richting zegt niets.
   */
  .stat-rij { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
              gap: 16px; margin-bottom: 20px; }
  .stat-kaart { padding: 18px 20px; display: flex; flex-direction: column; gap: 12px; }
  .stat-kaart .top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
  .stat-kaart .k { font-size: 13px; color: var(--muted); font-weight: 500;
                   display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
  .stat-kaart .ico { width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
                     display: flex; align-items: center; justify-content: center; }
  .stat-kaart .v { font-size: 28px; font-weight: 700; line-height: 1.1;
                   letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
  .stat-kaart .v.leeg { font-size: 17px; font-weight: 500; color: var(--faint); letter-spacing: 0; }
  /* Een datum of een tijdstip is geen getal om in één oogopslag te lezen; op 28
     pixels wordt het een kop die de kaart ernaast overschreeuwt. */
  .stat-kaart .v.kort { font-size: 19px; letter-spacing: 0; }
  .stat-kaart .onderrand { font-size: 12.5px; display: flex; align-items: center;
                           gap: 6px; flex-wrap: wrap; min-height: 19px; }
  .stat-kaart .onderrand .s { color: var(--faint); }
  .stat-kaart .badge { background: var(--warn-bg); color: var(--warn-text);
                       font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 5px; }
  /* Groen is niet altijd omhoog: bij advertentiekosten, TACOS en retouren is
     stijgen juist slecht, en dat bepaalt de aanroeper. */
  .delta { font-weight: 600; }
  .delta.op { color: #12b76a; }
  .delta.neer { color: #f04438; }

  /* ── De grafiek en de verdeling ───────────────────────────────────────── */
  .twee-kolommen { display: grid; grid-template-columns: 1.55fr 1fr; gap: 20px; margin-bottom: 4px; }
  .paneel-kop { display: flex; align-items: center; justify-content: space-between;
                gap: 12px; padding: 16px 20px; border-bottom: 1px solid rgb(16 24 40 / .055);
                flex-wrap: wrap; }
  .paneel-kop h2 { font-size: 15px; font-weight: 600; color: var(--text); }
  .paneel-kop .bij { font-size: 12px; color: var(--faint); }
  .paneel-lijf { padding: 20px; }

  /*
   * Het feedbackbord in de vorm van het overzicht.
   *
   * De berichten stonden als losse kaartjes onder elkaar; binnen een paneel is
   * dat een kaart in een kaart. Ze worden hier rijen met een scheidingslijn,
   * net als de leden op het Team-scherm - dezelfde vorm voor dezelfde soort
   * lijst, zodat je niet per scherm opnieuw hoeft te leren waar je kijkt.
   */
  /*
   * De Review Monitor.
   *
   * Eén klacht is een blok en geen tabelrij: de tekst is het belangrijkste wat
   * er staat, en die past niet in een kolom van 360 pixels zonder afgekapt te
   * worden. Bij WDM stond hij in een tabel met een tooltip; dan moet je ergens
   * overheen hangen om te kunnen lezen waar het over gaat.
   */
  /*
   * De selectiebalk boven de tabel.
   *
   * "Alles aanvinken" is een link en geen vinkje: zonder JavaScript kan de
   * browser andere vakjes niet aanzetten, dus doet de server het. Gevolg dat
   * meevalt: de selectie staat in het adres en is daarmee deelbaar, net als de
   * filters.
   */
  /*
   * Het uitgeklapte product op Monthly issues.
   *
   * Drie vakken naast elkaar, één per bron. Niet op één hoop: wat een koper
   * opschrijft bij een retour is iets anders dan wat hij in een beoordeling
   * zet, en een klantvraag is weer iets anders. Ze samenvoegen zou van drie
   * gesprekken één lijst maken.
   */
  .ean-link { color: var(--brand); text-decoration: none; font-weight: 600; }
  .ean-link:hover { text-decoration: underline; }
  tr.aan > td { background: rgb(46 107 255 / .04); }
  /* Drie naast elkaar zolang ze passen, en anders eronder.

     'auto-fit' met een minimum van 260 pixels: bij een blok van 900 pixels
     staan er drie naast elkaar, bij 600 twee en op een telefoon één. Ze delen
     de ruimte gelijk ('1fr'), dus ze bewegen mee met het venster in plaats van
     op een vaste maat te blijven staan. */
  .detail-vakken { display: grid; gap: 14px;
                   grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

  /*
   * De vakken van Branded shelves hebben een hogere ondergrens.
   *
   * Dat scherm zet drie tabellen met cijferkolommen naast elkaar, en die vragen
   * meer ruimte dan de signaalvakken van Monthly issues. Gemeten op 1280
   * punten met de gegevens van R2B: bij minmax(260px) is elk vak 279 pixels
   * breed terwijl de tabel erin er 530 tot 563 nodig heeft -- dus schoof elk van
   * de drie afzonderlijk, en dan staat in elke cel een afkapping in plaats van
   * een gegeven.
   *
   * 520 is de gemeten ondergrens. auto-fit en geen vast aantal, dus op een breed
   * scherm komen ze alsnog naast elkaar en op een smal onder elkaar.
   *
   * De min() eromheen is niet decoratief: een kale minmax(520px, 1fr) maakt de
   * kolom 520 breed ook als het vak zelf smaller is, en dan steekt de inhoud er
   * juist uit. Gemeten in een venster waar de kaart 563 punten breed was: vak
   * 518 in een houder van 491, en twee van de drie tabellen schoven alsnog. */
  .shelf-vakken { grid-template-columns: repeat(auto-fit, minmax(min(520px, 100%), 1fr)); }
  /* Een tabel in zo'n vak mag zijn vak niet oprekken, en zijn tekst mag afbreken.

     Let op waar die tweede regel vandaan komt: '.card.rijen td' zet
     'white-space: nowrap' met 'overflow: hidden' en 'text-overflow: ellipsis',
     om lange productnamen in de hoofdtabel af te kappen. Die regel gold ook
     voor de cellen van deze tabellen, want ze staan binnen diezelfde kaart -- en
     dan wordt elke datum '2026-...' en elke reden 'reden ...'. Een detailblok
     is er juist om te lezen wat er staat. */
  /* Elk vak is zijn eigen schuifgebied, en elke rij is één regel.

     Op verzoek van de eigenaar: de rijen liepen over drie regels en een blok
     werd daardoor honderden pixels hoog, terwijl je juist snel wilt zien wát er
     speelt. Nu leest elke rij als één regel en schuif je horizontaal als hij
     niet past.

     De 'min-width: 0' stond er al voor de grid, en hij is precies de
     voorwaarde waaronder 'overflow-x' hier werkt: zonder dat groeit een
     grid-item mee met zijn inhoud en komt er nooit een schuifbalk.

     Dit botst niet met de sticky-regel van dit scherm. Het sticky element is
     '.detail-inhoud', en dat hangt aan de schuivende '.card.scroll.rijen'
     erboven; '.detail-blok' is een afstammeling daarvan en geen voorouder, dus
     een schuifgebied hier verandert niets aan waar die zich aan vasthaakt. En
     'tr.detail > td.detail' blijft op 'overflow: visible' -- daar komt niets
     aan. */
  .detail-blok { min-width: 0; overflow-x: auto; }
  .detail-blok table.losse { table-layout: auto; width: max-content; min-width: 100%; }
  .detail-blok table.losse td, .detail-blok table.losse th {
    white-space: nowrap; overflow: visible; text-overflow: clip; max-width: none;
    vertical-align: top; }
  /* De eerste kolom draagt de datum met de bron eronder: smal en niet afbrekend. */
  .detail-blok table.losse td.wanneer, .detail-blok table.losse th.wanneer { width: 86px; }
  .detail-blok table.losse td.wanneer .bronpil { margin: 2px 0 0; display: inline-block; }
  .detail-blok table.losse td.dat { white-space: nowrap; }
  /* De tekst van een koper is drie regels, met de rest in de tooltip.

     Zonder grens wordt één klantvraag van driehonderd tekens twintig regels
     hoog, en dan is het blok 2.793 pixels en scrol je door één product heen.
     Wat dit scherm moet doen is laten zien wát er speelt, zodat je kunt kiezen
     waar je in duikt; de volle tekst staat in de tooltip, op de Klantvragen- en
     Retouren-pagina, en in de export. Afkappen mag hier dus, en alleen hier. */
  /* De klem staat op een blok ín de cel en niet op de cel zelf: een 'td' die
     zijn eigen overflow regelt is geen tabelcel meer, en dan loopt zijn tekst
     het vak naast zich in. Gemeten: de laatste kolom liep over de rand van zijn
     blok.

     De max-width is de grendel die het schuiven werkbaar houdt. Gemeten komt de
     zwaarste koperstekst op 3,6k tekens; zonder plafond wordt het schuifgebied
     tienduizenden pixels breed en schuift niemand ooit naar de tweede regel.
     Er verdwijnt niets: de volle tekst staat als tooltip op de cel, en verder op
     de Klantvragen- en Retouren-pagina en in de export. */
  .detail-blok table.losse td.tekst > .knip { display: block; white-space: nowrap;
                                              overflow: hidden; text-overflow: ellipsis;
                                              max-width: 420px; }
  .detail-blok { background: var(--card); border: 1px solid var(--line-strong);
                 border-radius: 10px; padding: 12px 14px; }
  .detail-kop { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
  .detail-kop .s { color: var(--faint); font-weight: 500; }
  .detail-item { font-size: 12.5px; color: var(--body); margin-bottom: 10px;
                 white-space: pre-wrap; }
  .detail-item:last-child { margin-bottom: 0; }
  .detail-item .wie { font-size: 11px; color: var(--faint); margin-bottom: 2px;
                      white-space: normal; }
  .detail-item .en { color: var(--muted); font-style: italic; margin-top: 2px; }
  /*
   * Waar een signaal vandaan komt, als klein label bij de datum.
   *
   * Op Monthly issues staan de retouren van bol en van de webshop in hetzelfde
   * vak, en de klantvragen van bol en van de helpdesk ook. Zonder dit label is
   * niet te zien welke regel waarvandaan komt, en dat is precies de vraag die
   * de uitklap hoort te beantwoorden.
   */
  .bronpil { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 8px;
             background: var(--line); color: var(--muted); font-size: 10px; font-weight: 600;
             text-transform: uppercase; letter-spacing: .3px; vertical-align: 1px; }

  /*
   * De redenen van één product, met hun aandeel.
   *
   * Een balk en niet alleen een getal: "18 keer verkeerde maat" zegt weinig
   * zonder te weten of dat de helft of een tiende van de retouren is. De vraag
   * bij een uitgeklapt product is waaróm, en een verhouding beantwoordt die
   * sneller dan een kolom cijfers.
   */
  .redenen { display: flex; flex-direction: column; gap: 8px; }
  .reden-regel { display: grid; align-items: center; gap: 10px;
                 grid-template-columns: minmax(0, 1fr) 160px 44px 46px; font-size: 12.5px; }
  .reden-regel .label { color: var(--body); overflow: hidden; text-overflow: ellipsis;
                        white-space: nowrap; }
  .reden-regel .balk { height: 8px; border-radius: 999px; background: var(--line);
                       overflow: hidden; }
  .reden-regel .balk > span { display: block; height: 100%; background: var(--brand);
                              border-radius: 999px; }
  .reden-regel .num { text-align: right; font-weight: 600; color: var(--text); }
  .reden-regel .pct { text-align: right; color: var(--faint); }

  .vinkjes { display: flex; flex-wrap: wrap; gap: 14px; }

  /*
   * De uitgeklapte retouren, als rijen in dezelfde tabel.
   *
   * Iets lichter en met een streep links, zodat je ziet dat ze bij de regel
   * erboven horen - maar in dezelfde kolommen, want dat is het punt: de maand
   * waarin een retour viel staat in dezelfde kolom als de telling erboven.
   */
  /*
   * Een kolomkop waar je op kunt klikken, met zijn paneel eronder.
   *
   * Zonder JavaScript: de kop is een link die zichzelf in het adres zet, en het
   * paneel is gewoon opmaak die er dan bij staat. Absoluut gepositioneerd, want
   * anders duwt hij de hele kopregel hoger en verspringt de tabel bij elke klik.
   */
  th.kop { position: relative; white-space: nowrap; }
  th.kop > a { color: inherit; text-decoration: none; display: inline-block; }
  th.kop > a:hover { color: var(--action); }
  th.kop.open > a { color: var(--action); }
  th.kop .onder { display: block; font-weight: 500; font-size: 11px;
                  color: var(--muted); letter-spacing: 0; }
  th.kop.num .onder { text-align: right; }
  .kop-paneel { position: absolute; z-index: 40; top: 100%; left: 0; min-width: 220px;
                margin-top: 4px; padding: 12px; text-align: left; font-weight: 400;
                background: var(--card); border: 1px solid var(--line-strong);
                border-radius: 10px; box-shadow: 0 12px 32px rgb(16 24 40 / .16); }
  .kop-paneel .kop-sorteer { display: flex; flex-direction: column; gap: 6px;
                             padding-bottom: 10px; margin-bottom: 10px;
                             border-bottom: 1px solid var(--line); }
  .kop-paneel a { font-size: 12px; }
  .kop-paneel form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
  .kop-paneel select, .kop-paneel input { font-size: 12px; padding: 5px 8px; }
  .kop-paneel .kop-label { font-size: 12px; color: var(--muted); }
  .kop-paneel .kop-sluit { display: block; margin-top: 10px; color: var(--muted); }
  .kop-filter-rij { font-size: 12px; }

  /*
   * De hele rij is de link, cel voor cel.
   *
   * Een tabelrij neemt geen adres en een link over meerdere cellen is geen
   * geldige HTML, dus krijgt elke cel er zelf een die hem vult. Zo is de rij
   * aanklikbaar én blijft hij met het toetsenbord te bedienen.
   */
  /* Op '.rijlink' en niet op 'a.rijlink'.

     Op een scherm dat uitklapt zonder te herladen is elke cel een 'label' bij
     het vinkje van die rij en geen anker. Die selector greep dus niets, en dan
     valt het label terug op zijn eigen afmeting: gemeten op Monthly issues 51
     bij 15 pixels in een cel van 75 bij 45. Wie in de rand van een cel klikte,
     klikte naast. Het gold ook op Retouren, dat dezelfde constructie draagt. */
  td > .rijlink { display: block; color: inherit; text-decoration: none;
                  margin: -10px -14px; padding: 10px 14px; }
  td.num > .rijlink { text-align: right; }
  tr:hover td > .rijlink { color: inherit; }

  /* ── Een rij die opengaat ──────────────────────────────────────────────
   *
   * Het pijltje zegt dat er iets achter zit. Zonder was de rij aanklikbaar maar
   * zag je dat alleen door het te proberen; de cursor verandert wel, maar dat is
   * op een tabel waar élke cel een link is geen onderscheid.
   *
   * Draaien in plaats van van teken wisselen: één vorm die kantelt leest als één
   * ding dat opengaat. En de overgang is er alleen voor wie hem wil zien -- een
   * gebruiker die beweging heeft uitgezet krijgt hem meteen in de eindstand. */
  td.metchev > .rijlink { display: flex; align-items: center; gap: 7px; }
  /* Een rij zonder uitklapblok houdt dezelfde inspringing als de rest, zodat de
     EANs onder elkaar staan. Alleen het pijltje ontbreekt: er is niets achter.

     Geen 'display: flex' op de cel zelf -- een 'td' die flexbox wordt, is geen
     tabelcel meer en trekt de kolombreedtes scheef. Een leeg blokje van dezelfde
     maat doet hetzelfde zonder dat risico. */
  .chev.leeg { display: inline-block; width: 14px; margin-right: 7px;
               vertical-align: middle; }

  /* ── Uitklappen zonder de pagina opnieuw te laden ──────────────────────
   *
   * Het vinkje in de EAN-cel is de schakelaar; elke cel van die rij is er een
   * label bij. Het vinkje zelf staat buiten beeld -- weghalen met
   * 'display: none' zou het ook uit de toetsenbordvolgorde halen, en dan is de
   * rij niet meer met tab en spatie te openen.
   *
   * De detailrij hoort bij de rij ervóór, dus ':has() +'. Dat vraagt een browser
   * van 2023 of nieuwer; is die er niet, dan staat elk blok gewoon open in
   * plaats van dicht. Dat is de goede kant om op te falen: alles te zien is
   * hinderlijk, niets kunnen openen is onbruikbaar.
   *
   * En let op wat er in zo'n commentaar staat: dit blok belandt letterlijk in
   * het style-element van elke pagina. Een test die controleert dat de
   * runhistorie van een andere klant er niet in staat, viel om op één woord uit
   * de tekst hierboven. */
  /* De pijl hangt aan de kolomnaam vast zonder deze ruimte. */
  .sorteerpijl { margin-left: 5px; color: var(--brand); }

  /* Een klacht die bij een zustervariant hoort. Geen foutkleur: er gaat niets
     mis, we weten alleen niet bij welk artikel hij hoort. */
  .variantklacht { font-size: 11.5px; color: var(--muted); background: var(--page);
                   border: 1px solid var(--line); border-radius: 999px;
                   padding: 1px 8px; white-space: nowrap; }

  .uitklapper { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
  .uitklapper:focus-visible + .chev { outline: 2px solid var(--brand); outline-offset: 2px;
                                      border-radius: 3px; }
  tr.rij:has(.uitklapper:checked) > td { background: rgb(46 107 255 / .04); }
  tr.rij:has(.uitklapper:checked) .chev { color: var(--brand); transform: rotate(90deg); }
  @supports selector(tr:has(input)) {
    tr.detail { display: none; }
    tr.rij:has(.uitklapper:checked) + tr.detail { display: table-row; }
  }
  .chev { color: var(--faint); flex-shrink: 0; line-height: 0; display: inline-block;
          transform: rotate(0deg); transition: transform .15s ease; }
  tr:hover .chev { color: var(--brand); }
  @media (prefers-reduced-motion: reduce) { .chev { transition: none; } }

  /* ── Het uitgeklapte product, als rij ín de tabel ───────────────────────
   *
   * De rij is zo breed als de tabel, en die schuift horizontaal: twaalf
   * maandkolommen plus een kolom per kanaal passen niet op een scherm. Zonder
   * verdere maatregel schuift de inhoud van dit blok mee naar links uit beeld
   * zodra iemand naar de rechterkolommen kijkt.
   *
   * Vandaar 'position: sticky' op het blok binnenín de cel: de cel blijft zo
   * breed als de tabel, de inhoud plakt aan de linkerrand van wat je ziet. Dat
   * is dezelfde afweging die dit blok ooit bóven de tabel zette; hier is hij
   * opgelost in plaats van omzeild. */
  /* De 'overflow: visible' hier is geen opmaak maar de voorwaarde: '.card.rijen
     td' zet 'overflow: hidden' om lange productnamen af te kappen, en een
     voorouder met een andere overflow dan 'visible' wordt zélf het venster waar
     'sticky' zich aan vastmaakt. Het blok plakte dus aan een cel die niet schuift, en
     schoof daarmee gewoon mee uit beeld. Gemeten in de browser: 419 pixels naar
     rechts, 418 pixels naar links verdwenen. */
  tr.detail > td.detail { padding: 0; background: var(--card); overflow: visible;
                          max-width: none; white-space: normal;
                          border-bottom: 1px solid var(--line); }
  /* De breedte van dit blok is de breedte van wat je ziet, niet van de tabel.

     Het plakt met 'sticky' aan de linkerrand van een kaart die horizontaal
     schuift, dus '100%' is hier de tabelbreedte en niet het venster. Een vaste
     980 pixels was daarom een gok: op een breed scherm bleef er ruimte
     onbenut en op een smaller scherm liep hij eroverheen.

     De variabele wordt door een script gezet uit de werkelijke breedte van de
     kaart, en volgt het venster als dat verandert. Zonder script blijft die 980
     staan, en dan werkt alles zoals het werkte. */
  .detail-inhoud { position: sticky; left: 0; padding: 16px 18px 18px;
                   max-width: min(var(--detail-breedte, 980px), 100%); }
  /* De kop van een uitklapblok vouwt, en de titel krijgt zijn eigen regel.

     Waarom niet alles op één regel: dit blok plakt met 'sticky' aan de
     linkerrand van een kaart die smaller is dan het blok zelf, dus alles wat
     tegen de rechterrand staat valt buiten beeld. Gemeten op 1280 punten: het
     blok loopt tot 1265 en de kaart tot 1244, dus de laatste 21 pixels zijn er
     niet. Een breder blok of meer padding schuift dat mee; links beginnen niet. */
  .detail-kop { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
                margin-bottom: 12px; }
  .detail-kop > strong { flex: 1 1 100%; }
  /* Niet tegen de rechterrand, en dat is gemeten.

     Deze knop stond op 'margin-left: auto', dus helemaal rechts in een blok van
     980 pixels breed. Dat blok plakt met 'sticky' aan de linkerrand van een
     kaart die op een scherm van 1280 punten ongeveer 960 pixels breed is, dus
     stak hij eroverheen: op Monthly issues stond 'dichtklappen' als
     'dichtklapper' op het scherm. Meer ruimte geven lost het niet op, want de
     kaart schuift mee met de zijbalk en met de breedte van het venster.
     Ernaast zetten wel. */
  .detail-kop .dicht { font-size: 12px; color: var(--action);
                       text-decoration: none; white-space: nowrap; cursor: pointer; }
  .detail-kop .dicht:hover { text-decoration: underline; }
  table.losse { width: 100%; margin-top: 14px; border-collapse: collapse; font-size: 12.5px; }
  table.losse th { text-align: left; font-weight: 600; color: var(--muted); font-size: 11.5px;
                   padding: 0 12px 6px 0; border-bottom: 1px solid var(--line); }
  table.losse td { padding: 7px 12px 7px 0; border-bottom: 1px solid rgb(16 24 40 / .04);
                   vertical-align: top; }
  table.losse td.dat { white-space: nowrap; font-variant-numeric: tabular-nums; }
  /* De tekst van de koper is het enige veld zonder vaste vorm; hij mag afbreken
     en de rest van de rij niet uit elkaar duwen. */
  table.losse td.tekst { color: var(--body); min-width: 220px; }

  /* ── De filterrij ──────────────────────────────────────────────────────
   *
   * Alle filters van een scherm naast elkaar, in gelijke vakken die netjes
   * afbreken. Dit verving losse rijen pillen: bij twaalf maanden was dat twee
   * regels knoppen voordat het eerste echte filter in beeld kwam, en drie
   * verschillende vormen voor wat één vraag is.
   *
   * 'align-items: end' zet de velden op hun onderrand gelijk, zodat een label
   * van twee regels de knop ernaast niet omhoog duwt. */
  .filterrij { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
               gap: 12px 14px; align-items: end; }
  .filterrij .veld { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
  .filterrij .veld.breed { grid-column: span 2; }
  .filterrij .veld > label { font-size: 12px; font-weight: 600; color: var(--muted); }
  .filterrij select, .filterrij input { width: 100%; }
  /* Een meervoudige keuzelijst krijgt geen vaste hoogte mee: de ene browser
     toont hem ingeklapt ("3 geselecteerd"), de andere als lijstvak. Een hoogte
     die voor de één klopt, duwt bij de ander de rij scheef. */
  .filterrij select[multiple] { min-height: 0; }
  .filterrij .veld.knoppen { flex-direction: row; align-items: center; gap: 10px; }
  /* Twee keuzelijsten die samen één filter zijn: welke maand tegen welke. */
  .filterrij .tweevelden { display: flex; align-items: center; gap: 6px; min-width: 0; }
  .filterrij .tweevelden select { flex: 1; min-width: 0; }
  .filterrij .tweevelden .met { font-size: 12px; color: var(--faint); flex-shrink: 0; }
  .filterrij .wissen { font-size: 12px; color: var(--action); text-decoration: none;
                       white-space: nowrap; }
  .filterrij .wissen:hover { text-decoration: underline; }

  /* De kop van een sectie met de handelingen erop: kop links, knoppen rechts. */
  .sectie-kop { display: flex; align-items: center; gap: 12px; margin: 0 0 12px;
                font-size: 16px; font-weight: 600; color: var(--text); }
  .sectie-kop .kop-acties { margin-left: auto; display: flex; align-items: center; gap: 8px; }

  .veldkop { display: block; margin: 14px 0 6px; font-size: 12px; font-weight: 600;
             color: var(--muted); }

  tr.sub > td { background: rgb(46 107 255 / .035); font-size: 12px;
                color: var(--muted); }
  tr.sub > td:first-child { border-left: 2px solid var(--brand); }
  tr.sub .datum { color: var(--body); font-weight: 600; }
  tr.sub .stip { color: var(--brand); font-size: 15px; }
  tr.sub.redenrij > td { white-space: normal; max-width: none; padding: 12px 20px; }

  .selectiebalk { display: flex; align-items: center; gap: 12px; margin-bottom: 10px;
                  flex-wrap: wrap; }
  /* Het opgestelde verzoek: vaste breedte-lettertype, want het gaat om de tekst
     zoals hij ingediend wordt - inclusief de regelafbrekingen. */
  pre.verzoek { margin: 0; white-space: pre-wrap; font-size: 12.5px; line-height: 1.55;
                color: var(--body); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
  .selectiebalk a { font-size: 12.5px; font-weight: 600; color: var(--brand);
                    text-decoration: none; }
  .selectiebalk a:hover { text-decoration: underline; }
  th.kies, td.kies { width: 34px; padding-right: 0; }
  td.kies input { margin: 0; }

  .reviews-lijst { display: flex; flex-direction: column; }
  .review-rij { padding: 16px 20px; border-bottom: 1px solid rgb(16 24 40 / .055); }
  .review-rij:last-child { border-bottom: none; }
  .review-kop { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .review-kop .titel { font-size: 14px; font-weight: 700; color: var(--text); }
  .review-meta { font-size: 11.5px; color: var(--faint); margin-top: 4px; }
  .review-tekst { font-size: 13px; color: var(--body); margin: 8px 0 0; white-space: pre-wrap; }
  .review-tekst.en { color: var(--muted); font-style: italic; margin-top: 4px; }
  .sterren { color: #f79009; letter-spacing: 1px; white-space: nowrap; font-size: 13px; }
  .sterren .leeg { color: var(--line-strong); }

  /* Het argument dat naar bol zou gaan, apart gezet: het is van ons en niet
     van de koper, en dat verschil moet je kunnen zien zonder te lezen. */
  .argument { margin-top: 10px; padding: 10px 12px; border-radius: 8px;
              background: rgb(46 107 255 / .05); border: 1px solid rgb(46 107 255 / .12); }
  .argument .wie { font-size: 11px; color: var(--muted); font-weight: 600; margin-bottom: 3px; }
  .argument .tekst { font-size: 12.5px; color: var(--body); white-space: pre-wrap; }

  .zoekrij { display: flex; gap: 8px; margin-top: 12px; }
  .zoekrij input[name="zoek"] { flex: 1; min-width: 0; }

  .feedback .posts { display: flex; flex-direction: column; }
  .feedback .posts .post { background: none; border: none; border-radius: 0;
                           padding: 16px 20px; margin: 0;
                           border-bottom: 1px solid rgb(16 24 40 / .055); }
  .feedback .posts .post:last-child { border-bottom: none; }

  /*
   * De twee tabbladen staan in de kop van het paneel en niet erboven. Reden:
   * "Open" en "Eerder afgerond" zijn twee weergaven van diezelfde lijst, en een
   * losse balk erboven leest als een filter over het hele scherm - inclusief de
   * telkaarten, die juist bij de gekozen lijst horen.
   */
  .sectie-bij a { display: inline-block; padding: 4px 10px; margin-left: 6px;
                  border-radius: 999px; font-size: 12px; font-weight: 600;
                  color: var(--muted); text-decoration: none;
                  border: 1px solid var(--line-strong); }
  .sectie-bij a.aan { color: #fff; background: var(--brand); border-color: var(--brand); }
  .sectie-bij a:hover { text-decoration: none; }
  .dagcurve { display: block; width: 100%; height: auto; }
  .dagcurve .raster { stroke: rgb(16 24 40 / .06); stroke-width: 1; }
  .dagcurve .as { font-size: 11px; fill: var(--faint); }

  .verdeling { display: flex; height: 10px; border-radius: 999px; overflow: hidden;
       background: rgb(16 24 40 / .06); margin: 2px 0 14px; }
  .verdeling span { display: block; height: 100%; }
  .legenda { display: flex; flex-direction: column; gap: 11px; font-size: 13px; }
  .legenda div { display: flex; align-items: center; gap: 10px; }
  .legenda .naam { color: var(--body); flex: 1; }
  .legenda .bedrag { font-weight: 600; font-variant-numeric: tabular-nums; }
  .legenda .deel { color: var(--faint); width: 52px; text-align: right;
                   font-variant-numeric: tabular-nums; }
  /* De stip is het enige dat de balk aan de kaart eronder verbindt: dezelfde
     kleur, dezelfde vorm, op beide plekken. */
  .legenda .stip, .kanaal .naam .stip, .lijst .stip {
       width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; display: inline-block; }

  /* ── De kanaalkaarten ─────────────────────────────────────────────────── */
  .sectie { margin: 26px 0 0; }
  /* Een blok van twee kolommen direct ná een sectie plakte eraan vast: '.sectie'
     heeft alleen een marge bóven zich en '.twee-kolommen' had er geen. Op het
     overzicht viel dat niet op omdat daar alleen secties op secties volgen; op
     het affiliate-scherm staan de toppen onder de sitekaarten en dan raakten de
     twee elkaar. Dezelfde 26px, zodat het ritme van de pagina gelijk blijft. */
  .sectie + .twee-kolommen { margin-top: 26px; }
  .sectie > h2 { display: flex; align-items: baseline; gap: 10px; margin: 0 0 12px;
                 font-size: 16px; font-weight: 600; color: var(--text); }
  .sectie-bij { font-size: 12px; font-weight: 500; color: var(--faint); }
  .kanalen { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
  /* De kaarten in een rij zijn even hoog (grid strekt ze), maar hun inhoud
     begon op verschillende hoogtes te schuiven zodra de regel onder het bedrag
     omsloeg - "30 van 30 dagen gemeten - voor Webshop" past niet altijd op een
     regel. Dan staan de cijferblokken van twee kaarten naast elkaar niet meer op
     dezelfde lijn, en dat is precies wat een rij kaarten rommelig maakt. Het
     cijferblok gaat daarom onderaan de kaart hangen: dat is de rand die alle
     kaarten in een rij wél delen. */
  .kanaal { padding: 18px 20px 0; display: flex; flex-direction: column; }
  .kanaal .kpis { margin-top: auto; }
  /* Een kanaal dat weigert: zichtbaar, maar zonder bedrag. */
  .kanaal.storing { background: rgb(255 255 255 / .5); padding-bottom: 18px; }
  .kanaal .bedrag.leeg { font-size: 16px; font-weight: 500; color: var(--faint); letter-spacing: 0; }

  .kanaal .naam { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; }
  .kanaal .bedrag { font-size: 26px; font-weight: 700; letter-spacing: -.02em;
       font-variant-numeric: tabular-nums; margin-top: 10px; }
  .kanaal .onder { font-size: 12px; color: var(--faint); margin-top: 3px; }
  .kanaal .spark { display: block; width: 100%; height: 22px; margin-top: 14px; }

  /* Zes cijfers naast elkaar lezen als één blok tekst. Een heel lichte lijn
     tussen de vakjes maakt er zes vakjes van, zonder een tabel te worden. De
     lijnen lopen door tot de rand van de kaart; vandaar de negatieve marge. */
  .kpis { display: grid; grid-template-columns: repeat(3, 1fr); margin: 15px -20px 0;
          border-top: 1px solid rgb(16 24 40 / .055); }
  .kpi { padding: 12px 16px; border-right: 1px solid rgb(16 24 40 / .055);
         border-bottom: 1px solid rgb(16 24 40 / .055); }
  .kpi:nth-child(3n) { border-right: none; }
  .kpi:nth-child(n+4) { border-bottom: none; }
  .kpi .k { font-size: 11.5px; color: var(--muted); }
  .kpi .v { font-size: 16px; font-weight: 650; font-variant-numeric: tabular-nums; margin-top: 1px; }
  .kpi .v.leeg { color: var(--faint); font-weight: 500; font-size: 13px; }
  .kpi .waarom { font-size: 11px; color: var(--faint); margin-top: 2px; line-height: 1.35; }


  /* ── Doelen per cijfer ─────────────────────────────────────────────────
   *
   * Een doel hangt aan een cijfer, dus het staat bij dat cijfer en niet in een
   * apart scherm met een lijst. De knop is klein en grijs tot er een doel staat:
   * hij hoort te vinden te zijn zonder de aandacht te trekken van de cijfers
   * zelf, want dat is waar dit scherm over gaat.
   */
  .doel-knop { font-size: 10.5px; font-weight: 600; color: var(--faint); text-decoration: none;
               border: 1px solid var(--line-strong); border-radius: 999px; padding: 1px 7px;
               margin-left: 7px; white-space: nowrap; vertical-align: middle;
               background: var(--card); display: inline-block; }
  .doel-knop:hover { color: var(--brand); border-color: var(--brand); }
  .doel-knop.gezet { color: var(--brand); border-color: var(--brand); }
  /* Het percentage boven of onder het doel. Dezelfde kleuren als '.delta', want
     het is dezelfde vraag - alleen tegen een afspraak in plaats van tegen de
     vorige periode. */
  .doel-deel { font-size: 12px; font-weight: 600; margin-left: 7px; white-space: nowrap;
               font-variant-numeric: tabular-nums; }
  .doel-deel.op { color: #12b76a; }
  .doel-deel.neer { color: #f04438; }

  /* Het formulier klapt open ín de kaart. Geen overlay: dit scherm laadt geen
     JavaScript, en een paneel dat over de cijfers heen valt zou niet weg te
     krijgen zijn zonder er een te schrijven. */
  .doel-form { margin-top: 10px; padding-top: 10px; border-top: 1px solid rgb(16 24 40 / .08); }
  .doel-rij { display: flex; align-items: center; gap: 6px; }
  .doel-rij input { width: 100%; min-width: 0; font-size: 13px; }
  .doel-rij .eenheid { font-size: 13px; color: var(--faint); }
  .doel-rij button { flex-shrink: 0; }
  .doel-form .vink { margin-top: 8px; font-size: 11.5px; color: var(--muted); }
  .doel-uitleg { margin: 6px 0 0; font-size: 11px; color: var(--faint); line-height: 1.35; }

  /* ── Merk en de retourlijst ───────────────────────────────────────────── */
  /* De naam is merkstand en niet merk: dat laatste is het gekleurde blokje met een
     letter naast de naam van een koppeling, en dat zet een breedte van 30 pixels
     die het merkblok hier in elkaar drukte. Twee schermen die dezelfde klassenaam
     lenen, is één schermnaam te weinig. */
  .merkstand { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
  .merkstand > div { padding: 16px 18px; }
  .merkstand .k { font-size: 13px; color: var(--muted); }
  .merkstand .v { font-size: 26px; font-weight: 700; letter-spacing: -.02em;
             font-variant-numeric: tabular-nums; margin-top: 4px; }
  .merkstand .v.leeg { font-size: 16px; font-weight: 500; color: var(--faint); }
  .merkstand .s { font-size: 12px; color: var(--faint); margin-top: 2px; }

  .lijst .regel { display: flex; align-items: center; gap: 12px; padding: 13px 20px;
                  border-bottom: 1px solid rgb(16 24 40 / .055); }
  .lijst .regel:last-child { border-bottom: none; }
  .lijst .hoofd { flex: 1; min-width: 0; }
  .lijst .t { font-size: 13px; font-weight: 600; white-space: nowrap;
              overflow: hidden; text-overflow: ellipsis; }
  .lijst .m { font-size: 12px; color: var(--faint); margin-top: 2px; }
  .lijst .empty { padding: 28px 20px; text-align: center; color: var(--faint); font-size: 13px; }
  /* Een bedrag rechts in een regel: de toppen op het affiliate-scherm en de
     stand van de commissie. Rechts uitgelijnd met tabulaire cijfers, zodat een
     kolom bedragen onder elkaar leesbaar is zonder er een tabel van te maken. */
  .lijst .bedrag { font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums;
       white-space: nowrap; }

  /* Uitleg achter een 'i': de tekst hoort beschikbaar te zijn, niet in de weg
   * te staan. Een details-element en niet JavaScript, want dit scherm heeft
   * er verder geen, en een uitklap is precies waar dat element voor is. */
  .uitleg { display: inline; }
  .uitleg > summary { display: inline-flex; align-items: center; justify-content: center;
       width: 16px; height: 16px; border-radius: 50%; background: var(--info-bg);
       color: var(--brand); font-size: 11px; font-weight: 700; cursor: pointer;
       list-style: none; vertical-align: middle; margin-left: 5px; }
  .uitleg > summary::-webkit-details-marker { display: none; }
  .uitleg > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
  .uitleg[open] > summary { background: var(--brand); color: #fff; }
  .uitleg .tekst { display: block; margin-top: 8px; padding: 10px 12px; font-size: 12.5px;
       line-height: 1.55; color: var(--muted); background: var(--info-bg);
       border-radius: 8px; font-weight: 400; }

  @media (max-width: 60rem) {
    .twee-kolommen { grid-template-columns: 1fr; }
  }


/* De kop van dit scherm volgt de demo: 22px in plaats van de 28px die de rest
   van het dashboard aanhoudt. Gehaakt aan een element dat alleen op deze pagina
   staat, zodat geen ander scherm meeverandert. */
body:has(.pa-tabs) main > header h1 { font-size: 22px; color: #111827; }
body:has(.pa-tabs) main > header { margin-bottom: 4px; }

.pa-afkoel { font-size: 12px; color: #6b7280; white-space: nowrap; }

/* Twee knoppen naast elkaar, geen streep eronder.
   De onderstreping las als een link in een tekst; het zijn twee weergaven van
   hetzelfde scherm en dat is een knop. Op verzoek van de eigenaar, 2026-09-02. */
/* Vouwen en niet schuiven. Gemeten op 2026-09-07: zonder 'flex-wrap' is deze
   balk minimaal 534 pixels breed (de tabs 187 plus de knoppen ernaast 356), dus
   onder ~566 pixels viewport kreeg de hele pagina een horizontale schuifbalk en
   stond de i van *Automatisch voorstellen* op 390 volledig buiten beeld. De
   tabbladen kunnen krimpen doordat hun tekst vouwt, de knoppen niet -- vandaar
   dat eerst de labels over twee regels gingen en daarna de pagina overliep. */
.pa-tabs { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 3px; margin: 8px 0 16px;
     background: rgb(255 255 255 / .55); border: 1px solid rgb(255 255 255 / .8);
     border-radius: 10px; }
.pa-tab { font-size: 13px; font-weight: 600; padding: 7px 14px; color: #6b7280;
     border-radius: 8px; text-decoration: none; }
.pa-tab:hover { background: rgb(255 255 255 / .7); color: #101828; }
.pa-tab.aan { color: #fff; background: #0000a4; }

.pa-kaarten {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px; margin-bottom: 20px;
}
.pa-kaart { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px 20px; }
.pa-kaart-label { font-size: 12px; font-weight: 500; color: #6b7280; }
.pa-kaart-cijfer { font-size: 24px; font-weight: 700; margin-top: 2px; }
.pa-kaart-cijfer.blauw { color: #0000a4; }
.pa-kaart-cijfer.donkerblauw { color: #1e40af; }
.pa-kaart-cijfer.groen { color: #059669; }
.pa-kaart-cijfer.oranje { color: #b45309; }

.pa-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.pa-filter-label { font-size: 12px; color: #6b7280; }
/* Een segmented control: de rondingen zitten op de groep, de knoppen zelf zijn
   recht. Zo staan ze tegen elkaar aan zonder dubbele randen ertussen. */
/* De knoppenreeks mag over meerdere regels vallen.

   Bij status en actief zijn het er drie of vier en gebeurt dat nooit. Bij de
   campagnes zijn het er twaalf met namen als "RC - B10D September 2026", en dan
   perst een reeks op één regel elke naam in een kolom van drie woorden hoog --
   onleesbaar, en de knop is juist de naam waar iemand op zoekt. Liever twee
   regels knoppen die te lezen zijn dan één regel die dat niet is. */
.pa-groep { display: flex; flex-wrap: wrap; border: 1px solid #e5e7eb;
            border-radius: 8px; overflow: hidden; }
.pa-chip {
  font-size: 12px; font-weight: 600; padding: 5px 11px;
  color: #374151; background: #fff; text-decoration: none; border: 0;
  /* Een naam breekt niet af: half "September" op de ene regel en half op de
     volgende leest als twee knoppen. */
  white-space: nowrap;
}
.pa-chip + .pa-chip { border-left: 1px solid #e5e7eb; }
.pa-chip.aan { background: #0000a4; color: #fff; }
.pa-vink {
  display: inline-flex; align-items: center; gap: 6px; margin-left: 6px;
  font-size: 12px; color: #374151; text-decoration: none;
}
.pa-vinkje {
  width: 14px; height: 14px; border: 1px solid #d1d5db; border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; color: #0000a4; background: #fff;
}
.pa-vink.aan .pa-vinkje { border-color: #0000a4; }
.pa-getoond { font-size: 12px; color: #9ca3af; margin-left: 4px; }

.pa-tabel-huls { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; overflow: hidden; }
.pa-tabel-scroll { overflow-x: auto; }
.pa-tabel { width: 100%; border-collapse: collapse; font-size: 13px; }
.pa-tabel thead tr { background: #f9fafb; }
.pa-tabel th {
  font-size: 13px; font-weight: 600; color: #6b7280; text-align: left;
  padding: 10px 12px; white-space: nowrap;
}
.pa-tabel td { padding: 9px 12px; border-bottom: 1px solid #f3f4f6; color: #101828; white-space: nowrap; }
.pa-tabel tbody tr { background: #fff; }
.pa-tabel tbody tr:last-child td { border-bottom: none; }
.pa-ean { font-variant-numeric: tabular-nums; color: #374151; }
.pa-product { font-weight: 600; max-width: 34rem; overflow: hidden; text-overflow: ellipsis; }
.pa-grijs { color: #6b7280; }
.pa-rechts { text-align: right; font-variant-numeric: tabular-nums; }
.pa-nu { color: #059669; font-weight: 600; }
.pa-nooit, .pa-leeg { color: #d1d5db; }
.pa-winkel { color: #6b7280; }
/* De campagnekiezer. Dicht is hij één regel met de gekozen campagne erin; open
   toont hij de hele reeks. Het summary-element krijgt geen driehoekje van de
   browser mee, want er staat al een eigen teken. */
/* De stappen in het voorstelformulier. Genummerd, want het is een volgorde en
   geen opsomming: wat er gebeurt nadat je op de knop drukt, is precies wat hier
   onduidelijk was. */
/* Het voorstelvak in een uitgeklapte actie. Een eigen achtergrond, want het is
   geen rij met cijfers maar iets waar je iets moet dóén -- en het staat midden
   in een tabel. */
/* De kolom met mogelijke acties: per actie een naam met een knopje ernaast.
   Onder elkaar, want een product zit vaak in twee of drie acties tegelijk en
   naast elkaar wordt dat een regel die niemand meer leest. */
.pa-welke { max-width: 320px; white-space: normal; }
.pa-welke-item { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }
.pa-welke-naam { font-size: 11.5px; color: #6b7280; overflow: hidden;
     text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }
.pa-welke-knop { font-size: 11px; font-weight: 600; color: #0000a4; background: none;
     border: 1px solid #c7d2fe; border-radius: 999px; padding: 1px 8px; cursor: pointer;
     white-space: nowrap; }
.pa-welke-knop:hover { background: #eef2ff; }
.pa-welke-knop.aan { color: #047857; border-color: #a7f3d0; background: #ecfdf5; }

/* Wat er klaarstaat voor een actie, in het voorstelvak. */
.pa-klaar { background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
     padding: 10px 12px; margin-bottom: 10px; }
.pa-klaar-kop { font-size: 12px; font-weight: 600; color: #047857; }
.pa-klaar ul { margin: 6px 0 0; padding-left: 18px; font-size: 12px; color: #6b7280; }
.pa-klaar code { font-variant-numeric: tabular-nums; color: #374151; }

.pa-voorstelvak { padding: 16px 20px; background: #f9fafb; border-radius: 10px;
     border: 1px solid #e5e7eb; margin: 4px 0 8px; }
.pa-voorstelvak > strong { display: block; font-size: 13px; margin-bottom: 8px; }
.pa-voorstelvak textarea { width: 100%; max-width: 640px; font-family: inherit;
     font-size: 13px; padding: 8px 10px; border: 1px solid var(--line-strong);
     border-radius: 8px; }
.pa-voorstelvak .form-acties { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
/* Het voorstelblok staat in het uitklapblok en niet meer in een eigen rij; het
   heeft alleen nog lucht nodig zodra er een producttabel boven staat. */
.pa-uitblok .pa-tabel + .pa-uit-voorstel { margin-top: 12px; }

.pa-stappen { margin: 0 0 12px; padding-left: 20px; font-size: 13px; color: var(--body);
     line-height: 1.55; }
.pa-stappen li { margin-bottom: 5px; }

.pa-campagnes { margin: 0 0 14px; }
.pa-campagnes > summary { display: inline-flex; align-items: center; gap: 8px;
     cursor: pointer; list-style: none; padding: 5px 11px; border-radius: 8px;
     border: 1px solid #e5e7eb; background: #fff; font-size: 12px; }
.pa-campagnes > summary::-webkit-details-marker { display: none; }
.pa-campagnes > summary::after { content: '▾'; color: #9ca3af; font-size: 11px; }
.pa-campagnes[open] > summary::after { content: '▴'; }
.pa-campagnes > summary:hover { border-color: #0000a4; }
.pa-campagne-nu { font-weight: 600; color: #101828; }
.pa-campagnes .pa-groep { margin-top: 10px; }

/* ── Filters als uitklapmenu ──────────────────────────────────────────
 *
 * Op verzoek van de eigenaar (2026-09-02): niet elke keuze als rij knoppen
 * naast elkaar, maar één knop per filter die openklapt. Met vier filters en
 * veertien campagnes was die rij twee regels lang, en dan is er geen verschil
 * meer tussen "waar kan ik op filteren" en "wat staat er aan".
 *
 * Zelfde techniek als de campagnekiezer hierboven: een details-element en
 * geen select, want de keuzes zijn links met de hele staat in het adres. Zo blijft
 * een gefilterd scherm deelbaar en doet de terugknop wat je verwacht.
 */
.pa-keuze { position: relative; }
.pa-keuze > summary { display: inline-flex; align-items: center; gap: 8px;
     cursor: pointer; list-style: none; padding: 6px 11px; border-radius: 8px;
     border: 1px solid #e5e7eb; background: #fff; font-size: 12px; white-space: nowrap; }
.pa-keuze > summary::-webkit-details-marker { display: none; }
.pa-keuze > summary::after { content: '▾'; color: #9ca3af; font-size: 11px; }
.pa-keuze[open] > summary::after { content: '▴'; }
.pa-keuze > summary:hover { border-color: #0000a4; }
.pa-keuze[open] > summary { border-color: #0000a4; }
.pa-keuze-nu { font-weight: 600; color: #101828; }

/* Het menu zweeft boven de tabel: een filter dat de pagina naar beneden duwt,
   verschuift precies de regel waar je naar keek. */
.pa-keuze-menu { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0;
     min-width: 220px; max-width: 380px; max-height: 320px; overflow-y: auto;
     padding: 6px; background: #fff; border: 1px solid #e5e7eb; border-radius: 10px;
     box-shadow: 0 1px 2px rgb(16 24 40 / .04), 0 12px 28px rgb(16 24 40 / .12); }
.pa-keuze-menu a { display: block; padding: 7px 10px; border-radius: 7px;
     font-size: 12.5px; color: #344054; text-decoration: none; white-space: nowrap;
     overflow: hidden; text-overflow: ellipsis; }
.pa-keuze-menu a:hover { background: #f3f4f6; }
.pa-keuze-menu a.aan { background: #0000a4; color: #fff; font-weight: 600; }
.pa-keuze-menu form { padding: 4px 6px 8px; }

/* Zoeken staat op dezelfde regel als de filters en niet in een eigen blok:
   het is één veld, en een paneel eromheen maakt er een formulier van. */
/*
 * De filterregel vouwt.
 *
 * Hij stond op inline-flex zonder flex-wrap, en dan duwt hij de hele pagina
 * opzij zodra hij niet past: gemeten op Branded shelves bij 485 punten stond de
 * knop Wissen 69 pixels buiten beeld en liep het document naar 554. Dat is
 * dezelfde fout als .paneel-kop op 2026-09-30 en de periodekiezer op
 * 2026-09-12 -- en hij raakt elk scherm dat deze klasse draagt.
 *
 * Wrap doet pas iets zodra het niet past, dus op een brede rij verandert er
 * niets. row-gap erbij, want twee gevouwen regels zonder verticale ruimte
 * plakken aan elkaar.
 *
 * Let op bij het aanpassen van dit bestand: een backtick in commentaar sluit de
 * template-string waar de hele stylesheet in staat.
 */
.pa-zoekregel { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; row-gap: 8px; }
.pa-zoekregel input[type=text],
.pa-zoekregel input[type=search] {
  font: inherit; font-size: 12.5px; padding: 6px 10px; min-width: 280px;
  border: 1px solid #e5e7eb; border-radius: 8px; background: #fff;
}
.pa-zoekregel input[type=text]:focus,
.pa-zoekregel input[type=search]:focus { outline: none; border-color: #0000a4; }

/* ── De uitklapper van een actie ──────────────────────────────────────
 *
 * Een eigen kolom vooraan met een ronde knop, op verzoek van de eigenaar
 * (2026-09-02). Hij zat als een pijltje vóór de titel, en dan is niet te zien
 * dat die titel iets doet.
 */
.pa-klapkolom { width: 40px; padding-right: 0 !important; }
.pa-klapknop { display: inline-flex; align-items: center; justify-content: center;
     width: 22px; height: 22px; border-radius: 50%; border: 1px solid #e5e7eb;
     background: #fff; color: #6b7280; text-decoration: none; }
.pa-klapknop:hover { border-color: #0000a4; color: #0000a4; }
/* Een gebouwde pijl en geen leesteken: het chevron-glyph verdween in de
   rotatie en dan staat er een leeg rondje. Twee randen van een vierkantje,
   gedraaid -- die kun je wél zien draaien. */
.pa-klapknop .pa-pijl { font-size: 0; width: 6px; height: 6px; margin-left: -2px;
     border-top: 2px solid currentColor; border-right: 2px solid currentColor;
     transform: rotate(45deg); transition: transform .16s ease; }
.pa-klapknop.open .pa-pijl { margin: -2px 0 0 0; }
.pa-klapknop.open { background: #0000a4; border-color: #0000a4; color: #fff; }
.pa-klapknop.open .pa-pijl { transform: rotate(135deg); }

/* De uitgeklapte inhoud komt open in plaats van te verschijnen.

   De animatie zat op '.pa-uit:not([hidden]) > td > *' -- elk kind van elke cel
   van elke uitklaprij. Bij een actie met tachtig producten schoven daarmee
   tientallen elementen los naar binnen, en dat leest als flikkeren en niet als
   iets dat opengaat. Hij zit nu op het éne blok.

   Hij mag nooit voorwaarde zijn om de inhoud te zien: dicht of open is het
   hidden-attribuut, dat de server ook zet. Wie 'reduce' heeft staan krijgt
   dezelfde inhoud, alleen meteen. */
@keyframes pa-uitklap {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.pa-uit:not([hidden]) .pa-uitblok { animation: pa-uitklap .18s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .pa-uit:not([hidden]) .pa-uitblok { animation: none; }
  .pa-klapknop .pa-pijl { transition: none; }
}

/* De preset-knoppen naast Campagne en Deadline. Dezelfde ghost-knop als de rest
   van de balk; aan is een gevulde staat, zodat je aan de balk ziet wat er
   aanstaat zonder de tabel te lezen. */
.pa-focusknop.aan {
  background: #eef2ff; border-color: #c7d2fe; color: #3730a3; font-weight: 600;
}

/* Wat bol goedkeurde maar buiten de actie valt: dichtgeklapt, want het is een
   kanttekening en geen lijst waar je iets mee moet. */
/* De suggestielijst met vinkjes: aanvinken is de handeling, dus de hele regel
   is klikbaar en de bolletjes vallen weg. */
.pa-kieslijst { list-style: none; margin: 8px 0 0; padding: 0; }
.pa-kieslijst li { margin: 0; }
.pa-kieslijst label { display: flex; align-items: baseline; gap: 8px;
     padding: 3px 6px; border-radius: 6px; cursor: pointer; }
.pa-kieslijst label:hover { background: #f3f4f6; }
.pa-kieslijst input { margin: 0; flex: none; }
/* Bij tachtig suggesties duwt de lijst de knop eronder buiten beeld. Vanaf een
   regel of twaalf scrollt hij daarom in zichzelf; de rand zegt dat er meer is.
   (Het woord met s-t-u-k staat hier bewust niet: deze stylesheet komt in elke
   pagina terecht, en een test op de runhistorie let daarop.) */
.pa-kieslijst.pa-scrollt, .pa-klaar ul.pa-scrollt { max-height: 320px; overflow-y: auto;
     border: 1px solid #e5e7eb; border-radius: 8px; padding: 4px; background: #fff; }
.pa-klaar ul.pa-scrollt { padding: 6px 6px 6px 22px; }

/* De uitleg naast een knop, achter een i. Zelfde vorm als de i naast een
   paginatitel: een rondje dat opengaat, en niet een regel die er altijd staat. */
.pa-uitleg { position: relative; display: inline-block; }
.pa-uitleg > summary { display: inline-flex; align-items: center; justify-content: center;
     width: 20px; height: 20px; border-radius: 50%; border: 1px solid #e5e7eb;
     background: #fff; color: #6b7280; font-size: 11px; font-weight: 700;
     font-style: italic; cursor: pointer; list-style: none; }
.pa-uitleg > summary::-webkit-details-marker { display: none; }
.pa-uitleg > summary:hover { border-color: #0000a4; color: #0000a4; }
.pa-uitleg p { position: absolute; z-index: 30; left: 0; top: calc(100% + 6px);
     width: min(360px, 70vw); margin: 0; padding: 10px 12px; background: #fff;
     border: 1px solid #e5e7eb; border-radius: 10px; font-size: 12.5px;
     color: #475467; line-height: 1.55;
     box-shadow: 0 1px 2px rgb(16 24 40 / .04), 0 12px 28px rgb(16 24 40 / .12); }

/* De wachtrijbalk boven de tabel: een mededeling die vanzelf verdwijnt zodra de
   rij leeg is, dus geen paneel met een kop. */
.pa-wachtrij { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.pa-wachtrij-stop { margin-left: auto; }
.pa-wachtrij-fout { flex-basis: 100%; margin: 4px 0 0 18px; font-size: 12.5px;
     color: #b42318; line-height: 1.6; }

.pa-buiten { margin: 10px 0 0; font-size: 12.5px; }
.pa-buiten > summary { cursor: pointer; color: #6b7280; }
.pa-buiten > summary:hover { color: #0000a4; }
.pa-buiten ul { margin: 8px 0 0 18px; color: #475467; line-height: 1.7; }
.pa-buiten code { font-size: 12px; color: #101828; }

.pa-geen { text-align: center; color: #9ca3af; padding: 28px; }
/* Het vinkje bij een actie waarvan elke prijs al klopt. Een teken en geen woord:
   ernaast staat een aantal, en "alles klaar" naast "3" leest als twee soorten
   antwoord op dezelfde vraag. */
.pa-vink-klaar { display: inline-flex; align-items: center; justify-content: center;
     width: 20px; height: 20px; border-radius: 6px; font-size: 12px; font-weight: 700;
     color: #047857; background: #d1fae5; border: 1px solid #a7f3d0; }

/* Sorteren op een kolomkop.

   De kop is een link en geen knop met script: de sortering staat in het adres,
   dus een gesorteerd scherm is te delen en te bookmarken - dezelfde keuze als
   bij de filters ernaast. Het pijltje staat alleen op de kolom die aan staat;
   een pijltje op elke kop leest als "hier valt niets te kiezen". */
.pa-sorteer {
  color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
  /* Het pijltje krijgt een vaste plek, zodat de kop niet verspringt op het
     moment dat je erop drukt. Dat verspringen was de helft van wat "houterig"
     voelde: de kolom werd een teken breder en de hele tabel schoof mee. */
  cursor: pointer; user-select: none;
}
.pa-pijl { width: 9px; display: inline-block; font-size: 11px; line-height: 1; }
/* De rijen wisselen van plek zonder de tabel opnieuw op te bouwen; een korte
   overgang op de achtergrond maakt zichtbaar dat er iets gebeurde. */
.pa-tabel tbody tr { transition: background-color .12s ease; }
.pa-sorteer:hover { color: #111827; text-decoration: underline; }
.pa-sorteer.aan { color: #111827; font-weight: 700; }

/* De vinkkolom. Smal, en met de rand van de tabel mee zodat hij niet als een
   eigen kolom met betekenis leest. */
.pa-vinkkolom { width: 34px; text-align: center; padding-right: 0 !important; }
.pa-vinkkolom input { margin: 0; cursor: pointer; }
.pa-gekozen td { background: #f0f7ff; }

.pa-selectiebalk {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-bottom: 1px solid #f3f4f6; background: #fcfcfd;
}

/* Het vak met de gekozen EANs. Monospace en tabular, want dit is een lijst
   getallen die iemand naast elkaar legt. */
.pa-eanvak {
  display: block; width: 100%; margin-top: 8px; padding: 8px 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
  border: 1px solid #d1d5db; border-radius: 8px; background: #fff; color: #111827;
  resize: vertical;
}
.pa-eans { background: #f0f7ff; border-color: #bfdbfe; }

/* De knoppen in de laatste kolommen. Klein en secundair: ze staan op elke rij,
   en een volle knop maal driehonderd rijen is een tabel die schreeuwt. */
.pa-doen { width: 1%; white-space: nowrap; text-align: right; }
.pa-knop { font-size: 12px; padding: 4px 10px; white-space: nowrap; }
.pa-tabel td.pa-doen { padding-left: 6px; }
/* De kolom met de directe knop. Smal en zonder omhaal: het is één knop, en
   hij hoort niet even breed te zijn als de promotietitel ernaast. */
.pa-tabel td.pa-direct { padding-left: 6px; white-space: nowrap; }
.pa-tabel td.pa-direct form { display: inline; }

/* De knop hoort in de kop van het paneel, rechts naast de telling -- niet in een
   eigen balk erboven. Die balk was een witte strook met één knop erin. */
/* Vouwen, want de kop draagt op smalle schermen meer dan erin past.

   Gemeten op de promotie-agenda van R2B op 390 punten: de kop bevat een titel,
   een telling en de knop 'Openen bij bol', samen 307 pixels naast een titel --
   en zonder wrap duwde dat de hele pagina naar 474 pixels breed, met die knop
   84 pixels buiten beeld. Een horizontale schuifbalk op het hele scherm, en een
   knop die je op een telefoon niet kunt raken.

   Dezelfde reparatie als bij .paneel-tabs en de knoppenrij van de
   instellingen: op een brede kop verandert er niets, want wrap doet pas iets
   zodra het niet past. */
.paneel-acties { margin-left: auto; display: flex; align-items: center; gap: 10px;
                 flex-wrap: wrap; }
.paneel-kop { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Twee weergaven van hetzelfde scherm, als knoppen in de kop van het paneel.
   Dezelfde vorm als .pa-tabs op de Promotie-agenda, maar zonder die klasse: daar
   hangt een regel aan die de paginakop kleiner maakt, en dat hoort niet mee te
   komen met een tabblad. De knoppen zelf zijn .pa-tab, dus één opmaak. */
/* Vouwen mag. Met een tabblad per bol-winkel staan er op LVB management vijf
   tabs, en de langste dragen een winkelnaam uit het manifest -- dus hoe breed
   deze rij wordt, bepaalt de klant en niet de opmaak. Zonder wrap duwt dat de
   hele pagina horizontaal open, precies zoals de tabbladenbalk van de
   promotie-agenda op 2026-09-07 deed. */
.paneel-tabs { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 3px;
     background: rgb(255 255 255 / .55); border: 1px solid rgb(255 255 255 / .8);
     border-radius: 10px; }

/* Even veel lucht onder een paneel als erboven. De secties stonden tegen
   elkaar aan doordat alleen de bovenmarge gezet was. */
.promo .paneel-kaart { margin-bottom: 18px; }
.promo .stat-rij { margin-bottom: 18px; }

/* Een uitgeklapte actie: de regels eronder horen zichtbaar bij hun promotie. */
.pa-actie.open > td { background: #f8fafc; }
.pa-klap { cursor: pointer; }

/* De greep om een kolom breder of smaller te maken. Een strookje op de
   rechterrand van de kop: onzichtbaar tot je erover gaat, want een streep in
   elke kop maakt van een tabel een spreadsheet. */
.pa-tabel th { position: relative; }
.pa-greep {
  position: absolute; top: 0; right: 0; width: 7px; height: 100%;
  cursor: col-resize; user-select: none;
}
.pa-greep:hover { background: #c7d2fe; }
/* Tijdens het slepen niets selecteren en overal dezelfde cursor, anders knippert
   hij zodra je de kop verlaat. */
body.pa-sleept { user-select: none; cursor: col-resize; }
body.pa-sleept * { cursor: col-resize !important; }

/* Zodra er een breedte gezet is, kapt een cel af in plaats van de tabel op te
   rekken -- anders doet smaller maken niets.

   Eerst brak hij af over meerdere regels (white-space: normal), en dat is op
   deze tabel het verkeerde antwoord: één actie is één regel, en zodra de
   producttitels van twee naar drie regels springen loopt de rest van de kolommen
   niet meer met het oog mee. Een rij die van hoogte verandert terwijl je aan een
   kolom sleept, leest bovendien als een tabel die het begeeft.

   Dus afkappen met een beletselteken. Kwijtraken doe je niets: de volle tekst
   staat in de title van de cel, dus aanwijzen laat hem zien. Dezelfde afspraak
   als bij de klantvragen -- afkappen mag, kwijtraken niet. */
.pa-tabel[style*="fixed"] td {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* De uitgeklapte regels zijn de uitzondering: daar staat de tekst van een
   product onder zijn actie, en die hoort wél te mogen lopen.

   Dit geldt ook voor de nieuwe uitklapcel, en dat is geen detail: zou die cel
   'overflow: hidden' houden zodra iemand een kolom versleept heeft, dan wordt
   hij zelf het venster waar de sticky van .pa-uitblok zich aan vastmaakt -- en
   dan schuift het blok alsnog uit beeld bij horizontaal scrollen. */
.pa-tabel[style*="fixed"] tr.pa-uit td { white-space: normal; overflow: visible; }
.pa-tabel[style*="fixed"] tr.pa-uit .pa-uitblok td { white-space: normal; overflow: visible; }

/* Het doelpaneel op Per product: dezelfde paneelvorm als de rest van het
   scherm, met een tint zodra er een doel gekozen is -- dan is de tabel
   gefilterd, en dat hoort je te zien zonder de tekst te lezen. */
.pa-doelpaneel .paneel-lijf { padding: 14px 20px 16px; }
.pa-doelpaneel.aan { border-color: #c7d2fe; }
.pa-doelpaneel.aan .paneel-kop { background: #eef2ff; }
.pa-doeluitleg { margin: 0 0 10px; font-size: 12.5px; color: #4b5563; line-height: 1.5; }
.pa-doelknoppen { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pa-doelknoppen .pa-campagnes { margin: 0; }

/* De kolomkeuze: vinkjes in een uitklapper onder de filters. Een vaste
   kolombreedte per vinkje, zodat vijftien labels drie nette kolommen vormen in
   plaats van een sliert. */
.pa-kolomform { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 4px 14px; }
.pa-kolomkeuze { display: inline-flex; align-items: center; gap: 6px;
     font-size: 12.5px; color: #374151; min-width: 170px; cursor: pointer; }
.pa-kolomkeuze input { margin: 0; }
.pa-kolomacties { flex-basis: 100%; display: flex; gap: 8px; margin-top: 8px; }

/* De deadlinechips op Per promotie, in de vorm van de andere filters. */
.pa-deadlines { margin-bottom: 14px; }

/* De tagnaam in Potentiele promoties is een link naar de actie; de stippellijn
   ('gok') markeert een bovenaan gekozen actie waar de controle van bol nog
   niet over gelopen heeft. */
a.pa-welke-naam { text-decoration: none; }
a.pa-welke-naam:hover { color: #0000a4; text-decoration: underline; }
a.pa-welke-naam.pa-gok { border-bottom: 1px dashed #9ca3af; }

/* Wat er volgens bol in een actie past, in de uitklap. Zelfde vorm als het
   klaargezet-blok erboven. */
.pa-suggesties { background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
     padding: 10px 12px; margin-bottom: 10px; }
.pa-suggesties ul { margin: 6px 0 0; padding-left: 18px; font-size: 12px; color: #6b7280;
     max-height: 220px; overflow-y: auto; }
.pa-suggesties code { font-variant-numeric: tabular-nums; color: #374151; }
.pa-suggesties .pa-eanvak { max-width: 420px; }
.pa-categorieen { margin: 0 0 10px; font-size: 12px; color: #6b7280; line-height: 1.5; }

.pa-naarbol { display: inline-block; margin-top: 8px; }
.pa-bijschrift { display: block; margin-top: 6px; font-size: 12px; color: #6b7280; }

/* De kanaalnaam op het overzicht is aanklikbaar om hem te hernoemen. Geen knop
   en geen potloodje: het is de naam zelf, en pas bij het aanwijzen blijkt dat er
   iets te doen valt. Een scherm vol bewerkknoppen leest als een formulier. */
/* De naam van een kanaal is sinds 2026-09-08 een summary-element: het veld zit
   er al in en klapt open zonder de server. Het driehoekje van de browser gaat
   eraf -- er staat al een streepje onder dat zegt dat je erop kunt drukken. */
.kanaal-naam { color: inherit; text-decoration: none; border-bottom: 1px dashed transparent; }
.kanaal-naam:hover { border-bottom-color: currentColor; cursor: text; }
.naam-huls > summary { list-style: none; display: inline-block; }
.naam-huls > summary::-webkit-details-marker { display: none; }
.naam-huls[open] > summary { border-bottom-color: currentColor; }
.naam-form { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* Bewaren zonder herladen: even zichtbaar dat het gebeurde, en daarna weg. Een
   naam die stil verandert leest als een naam die niet bewaard is. */
.naam-huls.bezig .naam-veld { opacity: .6; }
.naam-huls.klaar > summary { border-bottom-color: #12b76a; }
.naam-veld {
  flex: 1 1 120px; min-width: 90px; padding: 4px 8px; font: inherit;
  border: 1px solid #d1d5db; border-radius: 6px;
}
.naam-hint { flex: 1 0 100%; font-size: 11px; color: #6b7280; }

/* Wat het scherm nog niet kan weten, staat bovenaan en niet in een voetnoot.
   Zolang de historie korter is dan de afkoelperiode zijn 'Warm' en 'Ready' een
   aanname, en dan hoort dat er te staan waar iemand kijkt. */
.pa-melding {
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px;
  padding: 10px 14px; margin-bottom: 16px; font-size: 12.5px; color: #78350f; line-height: 1.5;
}
.pa-melding strong { font-weight: 700; }
/* Een gemiste ronde is erger dan een jonge historie: die dag is niet in te
   halen. Vandaar rood in plaats van geel. */
.pa-melding.pa-oud { background: #fef2f2; border-color: #fecaca; color: #991b1b; margin-top: 14px; }
.pa-melding em { font-style: normal; font-weight: 600; }
.pa-voet { font-size: 12px; color: #9ca3af; margin-top: 10px; }

/* ── Het tweede tabblad: per promotie, met uitklap ──────────────────────────
   De uitgeklapte regels staan in dezelfde tabel en niet in een blok eronder.
   Dat is de reden dat je ze naast elkaar kunt lezen: dezelfde kolombreedtes,
   dezelfde uitlijning. Het lichtblauw zegt "dit hoort bij de regel erboven" -
   sterk genoeg om het blok te zien, licht genoeg om de cijfers leesbaar te
   houden. */
.pa-klap { display: inline-flex; align-items: center; gap: 8px; color: #101828; text-decoration: none; font-weight: 600; }
.pa-klap:hover { color: #0000a4; }
.pa-pijl { color: #9ca3af; font-size: 11px; width: 10px; display: inline-block; }
.pa-actie.open .pa-pijl { color: #0000a4; }
.pa-actie.open td { background: #eff6ff; border-bottom-color: #dbeafe; }
.pa-actie.open .pa-klap { color: #1e40af; }

/* De uitklap is sinds 2026-09-11 één cel over de volle breedte met een blok
   erin, en niet meer zeven losse cellen in een tabel van dertien kolommen. Die
   dwongen de browser alle kolombreedtes te herverdelen bij elke klik: gemeten
   458 pixels verschuiving en een tabel die van 2.174 naar 2.745 pixels groeide.

   'padding: 0' omdat het blok zijn eigen ruimte meebrengt, en 'overflow:
   visible' omdat een voorouder met een andere overflow zélf het venster wordt
   waar 'position: sticky' zich aan vastmaakt -- dezelfde voorwaarde als bij de
   retourpagina en bij Zending controle. */
.pa-uit > td {
  padding: 0 !important; background: #eff6ff; overflow: visible;
  border-bottom: 1px solid #dbeafe; font-size: 12.5px;
}
.pa-uit:last-child > td { border-bottom: 1px solid #e5e7eb; }
/* Het blok zelf, in de vorm van .vr-zblok op Zending controle: één wit kader met
   een accentrand links, dat aan de linkerkant blijft plakken terwijl de tabel
   eromheen horizontaal schuift. De marge links lijnt uit met de eerste echte
   kolom, achter de uitklapkolom van 40px. */
.pa-uitblok {
  position: sticky; left: 0;
  max-width: min(var(--vr-zbreedte, 1100px), 100%);
  margin: 10px 12px 14px 40px;
  padding: 12px 14px 14px;
  background: #fff;
  border: 1px solid #dbeafe;
  border-left: 3px solid #2e6bff;
  border-radius: 10px;
}
/* De geneste tabel verliest zijn eigen kader: het blok eromheen is het kader.
   Twee kaders om dezelfde inhoud is wat de uitklap rommelig maakte. */
.pa-uitblok .pa-tabel { background: transparent; border: 0; border-radius: 0; width: 100%; }
.pa-uitblok .pa-tabel th { font-size: 12px; }
.pa-uitblok .pa-tabel code { font-variant-numeric: tabular-nums; color: #475569; }
.pa-actieprijs { font-weight: 600; color: #1e40af; }
.pa-eraf { color: #b91c1c; font-weight: 600; }
.pa-goed { color: #059669; font-weight: 600; }

.pa-pil {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 6px;
}
.pa-stip { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pa-warm { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
.pa-koud { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
.pa-warm-bol { background: #fef3c7; color: #b45309; border: 1px solid #fde68a; }
.pa-in-promotie { background: #dbeafe; color: #1e40af; border: 1px solid #bfdbfe; }
.pa-neutraal { background: #f3f4f6; color: #6b7280; border: 1px solid #e5e7eb; }
.pa-bol { background: #e0e7ff; color: #3730a3; border: 1px solid #c7d2fe; }
/*
 * Wat er onderweg is naar bol. Blauw en niet groen: het is geen voorraad -- er
 * kan vandaag niets van verkocht worden -- maar wel iets dat loopt. Groen zou
 * hier "in orde" betekenen naast een LVB-stapel die leeg is.
 */
.pa-onderweg { background: #e0f2fe; color: #075985; border: 1px solid #bae6fd; }

/* -- Ads per product ---------------------------------------------------
 *
 * Vier standen en vier kleuren, en de keuze die telt zit tussen de tweede en de
 * vierde: "stil" is amber en "niet gemeten" grijs. Amber is een signaal (er
 * staat iets ingericht dat niets doet), grijs is afwezigheid van kennis. Die
 * twee dezelfde kleur geven zou van dit scherm een ja/nee-lijst maken, en dan
 * is precies de regel waar werk aan zit niet meer te vinden.
 *
 * Rood is hier met opzet niet gebruikt: "niet live" is geen storing maar vaak
 * een bewust besluit, en rood op de helft van een catalogus leest als een lijst
 * vol fouten.
 */
.ads-pil {
  display: inline-flex; align-items: center;
  font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 6px;
  white-space: nowrap;
}
.ads-live { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
.ads-stil { background: #fef3c7; color: #b45309; border: 1px solid #fde68a; }
.ads-uit { background: #eef2f7; color: #475569; border: 1px solid #e2e8f0; }
.ads-onbekend { background: #f3f4f6; color: #6b7280; border: 1px dashed #d1d5db; }

/*
 * De producttitel klemt af in plaats van alles op te eten wat er over is.
 * Gemeten op Feedback & Compensations: een ongeklemde titel vulde 1.319 van de
 * 1.440 beschikbare pixels. De volledige tekst staat in de tooltip.
 */
/*
 * De klem staat op een span en niet op de cel.
 *
 * Een tabelcel negeert max-width zodra de tabel op auto-layout staat -- gemeten
 * op dit scherm: met de klem op de td werd de productkolom 320 pixels breed in
 * plaats van 260. Een inline-block eromheen is wél te klemmen, en pas dan doet
 * de beletselteken-regel eronder wat hij belooft.
 */
.adsproducten .ads-titel {
  display: inline-block; max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;
}

/* ── Stock management ─────────────────────────────────────────────────
 *
 * De filterrij, de zoekbalk en de knoppen zijn dezelfde als op LVB management
 * -- ze dragen letterlijk dezelfde klassen, want twee schermen met hetzelfde
 * werk horen er niet verschillend uit te zien. Wat hier bijkomt, is wat dit
 * scherm eigen heeft: dertig kolommen, een versleepbare breedte, en drie
 * kolommen die een besluit dragen in plaats van een getal. */

/* De producttitel vulde alles wat er overbleef. Hij kapt nu af met een
   beletselteken; de volledige titel staat in de tooltip die er al stond. Een
   'max-width' en geen 'width': is er ruimte over, dan mag een korte titel hem
   gewoon houden -- en wie er meer van wil zien, sleept de kolom breder. */
.ik-tabel td[data-kol="referentie"], .ik-tabel th[data-kol="referentie"] {
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ik-tabel td[data-kol="ean"], .ik-tabel th[data-kol="ean"] { white-space: nowrap; }

/* De drie besliskolommen staan vóór de getallen en krijgen geen rechte
   uitlijning: het zijn geen bedragen. Ze mogen niet afbreken -- "Going out of
   stock" over twee regels maakt elke rij een halve regel hoger dan zijn
   buren. */
.ik-tabel td.ik-besluit, .ik-tabel th.ik-besluit { white-space: nowrap; }

/* De sleepgreep op de rand van een kolomkop. Hij wordt door het script
   aangemaakt; zonder script bestaat hij niet en houdt de tabel de breedtes die
   de server rendert. Zes pixels breed: smal genoeg om de kop niet in de weg te
   zitten, breed genoeg om te raken. */
.ik-tabel th { position: relative; }
.ik-greep {
  position: absolute; top: 0; right: 0; width: 6px; height: 100%;
  cursor: col-resize; user-select: none;
}
.ik-greep:hover { background: var(--brand); opacity: .35; }
/* Tijdens het slepen mag er niets geselecteerd worden en blijft de cursor
   staan, ook als de muis buiten de kop komt. */
body.ik-sleept { user-select: none; cursor: col-resize; }

/* ── Feedback & Compensations ──────────────────────────────────────────
 *
 * De uitklap is hier geen samenvatting maar de werklijst zelf: een tabel in een
 * tabel, met twaalf kolommen waarvan er vijf een link naar Drive zijn. Hij
 * schuift binnen zijn eigen blok, want de buitenste tabel doet dat al en twee
 * schuifgebieden over elkaar is niet te bedienen. */
.comp-binnen { font-size: 12.5px; margin-top: 8px; }
.comp-binnen th { font-size: 11px; text-transform: uppercase; letter-spacing: .3px; }
.comp-binnen td, .comp-binnen th { padding: 6px 9px; }

/* De uitleg van de koper is de enige kolom die lang wordt -- gemeten tot
   driehonderd tekens. Zonder plafond wordt de binnenste tabel daardoor breder
   dan het scherm en schuift niemand ooit naar de kolommen met de foto's. De
   volledige tekst staat als tooltip op de cel. */
.comp-binnen td.comp-tekst {
  max-width: 420px; white-space: normal; overflow: hidden; text-overflow: ellipsis;
}

/* Hoeveel meldingen er in een regel zitten, achter de datum. Een regel is een
   probleem; dat er twee helpdeskzaken onder zitten is een bijschrift en geen
   tweede regel. Zie 'groepeerZaken'. */
.comp-maal { color: var(--faint); font-weight: 600; font-size: 11px; }

/* De breedte van de twee eerste kolommen, op verzoek vastgezet.
 *
 * De producttitel vulde alles wat er overbleef -- gemeten 1.319 pixels naast
 * een EAN van 142 -- en dat is op een scherm waar de telling en de stand rechts
 * staan precies de verkeerde kant op. Hij is nu twee keer de EAN-kolom en
 * blijft op één regel; wat er niet past krijgt een beletselteken, en de
 * volledige titel staat in de tooltip die er al stond.
 *
 * 'table-layout: fixed' hoort hierbij: zonder dat onderhandelt de browser de
 * breedtes op de inhoud en wint een lange titel het alsnog van een 'width'. En
 * daarmee wordt 'width' op de overige koppen een verdeelsleutel in plaats van
 * een wens. */
.comp-tabel { table-layout: fixed; }

/* One column has to stay flexible, and it is Brand.
 *
 * With 'table-layout: fixed' the first row sets the columns, and whatever the
 * table is wider than their sum has to land somewhere. With every column
 * pinned, Chrome dropped the slack on the first one -- measured at 1680 points:
 * the tick column became 159 pixels wide while its own cell stayed 34, leaving
 * a 125-pixel hole between the checkbox and the EAN. That is the gap in the
 * screenshot, and it grows with the window.
 *
 * Brand carries the slack because it is the one column where extra room is
 * useful and nothing depends on its exact size: brand names run from "ZEUZ" to
 * "RX Goods Premium". EAN and Product name keep their fixed widths, so the two
 * to one ratio between them holds at every window size. */
.comp-tabel th.comp-ean, .comp-tabel td.comp-ean { width: 140px; }
.comp-tabel th.comp-naam, .comp-tabel td.comp-naam { width: 280px; }
.comp-tabel td.comp-naam span, .comp-tabel td.comp-merk > .rijlink {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.comp-tabel td.comp-naam span { width: 100%; }
/* Deliberately no width: this is the column that absorbs the remainder. */
.comp-tabel th.comp-merk, .comp-tabel td.comp-merk { min-width: 110px; }
.comp-tabel th.num, .comp-tabel td.num { width: 94px; }
/* 'Image/video' is the longest header on this table; at 86 pixels it was cut
   off mid-word. A header you cannot read is a column nobody trusts. */
.comp-tabel th.comp-beeld, .comp-tabel td.comp-beeld { width: 112px; }
.comp-tabel th.comp-laatste, .comp-tabel td.comp-laatste { width: 118px; }
.comp-tabel th.kies, .comp-tabel td.kies { width: 34px; text-align: center; }

/* The pills sat flush against the date in the column beside them. Centred in
   their own column they keep their distance from both neighbours, and the
   header sits above them instead of off to one side. */
.comp-tabel th.num, .comp-tabel td.num,
.comp-tabel th.comp-beeld, .comp-tabel td.comp-beeld { text-align: center; }
.comp-tabel td.num > .rijlink, .comp-tabel td.comp-beeld > .rijlink { text-align: center; }

/* Geen dode zone in een rij die je aanklikt om hem open te vouwen.
 *
 * Het label vulde de cel in de breedte maar niet in de hoogte -- gemeten 35 van
 * de 40 pixels -- en die vijf pixels zijn precies de rand waar een klik niets
 * deed. Dat is waarom "hij klapt niet weer dicht": de tweede klik landde in de
 * marge. */
.comp-tabel tr.rij > td:not(.kies) { padding: 0; }
/* The negative margin has to go with it.
 *
 * The base rule gives '.rijlink' 'margin: -10px -14px' so the label spills into
 * the cell's own padding -- that is how the whole cell becomes clickable on
 * Retouren. Here the padding was moved onto the label and the cell set to zero,
 * but the negative margin stayed: the label then stuck fourteen pixels out of a
 * cell that had nothing left to spill into, and lay on top of its neighbour.
 * That is why a truncated product title ran straight into the brand beside it.
 * Measured: the Brand label started fourteen pixels to the left of the Brand
 * column. */
.comp-tabel tr.rij > td > label.rijlink {
  margin: 0; padding: 10px 12px; box-sizing: border-box; height: 100%;
  display: flex; align-items: center;
}
/* 'height: 1px' is what makes 'height: 100%' on the label resolve against the
   row instead of against nothing.
 *
 * Without it the label is as tall as its own text -- measured 35 pixels in a
 * row of 42, because the row is set by the tallest cell and that is the one
 * with a pill in it. Those seven pixels are a band across every row where a
 * click does nothing, which is the same dead zone as before, only horizontal
   instead of at the edge. A table cell ignores 'height' as a minimum, so the
   1px is not a size but a way of saying "definite". */
.comp-tabel tr.rij > td { height: 1px; }
/* A flex item does not shrink below its content by default, and then
   'text-overflow' never fires. */
.comp-tabel td.comp-naam > .rijlink > *, .comp-tabel td.comp-merk > .rijlink {
  min-width: 0;
}
.comp-tabel td.metchev > .rijlink { display: flex; align-items: center; gap: 7px; }

/* Een schakelaar is een knop in een eigen formuliertje. 'display: inline' op het
   formulier, anders zet de browser er een blok van en springt elke rij een
   regel hoger dan zijn buren. */
form.comp-schakel { display: inline; }
.comp-knop { cursor: pointer; font: inherit; font-weight: 600; }
.comp-knop:hover { filter: brightness(.96); }

/* Per LVB-item: acht kolommen waarvan zes een invoerveld zijn. De velden kregen
   elk hun eigen breedte van de browser, en dan staan de randjes van rij tot rij
   een paar pixels verschoven -- dat is wat "rommelig uitgelijnd" betekent. Vaste
   breedtes per kolom, en de getallen rechts zoals overal in dit dashboard. */
.vr-items td, .vr-items th { vertical-align: middle; }
.vr-items input[type="text"], .vr-items select { width: 100%; box-sizing: border-box; }
.vr-items th:nth-child(5), .vr-items td:nth-child(5),
.vr-items th:nth-child(7), .vr-items td:nth-child(7),
.vr-items th:nth-child(8), .vr-items td:nth-child(8) { width: 7.5rem; text-align: right; }
.vr-items td:nth-child(5) input, .vr-items td:nth-child(7) input,
.vr-items td:nth-child(8) input { text-align: right; }
.vr-items th:nth-child(9), .vr-items td:nth-child(9) { width: 6.5rem; }
.vr-items th:nth-child(10), .vr-items td:nth-child(10) { width: 10rem; }
/* De twee vinkkolommen: smal en gecentreerd, zodat het vinkje onder zijn kop
   staat in plaats van links tegen de rand. */
.vr-items th:nth-child(4), .vr-items td:nth-child(4),
.vr-items th:nth-child(6), .vr-items td:nth-child(6) { width: 6rem; text-align: center; }
.vr-items td:nth-child(4) input, .vr-items td:nth-child(6) input { margin: 0; }
/* De prioriteitskeuze is smal: er staan vijf waarden in van één teken. */
.vr-prio { padding: 3px 6px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; }
.vr-bulk .vr-prio { width: auto; }

/* Het tabblad Zending controle. De hele rij is de uitklaplink, dus elke cel
   draagt een <a> die de cel vult -- zo is er geen strookje waar een klik niets
   doet, en blijft de tekst gewoon selecteerbaar. Geen onderstreping en geen
   linkkleur: het is een rij, geen link in een zin. */
.vr-ztabel td { padding: 0; }
.vr-ztabel td > a.vr-zrij {
  display: block; padding: 9px 12px; color: inherit; text-decoration: none;
}
.vr-ztabel .pa-rechts > a.vr-zrij { text-align: right; }
/* Een cel die niet in de uitklaplink zit, draagt zijn padding zelf.

   De padding van deze tabel staat op 'a.vr-zrij' en niet op de cel, want die
   link vult de hele cel zodat je overal kunt klikken. De Controle-cel heeft die
   link niet -- daar staat een knop in, en een formulier binnen een link is
   ongeldige HTML. Zonder deze regel staat die ene cel strak tegen de rand en is
   hij lager dan zijn buren; gemeten op 2026-09-28 scheelde dat de volle 18
   pixels van de verticale padding, en dat zie je over de hele kolom. */
.vr-ztabel td.vr-zkaal { padding: 9px 12px; }
.vr-ztabel tbody tr.vr-zkop:hover { background: #f9fafb; }
.vr-ztabel tbody tr.vr-zkop.aan { background: #eff6ff; }
/* Het pijltje draait mee bij het openklappen; een overgang maakt zichtbaar dat
   het dezelfde rij is en geen nieuwe. */
.vr-zpijl { display: inline-block; transition: transform .12s ease; color: #9ca3af; }
.vr-zpijl.aan { transform: rotate(90deg); color: #374151; }
/* De regels van een uitgeklapte zending. De tabel eromheen schuift horizontaal,
   dus dit blok blijft plakken -- dezelfde ingreep als op de retourpagina, en met
   dezelfde voorwaarde: geen voorouder met een andere overflow dan visible.

   De detailrij draagt dezelfde tint als de open koprij (.vr-zkop.aan) en niet
   het grijs dat er stond. Dat grijs maakte er twee dingen van: een blauwe rij
   met daaronder een grijs vak, terwijl het één uitgeklapte zending is. */
.vr-ztabel td.vr-zdetail-cel, .vr-zdetail > td {
  padding: 0 !important; background: #eff6ff; overflow: visible;
}
/* Het blok is het enige kader, in de .card-taal: één witte doos met een rand.
   Er stond een grijze cel met daarin een witte tabel met een eigen rand en
   radius, binnen de al omrande buitentabel -- een doos in een doos in een doos.

   De linker accentrand hoort bij de tint erboven: kop en detail lezen als één
   blok in plaats van als twee dingen die elkaar raken.

   Marge links gelijk aan de vinkkolom (34px), zodat het blok uitlijnt met de
   eerste echte kolom. Er stond 'padding-left: 40px', en dat lijnde met niets.

   De breedte komt uit een variabele die een script uit de werkelijke breedte
   van het scrolvak zet; er stond een harde 'min(100%, 1100px)', en 1100 is een
   gok die op een breed scherm ruimte laat en op een smal scherm eroverheen
   loopt. Zonder script blijft de terugval staan en werkt alles zoals het werkte. */
.vr-zblok {
  position: sticky; left: 0;
  max-width: min(var(--vr-zbreedte, 980px), 100%);
  margin: 10px 12px 14px 34px;
  padding: 12px 14px 14px;
  background: #fff;
  border: 1px solid #dbeafe;
  border-left: 3px solid #2e6bff;
  border-radius: 10px;
}
/* De geneste tabel verliest zijn eigen rand en radius: het blok eromheen is het
   kader. Twee kaders om dezelfde inhoud is wat de uitklap rommelig maakte. */
.vr-zblok .pa-tabel { background: transparent; border: 0; border-radius: 0; }
.vr-zblok .pa-tabel th { font-size: 12px; }
/* Eén samenvattingsregel boven de geneste tabel, in de pillentaal die dit
   dashboard elders al gebruikt. Zonder die regel dubbelen de koppen van de
   uitklap de woorden van de rij erboven in 12px, en staat er niets dat zegt
   waar je naar kijkt. */
.vr-zsom {
  display: flex; flex-wrap: wrap; gap: 6px 8px;
  margin: 0 0 10px; font-size: 12px; color: #475467;
}
.vr-zsomdeel {
  padding: 2px 8px; border-radius: 999px;
  background: #f2f4f7; color: #344054; white-space: nowrap;
}
/* De drie downloadknoppen van een aanmelding: te weinig, te veel, en alles.
   Ze stonden als een losse link vlak boven de samenvattingsregel, en daar plakte
   de knop tegen de tekst eronder -- de eigenaar vroeg (2026-10-06) om meer wit.
   Een eigen rij met een marge eronder in plaats van een marge op de knop zelf:
   zo blijft .pa-knop overal even groot, en groeit de ruimte mee zodra er een
   vierde bestand bij komt. */
/* De Zoho-pagina: verdelingstabellen met een balk, en de maandgrafiek. */
/*
 * Een brede tabel schuift binnen zijn eigen blok en niet met de pagina mee.
 * Dat moet hier, want .card staat op overflow-x hidden: zonder dit blok
 * wordt een kolom op een smal scherm niet afgekapt maar onbereikbaar.
 */
.zo-schuif { overflow-x: auto; }
.zo-verdeling { width: 100%; border-collapse: collapse; min-width: 420px; }
.zo-verdeling th, .zo-verdeling td { padding: 7px 10px; border-bottom: 1px solid var(--line); font-size: 13px; }
.zo-verdeling th { text-align: left; font-weight: 600; color: var(--muted); }
.zo-verdeling .r { text-align: right; white-space: nowrap; }
/* De balkkolom neemt wat er over is; de getallen ernaast blijven leesbaar. */
.zo-verdeling th.balk, .zo-verdeling td.balk { width: 34%; min-width: 90px; }
.zo-verdeling td.balk span { display: block; height: 8px; border-radius: 4px; background: var(--action); min-width: 2px; }
.zo-grafiek { width: 100%; height: 150px; display: block; }
.zo-grafiek rect { fill: var(--action); }
.zo-maandnamen { display: flex; gap: 0; font-size: 11px; color: var(--muted); }
.zo-maandnamen span { flex: 1 1 0; text-align: center; }

.vr-zcsv {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 2px 0 18px;
}
/* Een formulier dat zich in een filterrij gedraagt als de knoppen ernaast.
   Zonder dit is het een blokelement dat de rij breekt -- de knop *Vernieuwen*
   op LVB order moet een formulier zijn (hij verandert iets aan de serverkant,
   en een browser mag een link vooruitladen) maar hoort er niet anders uit te
   zien dan Export of Copy EANs. */
.pa-inline { display: inline-flex; margin: 0; }
/* De tabel van *Instellingen per product* op Stock management.
   Gemeten in een echte browser op 1280 punten: zonder dit werd hij 3.680 pixels
   breed in een vak van 943, met een productkolom van 1.548 -- alleen EAN en
   Product waren te zien en elk invoerveld stond buiten beeld. De oorzaak is dat
   de titels niet afkapten en de velden geen maat hadden, dus de browser gaf elk
   getalveld 192 pixels. Vaste indeling met de maten op de koppen, zoals bij de
   groepstabellen van Zending controle, en de titel kapt af met de volledige
   tekst in de tooltip. Rijhoogte van 53 naar de 33 die het tabblad ernaast
   heeft. */
/* De minimumbreedte is de som van de vaste kolommen plus ruimte voor de titel,
   en niet een rond getal: bij 1.180 kreeg de productkolom de 44 pixels die
   overbleven en stond er "ZE..." in elke rij. 140 + 76 + 10x92 = 1.136 vast,
   dus 1.420 laat er 284 over -- genoeg voor een herkenbare titel. */
.ik-items { table-layout: fixed; width: 100%; min-width: 1420px; }
.ik-items th:nth-child(1) { width: 140px; }
.ik-items th:nth-child(2) { width: auto; }
.ik-items th:nth-child(3) { width: 76px; }
.ik-items th:nth-child(n+4) { width: 92px; }
.ik-items td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ik-items th, .ik-items td { padding-top: 4px; padding-bottom: 4px; }
/* Een invoerveld vult zijn kolom in plaats van een eigen breedte te kiezen. */
.ik-items td input[type="text"] { width: 100%; min-width: 0; box-sizing: border-box; }
/* Te weinig en te veel staan als twee blokken onder elkaar, elk met hun eigen
   kop. Het zijn twee soorten werk met twee verschillende partijen erachter --
   een tekort gaat over de zending, een overschot over je eigen administratie --
   en op een gedeelde lijst leest iemand telkens langs de andere heen. */
.vr-zgroep + .vr-zgroep { margin-top: 16px; }
.vr-zgroepkop {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 6px; font-size: 13px; font-weight: 600; color: #344054;
}
.vr-zgroepaantal {
  padding: 1px 8px; border-radius: 999px;
  background: #f2f4f7; color: #475467;
  font-size: 11px; font-weight: 500; white-space: nowrap;
}
/* De twee groepstabellen lijnen uit, en dat moet afgedwongen worden.
   Gemeten in een echte browser op 1280 punten: zonder dit werd de ene tabel
   1.183 en de andere 878 pixels breed, met een productkolom die 457 tegen 109
   pixels kreeg. Twee tabellen met dezelfde negen kolommen die niet onder elkaar
   staan, zijn precies wat "niet netjes" betekent -- en in de ene tabel viel de
   helft van de kolommen daardoor buiten het blok.
   Vaste indeling met de maten op de koppen: dan hangt de breedte af van de
   kolom en niet van de langste producttitel die er toevallig in staat. De
   titel kapt af met een beletselteken en staat volledig in de tooltip, zoals
   overal op dit scherm.
   De zeven getalkolommen staan op 78 en niet op 92 pixels: breder dan het
   langste getal dat er in past, en wat eraf gaat komt bij de producttitel --
   die is de enige kolom die van langer worden beter wordt. Nagemeten op 1280
   punten: 118 / 200 / 7x78. */
.vr-zgroep .pa-tabel { table-layout: fixed; width: 100%; }
.vr-zgroep .pa-tabel th:nth-child(1) { width: 118px; }
.vr-zgroep .pa-tabel th:nth-child(2) { width: auto; }
.vr-zgroep .pa-tabel th:nth-child(n+3) { width: 78px; }
.vr-zgroep .pa-tabel td {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* De kolom Verschil. Nul is groen (alles is verkoopbaar of nog onderweg), boven
   nul rood, en onder nul nadrukkelijk geen van beide: bol ontving meer dan er
   aangemeld was, en daar mist niets. Een negatief getal groen maken zou het als
   winst lezen; rood als tekort. Het is geen van tweeen. */
.vr-verschil { font-variant-numeric: tabular-nums; }
.vr-verschil.goed { color: #067647; }
.vr-verschil.slecht { color: #b42318; font-weight: 600; }
.vr-verschil.neutraal { color: #b54708; }
/* De knop *Opslaan* nadat er werkelijk opgeslagen is. Niet uitgezet -- de tabel
   is meteen weer te bewerken -- alleen groen, zodat het verschil tussen
   "gelukt" en "ik heb misschien niet gedrukt" te zien is. */
.button.vr-opgeslagen {
  background: #067647; border-color: #067647; color: #fff;
}
/*
 * De drie standen van het LVB-advies op het voorraadscherm.
 *
 * Rood, geel, groen -- de volgorde van een stoplicht, want dat is precies wat
 * deze kolom is: hoe ver is de dag waarop de doos weg moet. "Te laat" ligt
 * achter ons, "Verzenden" is deze week, "Gezond" kan wachten.
 *
 * Rood mag hier, in tegenstelling tot bij de vorige opzet: die had een tag
 * (tekort) die geen alarm was maar werk voor de inkoop, en die stond naast de
 * rode regel van "hier ligt niets meer". Het tekort staat nu in de tooltip van
 * de pil, en rood betekent op deze kolom precies één ding.
 */
.pa-telaat { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
.pa-verzenden { background: #fef3c7; color: #b45309; border: 1px solid #fde68a; }
.pa-gezond { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
/* Een winkel waar het aanbod op pauze staat: hij bestaat, hij verkoopt niet. */
.pa-hold { background: #f3f4f6; color: #6b7280; border: 1px solid #e5e7eb; }
/*
 * Placements.
 *
 * Twintig kolommen naast elkaar is veel, en dat is de opdracht: de vraag op dit
 * scherm is vergelijkend. Wat het leesbaar houdt is niet minder kolommen maar
 * rust -- cijfers rechts uitgelijnd op tabulaire cijfers, tekst afgekapt in
 * plaats van omgebroken, en de kop die blijft staan tijdens het scrollen.
 */
.placement-tabel { font-size: 12.5px; }
.placement-tabel th, .placement-tabel td { padding: 9px 10px; white-space: nowrap; }

/* De kop blijft staan; zonder dit weet je bij rij tachtig niet meer welke kolom
   je leest, en dan is horizontaal scrollen een gok. */
.placement-tabel thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--card); border-bottom: 1px solid var(--line-strong);
}

/* Tekstkolommen mogen breed zijn maar niet ongelimiteerd: één campagnenaam van
   negentig tekens duwt anders elke cijferkolom uit beeld. */
.placement-tabel td.breed { max-width: 260px; }
.placement-tabel .tekst, .placement-tabel .scope {
  display: block; overflow: hidden; text-overflow: ellipsis; max-width: 260px;
}
.placement-tabel .scope { color: var(--muted); font-size: 12px; }
.placement-tabel .scope .pijl { color: var(--faint); }
.placement-tabel .onder-ean {
  display: block; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums;
}
.placement-tabel .soort { font-size: 11.5px; color: var(--muted); }

/* Een bod boven de eigen grens is de reden dat die kolom bestaat. */
.placement-tabel .over { color: var(--bad-text); font-weight: 700; }

/* De ster achter een positie zegt: die plek is gekocht, niet verdiend. */
.placement-tabel .ster { color: var(--faint); margin-left: 1px; }

/* Het totaal hoort bij de tabel maar is geen regel erin. */
.placement-tabel tfoot .totaal td {
  border-top: 2px solid var(--line-strong); font-weight: 700; background: var(--card);
  position: sticky; bottom: 0;
}

/*
 * De identiteitskolom blijft staan tijdens het schuiven.
 *
 * Dezelfde reden als de vastgezette koprij, één as gedraaid: bij kolom vijftien
 * weet je zonder dit niet meer wélk zoekwoord je leest, en dan is elke cel
 * ernaast een getal zonder onderwerp. Het vinkje gaat mee, anders klik je een
 * regel aan die je niet ziet.
 */
.placement-tabel th.kies, .placement-tabel td.kies { position: sticky; left: 0; z-index: 3; }
.placement-tabel th.vast, .placement-tabel td.vast { position: sticky; left: 34px; z-index: 3; }
.placement-tabel td.kies, .placement-tabel td.vast { background: var(--card); }
/* De koppen staan op twee assen tegelijk vast en horen dus bovenop. */
.placement-tabel thead th.kies, .placement-tabel thead th.vast { z-index: 4; }
/* Een randje maakt zichtbaar dat de rest eronderdoor schuift. */
.placement-tabel th.vast, .placement-tabel td.vast { box-shadow: 1px 0 0 var(--line); }

/* De acties staan in de kop van het paneel en niet erboven: het zijn twee
   handelingen op deze tabel, geen navigatie over het scherm. */
.kop-acties { display: flex; gap: 8px; }
.kop-acties .button { padding: 6px 12px; font-size: 12px; }

/* Het filterblok ademt minder dan een paneel met inhoud; anders staan de
   cijfers een half scherm lager dan de filters die ze bepalen. */
.filterblok .paneel-lijf { padding: 16px 20px 18px; }
.filterblok .veldrij { margin-bottom: 12px; }
.filterblok textarea {
  width: 100%; font: inherit; font-size: 13px; padding: 8px 10px;
  border: 1px solid var(--line-strong); border-radius: 8px; resize: vertical;
}

/* ── Het voorraadscherm ───────────────────────────────────────────────
 *
 * Leunt op de tabel en de chips van de promotie-agenda hierboven: het is
 * dezelfde soort pagina -- een brede tabel met een filterblok erboven -- en een
 * tweede set klassen die er net anders uitziet, is precies hoe een dashboard
 * uit elkaar groeit. Wat hier staat is alleen wat dat scherm extra nodig heeft.
 */
.voorraad .paneel-kaart { margin-bottom: 18px; }
.voorraad .stat-rij { margin-bottom: 12px; }

/* Het filterblok: velden naast elkaar, en op een smal scherm onder elkaar. */
.pa-paneel-body { padding: 14px 16px; }
.pa-velden { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; margin: 0 0 12px; }
.pa-velden label { display: flex; flex-direction: column; gap: 4px;
     font-size: 12px; font-weight: 500; color: var(--muted); }
.pa-velden input[type=text], .pa-velden textarea {
  font: inherit; font-size: 13px; padding: 7px 10px; min-width: 240px;
  border: 1px solid var(--line-strong); border-radius: 8px; resize: vertical;
}

/*
 * Het instellingenpaneel van het LVB-advies: acht velden in een raster.
 *
 * Een raster en geen rij die omslaat (2026-09-04, op verzoek van de eigenaar).
 * Met flex-wrap bepaalde de breedte van elk label waar de volgende begon, dus
 * lijnde er niets uit en verschoof de tweede regel bij elke andere waarde.
 * Kolommen van gelijke breedte doen dat niet, en bij een smal scherm worden het
 * er vanzelf minder.
 *
 * Labels boven hun veld, en het label omsluit het veld niet: dat laatste ging op
 * het Team-scherm mis, en display:block zet dat niet recht. Vandaar for/id in
 * plaats van een omhullend label -- ook omdat er een details-uitklapper naast
 * staat, en een klik daarop hoort geen invoerveld te focussen.
 *
 * De uitleg zit achter de i en staat niet meer als regel onder het veld. Acht
 * velden met elk twee regels toelichting is een paneel dat je wegklikt zonder te
 * lezen; dit is hetzelfde idioom als de i op de Promotie-agenda.
 */
.vr-instellingen { display: grid; gap: 16px 18px;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); align-items: start; }
.vr-veld { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.vr-kop { display: flex; align-items: center; gap: 6px; }
.vr-label { font-size: 12px; font-weight: 600; color: var(--muted); }
.vr-instellingen input[type=text] {
  font: inherit; font-size: 13px; padding: 7px 10px; width: 100%; box-sizing: border-box;
  border: 1px solid var(--line-strong); border-radius: 8px;
}
/* De knoppen staan onder het hele raster en niet in een cel ernaast: opslaan
   gaat over alle acht de velden tegelijk. */
/* Ook deze rij vouwt: op 390 stond *Verwijderen* 64 pixels en zijn i 92 pixels
   buiten beeld. Gemeten 2026-09-07. */
.vr-knoppen { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  grid-column: 1 / -1; }
/* Een formule is een expressie en geen getal: die past niet in een cel van
   170 pixels. Over de hele breedte, met de woordenlijst achter de i. */
.vr-breed { grid-column: 1 / -1; }

/*
 * De formulebouwer: zes rijen van bewerking, kolom en getal.
 *
 * Rijen onder elkaar en geen raster van drie kolommen (2026-09-08). De
 * kolomkeuze draagt een omschrijving en is dus veel breder dan de twee andere
 * velden; in een raster met gelijke kolommen zou hij afgekapt worden terwijl
 * het getalvak driekwart leeg blijft staan.
 *
 * Elke rij vouwt, want deze drie velden samen zijn minimaal ~300 pixels breed
 * en dit paneel staat ook op een telefoon. De kolomkeuze krijgt de rest van de
 * ruimte, de twee andere een vaste breedte: een bewerking is één teken en een
 * getal zijn er hoogstens een paar, en die mee laten groeien geeft een rij
 * waarin het oog het belangrijkste veld niet meer vindt.
 *
 * De lege plek op de eerste rij heeft dezelfde breedte als een keuzelijst.
 * Zonder die plek schuift de eerste rij op en lijnt er niets uit -- dezelfde
 * fout als de labels op het Team-scherm, en net zo goed alleen in een browser
 * te zien.
 */
.vr-bouwer { display: flex; flex-direction: column; gap: 6px; }
.vr-slot { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-width: 0; }
.vr-slotnr { width: 14px; flex: none; font-size: 12px; color: var(--muted);
  text-align: right; }
.vr-instellingen .vr-slot select, .vr-instellingen .vr-slot input[type=text] {
  font: inherit; font-size: 13px; padding: 7px 10px; box-sizing: border-box;
  border: 1px solid var(--line-strong); border-radius: 8px; background: var(--card);
  color: inherit; min-width: 0;
}
.vr-slot .vr-op, .vr-slot .vr-geenop { width: 62px; flex: none; }
.vr-slot .vr-term { flex: 1 1 220px; min-width: 0; }
.vr-instellingen .vr-slot .vr-getal { width: 92px; flex: none; }

/*
 * Wat er nú gerekend wordt, onder de rijen.
 *
 * Nodig omdat de rijen aaneengeregen worden en met rekenkundige voorrang
 * gelezen: wie ze van boven naar beneden leest komt op iets anders uit. Klein
 * en in de muted-kleur, want het is een aantekening bij de keuze en niet de
 * keuze zelf -- behalve bij een formule die niet in de rijen past; die staat
 * hier als enige plek waar hij te zien is.
 */
.vr-nu { margin: 2px 0 0; font-size: 12px; color: var(--muted); }
.vr-nu code { font-size: 12px; }
.vr-behoud code { color: var(--text); }
.vr-wis { display: flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--muted); }

/*
 * Het tabblad Per LVB-item is een invulformulier in tabelvorm.
 *
 * Zonder dit blok is een invulrij anderhalf keer zo hoog als een leesrij in de
 * adviestabel ernaast: de globale invoeropmaak (8px padding, 10px radius) telt
 * op bij de 9px van '.pa-tabel td'. Twee tabbladen van hetzelfde scherm horen
 * dezelfde regelhoogte te hebben, anders leest het als twee schermen.
 *
 * Links uitlijnen en niet rechts: de getallen hier zijn invoervelden en geen
 * uitkomsten. Bij een uitkomst helpt rechts uitlijnen om cijfers onder elkaar
 * te kunnen vergelijken; bij een veld waar je in typt begint de tekst waar je
 * cursor komt te staan, en dat is links.
 */
.vr-items td { padding: 3px 12px; text-align: left; }
.vr-items th { text-align: left; }
.vr-items input[type=text], .vr-items select {
  font: inherit; font-size: 13px; padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--line-strong); text-align: left;
}
.vr-items input[type=checkbox] { margin: 0; }

/* Het invoerveld voor 'Aantal naar LVB' op het tabblad LVB order.

   Smal en rechts uitgelijnd, zodat de kolom blijft lezen als een getallenkolom
   en niet als een formulier: er staan er honderdtachtig onder elkaar, en een
   rij invoervakken over de volle kolombreedte maakt de tabel onleesbaar.

   Een veld met een eigen waarde krijgt een accentrand. Zonder dat verschil is
   een regel die iemand met de hand gezet heeft niet te onderscheiden van een
   regel die het advies volgt -- en dat is precies wat je op deze lijst wilt
   zien. De placeholder draagt het advies, dus een leeg veld toont nog steeds
   een getal; grijs, zodat het als voorstel leest en niet als invoer. */
.vr-aantal {
  font: inherit; font-size: 13px; padding: 2px 6px; border-radius: 6px;
  border: 1px solid var(--line-strong); text-align: right; width: 5.5em;
}
.vr-aantal:not(:placeholder-shown) { border-color: #2e6bff; font-weight: 600; }
.vr-aantal::placeholder { color: var(--muted); opacity: 1; }

/* Een rij aanklikken zet zijn vinkje om; zie 'rijScript'. De aanwijzer zegt dat
   vooraf, want een klikgebied dat je niet ziet is geen knop maar een verrassing.
   Alleen op tabellen die zo'n vinkje hébben. */
.voorraad .pa-tabel tbody tr:has([data-vr-kies]) { cursor: pointer; }
.voorraad .pa-tabel tbody tr:has([data-vr-kies]:checked) > td { background: #f5f8ff; }

/* De bulkactie op het tweede tabblad: een veld en een knop, naast Opslaan.
   Ze horen bij elkaar, dus ze staan als één geheel in de paneelkop en niet als
   twee losse knoppen tussen de rest. */
.vr-bulk { display: inline-flex; gap: 6px; align-items: center; }
.vr-bulk input[type=text] { font: inherit; font-size: 13px; padding: 6px 9px;
  border-radius: 8px; border: 1px solid var(--line-strong); width: 130px; }
.vr-bulkuitleg { margin: 0 0 10px; }

/* Het instellingenpaneel van de Promotie-agenda: wanneer er post uitgaat,
   waarover en naar wie. Zelfde raster-idioom als de LVB-instellingen, maar met
   brede velden: hier staat een sjabloon in en geen getal. */
.pm-form { display: flex; flex-direction: column; gap: 16px; }
.pm-veld { display: flex; flex-direction: column; gap: 6px; }
.pm-kort { max-width: 220px; }
.pm-label { font-size: 12px; font-weight: 600; color: var(--muted); }
/* Het label met zijn i ernaast, op één regel. Zo staat elk veld even hoog en
   lijnen de velden in een rij netjes uit -- wat met een losse uitlegregel onder
   het ene veld en niet onder het andere juist niet gebeurde. */
.pm-kop { display: flex; align-items: center; gap: 6px; min-height: 18px; }
.pm-form textarea { font-family: inherit; font-size: 13px; }
/* Het sjabloonveld is code en leest beter in een vaste breedte; de adressen en
   de gewone tekstvakken niet. */
.pm-form textarea[name=sjabloon] { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; }
/* Velden in een rij: allemaal even hoog beginnen, en de korte velden niet
   uitrekken. */
.pm-rij { align-items: flex-start; }
.pm-rij .pm-kort { flex: 0 0 auto; min-width: 0; }
.pm-hint { font-size: 12px; color: var(--faint); line-height: 1.45; }
.pm-waarschuwing { color: var(--bad-text); }
.pm-form input[type=text] { font: inherit; font-size: 13px; padding: 7px 10px;
  border: 1px solid var(--line-strong); border-radius: 8px; box-sizing: border-box; }
.pm-form textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.5; padding: 10px 12px; border-radius: 8px;
  border: 1px solid var(--line-strong); }
.pm-aan { display: flex; align-items: center; gap: 8px; font-size: 13px;
  color: var(--body); font-weight: 400; margin: 0; }

/* Een veld per ontvanger, onder elkaar. Het onderste veld is altijd leeg -- zo
   voeg je zonder JavaScript een adres toe -- en de x en de knop "+ adres" zet
   het script erbij; zonder script staan hier alleen de velden. */
.pm-adressen { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.pm-form input[type=email] { font: inherit; font-size: 13px; padding: 7px 10px;
  border: 1px solid var(--line-strong); border-radius: 8px; box-sizing: border-box;
  width: 100%; max-width: 340px; }
.pm-adres { display: flex; align-items: center; gap: 6px; width: 100%; max-width: 380px; }
.pm-adres input[type=email] { flex: 1; min-width: 0; }
.pm-adres-weg { flex: 0 0 auto; border: 1px solid var(--line-strong); background: none;
  border-radius: 8px; width: 28px; height: 28px; line-height: 1; font-size: 15px;
  color: var(--muted); cursor: pointer; }
.pm-adres-weg:hover { border-color: var(--bad-text); color: var(--bad-text); }
.pm-adres-erbij { border: 1px dashed var(--line-strong); background: none; border-radius: 8px;
  padding: 6px 10px; font: inherit; font-size: 12.5px; color: var(--muted); cursor: pointer; }
.pm-adres-erbij:hover { border-color: var(--brand); color: var(--brand); }

/* De dagen als een rij vakjes en niet als een keuzelijst: je kiest er meerdere,
   en welke er aanstaan wil je in één oogopslag zien. */
.pm-dagen { display: flex; flex-wrap: wrap; gap: 6px; }
.pm-dag { display: inline-flex; align-items: center; gap: 6px; margin: 0;
  padding: 6px 10px; border: 1px solid var(--line-strong); border-radius: 999px;
  font-size: 13px; color: var(--body); cursor: pointer; }
.pm-dag:has(input:checked) { border-color: var(--brand); background: var(--info-bg); }

/*
 * De dagvinkjes gelden niet bij "als er campagnes beginnen", en dat moet in het
 * veld zelf te zien zijn.
 *
 * Bij die soort bepaalt bols agenda de dag. Dat stond alleen in de uitleg achter
 * de i, en daar leest niemand het: de eigenaar vinkte dagen aan die nergens
 * heengingen. De opmaak draagt daarom twee koppen en hier staat welke er te zien
 * is.
 *
 * Op ':has()' van de radio en niet op een klasse die de server meegeeft. Dat is
 * geen script -- dezelfde selector als bij '.pm-dag' hierboven -- en het is het
 * enige dat óók klopt voordat je opslaat: de soort ligt pas na een POST vast,
 * dus een kop uit de opgeslagen waarde zou tot dat moment het verkeerde zeggen.
 * Kent een browser ':has()' niet, dan staat er de gewone kop en is er niets
 * verloren.
 *
 * De vinkjes zelf worden gedimd en niet uitgezet: hun waarde wordt gewoon
 * bewaard, dus wie terugschakelt naar een soort die ze wél gebruikt vindt zijn
 * keuze terug. 'pointer-events: none' zou een veld op slot zetten waarvan de
 * inhoud er nog steeds toe doet.
 */
.pm-dagenkop-niet { display: none; }
.pm-form:has(input[name=soort][value=campagne_start]:checked) .pm-dagenkop-wel { display: none; }
.pm-form:has(input[name=soort][value=campagne_start]:checked) .pm-dagenkop-niet { display: block; }
.pm-form:has(input[name=soort][value=campagne_start]:checked) .pm-dagenveld .pm-dagen {
  opacity: 0.55; }

.pm-onderwerpen { display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.pm-onderwerp { display: flex; align-items: baseline; gap: 8px; margin: 0;
  font-size: 13px; color: var(--body); font-weight: 400; }
/* Het token naast zijn eigen aanvinkvakje: zo hoef je nergens op te zoeken welk
   blok bij welke plaatshouder hoort. */
.pm-token { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; color: var(--faint); }

/* De knoppen rechts in de tabbladenbalk: Instellingen en de schakelaar voor
   automatisch voorstellen, met hun uitleg achter een i. Op één regel, zodat de
   agenda eronder niet weggeduwd wordt door een blok dat je zelden leest. */
.pa-tabs-rechts { margin-left: auto; display: inline-flex; flex-wrap: wrap;
  gap: 8px; align-items: center; }
.pa-tabs-knop { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin: 0; }

/*
 * Een uitlegvenster dat rechts staat, opent naar links.
 *
 * '.pa-uitleg p' opent altijd naar rechts ('left: 0'), en dat gaat mis zodra
 * het ankertje zelf rechts staat. Gemeten op 2026-09-07: het venster van
 * *Dagen vooruit* -- het laatste veld in zijn rij -- stak op 1280 precies 176
 * pixels buiten beeld, en op 1600 nog steeds 176: het anker schuift mee met de
 * rechterrand van de kaart, dus dit gaat op géén enkele desktopbreedte vanzelf
 * goed. Niets knipt het af, dus de hele pagina kreeg een horizontale schuifbalk
 * zodra je hem opende.
 *
 * **Achter een mediaregel, en dat is de hele truc.** Onder 640 pixels zijn de
 * rijen gevouwen en staan diezelfde ankers juist links; daar zou dezelfde flip
 * ze 115 tot 149 pixels de linkerkant uit duwen. Gemeten in beide richtingen.
 */
/*
 * Het uitlegvenster lost op tegen de kop en niet tegen de i-knop.
 *
 * Die knop staat achter de titel, dus zijn x-positie hangt af van hoe lang de
 * titel is. Het venster is min(560px, 100vw - 60px) breed en opent naar rechts,
 * en dan past het op elk venster dat niet ruim is per definitie niet. Gemeten op
 * het scherm Ads per product: op 485 punten stond het 182 pixels buiten beeld en
 * op 885 punten 170, en in beide gevallen kreeg de hele pagina een horizontale
 * schuifbalk zodra iemand het opende. Dat raakt elk scherm met zo'n venster en
 * niet alleen dit ene.
 *
 * De bestaande vlucht-naar-links verderop geldt voor .pa-uitleg en niet voor
 * .scherm-info, dus hier greep er niets.
 *
 * position: static op de uitklapper laat het venster oplossen tegen het blok
 * eromheen, en dat loopt altijd van rand tot rand -- ongeacht de titel en
 * ongeacht de breedte. Dezelfde reparatie die .cs .cs-tabs .scherm-info al
 * droeg, nu voor elk scherm.
 */
.scherm-info { position: static; }
.scherm-info .paneel { left: 0; right: auto; max-width: calc(100vw - 32px); }

@media (min-width: 640px) {
  .pm-kort .pa-uitleg p,
  .pa-tabs-rechts .pa-uitleg p,
  .vr-knoppen .pa-uitleg p { left: auto; right: 0; }
}

/* Een update in de lijst: naam, waar hij door afgaat, naar wie, en wanneer hij
   voor het laatst iets deed. Een regel per update en niet een kaart per update:
   je hebt er twee of drie, en die wil je naast elkaar kunnen lezen. */
.pm-regel { display: flex; gap: 12px; align-items: center; padding: 12px 0;
  border-top: 1px solid var(--line); }
.pm-regel:first-of-type { border-top: none; }
.pm-regel.aan { border-bottom: none; }
.pm-regel-tekst { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.pm-regel-stand { flex: 0 0 auto; }
.pm-rij { display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap; }
.pm-rij .pm-veld { flex: 1; min-width: 180px; }
.pm-soorten { display: flex; gap: 8px; flex-wrap: wrap; }
/* Het formulier van de open update staat ingesprongen onder zijn regel, zodat
   te zien is bij welke van de drie het hoort. */
.pm-form { border-left: 2px solid var(--brand); padding-left: 14px; margin: 4px 0 18px; }

/* De kant-en-klare updates: een kaart per soort, zodat je ze naast elkaar
   leest in plaats van als lijst afgaat. */
.pm-presets { display: grid; gap: 10px; margin: 10px 0 16px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.pm-preset { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px;
  border: 1px solid var(--line-strong); border-radius: 10px; text-decoration: none;
  color: var(--text); background: var(--card); }
.pm-preset:hover { border-color: var(--brand); }
.pm-preset-leeg { border-style: dashed; }

/* Het mailvoorbeeld. Vaste hoogte met een eigen schuifbalk: een mail is lang,
   en de knop terug hoort in beeld te blijven. */
.pm-voorbeeld .pm-mail { width: 100%; height: 30rem; border: 1px solid var(--line-strong);
  border-radius: 10px; background: #fff; }
.pm-onderwerpregel { font-size: 14px; color: var(--body); margin: 0 0 10px; }
.pm-tekstversie { margin-top: 12px; }
.pm-tekstversie pre { white-space: pre-wrap; font-size: 12.5px; color: var(--body);
  background: var(--page); padding: 12px; border-radius: 8px; overflow-x: auto; }

/* Een product waar niets meer van ligt. Geen rode regel -- dat is een fout, en
   dit is een besluit -- maar wel genoeg verschil om hem te zien staan. */
.voorraad tr.pa-op td { background: #fffbfa; }
.voorraad tr.pa-op td:first-child { box-shadow: inset 3px 0 0 #f97066; }

/* Wanneer elke bron gemeten heeft. Per bron, want het hele punt van twee
   bronnen is dat er een kan uitvallen. */
.voorraad .pa-voet { margin-top: 12px; font-size: 12px; color: var(--faint); }

/* ── De klantenservice ────────────────────────────────────────────────────
   Let op: backticks in commentaar sluiten de template-string waar deze
   stylesheet in staat. Het is hier al twee keer gebeurd.

   De inbox is een tweekolommenscherm: links een regel per gesprek, rechts een
   uitgewerkt gesprek. De verdeling staat vast op 340 pixels en niet op een
   percentage: een lijstregel heeft een vaste hoeveelheid tekst, en een kolom
   die meegroeit met het scherm wordt op een breed scherm een baan witruimte. */
.cs .cs-tabs { display: flex; gap: 2px; margin-bottom: 18px; position: relative;
  border-bottom: 1px solid var(--line-strong); }
/* Dezelfde ingreep als bij de i in de gesprekskop: de uitlegknop zelf static
   maken, zodat het venster oplost tegen de balk in plaats van tegen de knop.
   Die balk loopt altijd tot de rand, dus het venster past altijd -- en de knop
   staat hier helemaal rechts, waar een venster dat naar rechts opent
   gegarandeerd buiten beeld valt. Gemeten op 500 punten: 341 pixels aan
   paginabreedte erbij, precies dit venster. */
.cs .cs-tabs .scherm-info { position: static; }
.cs .cs-tabs .scherm-info .paneel { left: auto; right: 0; top: 100%; }
.cs .cs-tabs a { padding: 8px 14px; font-size: 13.5px; font-weight: 500;
  color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent;
  margin-bottom: -1px; }
.cs .cs-tabs a:hover { color: var(--body); }
.cs .cs-tabs a.aan { color: var(--action); border-bottom-color: var(--action); }

.cs .cs-melding { margin-bottom: 14px; }


/* Twee getallen op één regel, en geen rij kaarten.
   Er stonden er vier in kaarten over de volle breedte, op elk tabblad; twee
   daarvan waren archieftellers die geen handeling sturen. Wat overblijft zegt
   of er vandaag werk is, en neemt een regel in plaats van een blok. */
.cs .cs-tellers { display: flex; gap: 18px; margin: 0 0 14px; font-size: 13px; }
.cs .cs-tel { color: var(--muted); text-decoration: none; }
.cs .cs-tel:hover { color: var(--action); }
.cs .cs-tel .v { font-weight: 600; font-size: 15px; color: var(--body);
  font-variant-numeric: tabular-nums; }
.cs .cs-tel.let-op .v { color: var(--bad-text); }

.cs .cs-split { display: grid; grid-template-columns: 340px minmax(0, 1fr);
  gap: 14px; align-items: stretch; }
.cs .cs-lijst { position: sticky; top: 12px; max-height: calc(100vh - 182px);
  display: flex; flex-direction: column; }
.cs .cs-lijst > .body { overflow-y: auto; }
/* Het gesprek krijgt hetzelfde plafond als de lijst en schuift van binnen.
   Stond op align-items:start met een vrij groeiend gesprek, en dan eindigen
   de twee kolommen op verschillende hoogte: gemeten op het scherm van JDL
   market liep de lijst tot 926 en het gesprek tot 1124 -- bijna tweehonderd
   pixel rafelrand. Bij een kort gesprek is het andersom en erger: een lijst van
   760 naast een vakje van 78.
   Geen nieuw getal: dit is dezelfde calc(100vh - 140px) die de lijst al had,
   nu op allebei. min-height:0 is wat een flex-kind laat krimpen tot onder
   zijn inhoud -- zonder dat groeit de kaart gewoon door en schuift er niets. */
/* Het gesprek vúlt het venster in plaats van eronder op te houden.
   Dit stond op max-height, en dat betekent "word niet hoger dan" -- niet "word
   zo hoog". Bij een kort gesprek eindigde de kaart halverwege het scherm met
   een halve meter grijs eronder, terwijl het antwoord in een vakje van drie
   regels stond. Nu vaste hoogte, en de ruimte wordt binnen de kaart verdeeld. */
.cs .cs-detail { position: sticky; top: 12px; height: calc(100vh - 182px);
  display: flex; flex-direction: column; min-height: 0; }
.cs .cs-detail > .card { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* De kaart schuift zelf niet: hij verdeelt. Het antwoord en de knoppen krijgen
   de hoogte die ze nodig hebben, en wat er overblijft is voor het gesprek --
   dat schuift vanbinnen. Zo staat de knop Versturen altijd op het scherm en
   is het concept altijd in zijn geheel te lezen, ongeacht hoe lang de draad is. */
.cs .cs-detail > .card > .body { display: flex; flex-direction: column;
  min-height: 0; overflow: hidden; gap: 0; }
/* Het gesprek krijgt een eerlijk deel van de kaart en niet wat er overblijft.
   Met alleen flex:1 1 auto at het meegroeiende antwoordveld alles op: het
   gesprek zakte naar negentig pixels en dan is er niets meer te lezen, laat
   staan terug te scrollen. Nu minstens een derde van de hoogte, en het
   antwoord krijgt de rest. */
.cs .cs-detail > .card > .body > .cs-gesprek { flex: 1 1 34%; min-height: 6rem; }
.cs .cs-detail > .card > .body > .cs-knoppen,
.cs .cs-detail > .card > .body > .cs-taakregel,
.cs .cs-detail > .card > .body > .cs-herschrijf-stand { flex: 0 0 auto; }
/* Het antwoord mág krimpen, en dat is het vangnet onder de belofte van dit
   raster: de knop Versturen staat altijd op het scherm.

   Hij stond op flex: 0 0 auto -- neem wat je nodig hebt, krimp nooit -- en
   dat gaat goed zolang je weet hoe hoog hij wordt. Sinds er een Engelse
   leeshulp boven het concept kan staan, weet je dat niet: gemeten op zaak #46
   bij 1440x900 werd het blok 278 pixels hoger en vielen de knoppen **392
   pixels** buiten de kaart. Zonder schuifbalk, want de kaart staat op
   overflow: hidden -- dus geen knop, geen melding, niets dat erop wijst.

   In het Nederlands paste dezelfde zaak met één pixel over. Dat is geen marge
   maar toeval, en het gold voor élk lang concept op een lager scherm.

   Nu krimpt het antwoordblok als het moet en schuift het vanbinnen, net als
   het gesprek erboven. De knoppen zijn een broer met flex: 0 0 auto en
   houden dus altijd hun plek. */
.cs .cs-detail > .card > .body > .cs-antwoord { flex: 0 1 auto; min-height: 5rem;
  overflow-y: auto; }

/* Het vragenraster van de instellingen. Vier kolommen met velden van
   verschillende hoogte gaven een rafelige onderkant; nu lijnt elke rij uit op
   zijn hoogste veld en staat het invoerveld onderaan de cel. */
/* Elke vraag een eigen regel, met het antwoord eronder. Genummerd, zodat er
   naar te verwijzen is -- dezelfde reden als bij de soorten vragen. */
.cs .cs-vragenlijst { list-style: none; counter-reset: vraag; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 18px; }
.cs .cs-vragenlijst > li { counter-increment: vraag; padding-left: 30px; position: relative; }
.cs .cs-vragenlijst > li::before { content: counter(vraag); position: absolute; left: 0; top: 1px;
  width: 22px; text-align: right; font-size: 12px; font-weight: 600; color: var(--faint); }
.cs .cs-vragenlijst > li > label { display: flex; flex-direction: column; gap: 4px; }
.cs .cs-vraagtekst { font-size: 13.5px; font-weight: 600; color: var(--text); }
.cs .cs-vragenlijst small { margin-bottom: 4px; }
.cs .cs-vragenlijst textarea, .cs .cs-vragenlijst input { width: 100%; font-family: inherit;
  font-size: 13px; line-height: 1.55; }
/* Leeg is hier geen neutrale toestand maar een gat in wat het systeem weet. */
.cs .cs-vragenlijst > li.leeg::before { color: var(--warn-text); }
.cs .cs-vragenlijst > li.leeg textarea, .cs .cs-vragenlijst > li.leeg input {
  border-color: var(--warn-line); background: #fffdf7; }

.cs .cs-vragen { display: grid; gap: 14px 18px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); align-items: stretch; }
.cs .cs-vraag { display: flex; flex-direction: column; min-width: 0; }
/* Het invoerveld onderaan de cel, zodat elke rij op dezelfde hoogte begint met
   typen. Zonder dit zweeft een veld met een korte uitleg halverwege, en dat is
   wat dat raster rafelig maakte. */
.cs .cs-vraag textarea, .cs .cs-vraag input { margin-top: auto; width: 100%;
  box-sizing: border-box; }
.cs .cs-vraag > span:first-child { font-weight: 600; font-size: 13px; }
.cs .cs-vraag small { display: block; margin: 2px 0 6px; line-height: 1.35; }

/* De tabel met soorten vragen: de stand van alle twaalf naast elkaar. */
.cs .cs-soorten td, .cs .cs-soorten th { padding: 7px 10px; vertical-align: middle; }
.cs .cs-soorten .cs-nr { color: var(--muted); font-variant-numeric: tabular-nums; width: 1%; }
.cs .cs-soorten .cs-score { white-space: nowrap; }
.cs .cs-soorten td.rechts, .cs .cs-soorten th.rechts { text-align: right; width: 1%; }
.cs .cs-soorten tr.botst td { background: var(--bad-bg, rgba(200,0,0,.04)); }
.cs .cs-soorten form { display: inline; }

/* De schakelaar: een knop die eruitziet als een schakelaar, zonder JavaScript.
   Hij post naar dezelfde route als de rest, dus hij werkt ook zonder script. */
.cs .cs-toggle { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--line);
  background: transparent; border-radius: 999px; padding: 3px 10px 3px 4px; cursor: pointer;
  font-size: 12px; color: var(--muted); }
.cs .cs-toggle .cs-toggle-knop { width: 26px; height: 15px; border-radius: 999px;
  background: var(--line); position: relative; transition: background .12s; }
.cs .cs-toggle .cs-toggle-knop::after { content: ''; position: absolute; top: 2px; left: 2px;
  width: 11px; height: 11px; border-radius: 50%; background: #fff; transition: left .12s; }
.cs .cs-toggle.aan { color: var(--action); border-color: var(--action); }
.cs .cs-toggle.aan .cs-toggle-knop { background: var(--action); }
.cs .cs-toggle.aan .cs-toggle-knop::after { left: 13px; }

/* Het aantal achter een tabnaam: een getal, geen bolletje. Een bolletje zegt
   dat er iets is, een getal zegt hoeveel -- en dat bepaalt of je nu kijkt. */
.cs .cs-tel-tab { margin-left: 6px; font-size: 11.5px; font-weight: 600;
  color: var(--muted); font-variant-numeric: tabular-nums; }
.cs .cs-tabs a.aan .cs-tel-tab { color: var(--action); }

/* Een haarlijn tussen de vragen. Subtiel met opzet: de lijst moet als lijst
   lezen, niet als tabel. De eerste krijgt er geen, anders staat er een streep
   onder de filterbalk die er al een heeft. */
.cs .cs-regel + .cs-regel { border-top: 1px solid var(--line); }
.cs .cs-regel { border-radius: 8px; }
.cs .cs-regel:hover { background: var(--hover, rgba(0,0,0,.02)); }

/* Sorteren: een keuzemenu en een los knopje voor de richting. */
.cs .cs-sorteer { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.cs .cs-sorteer select { flex: 1; min-width: 0; font-size: 12.5px; padding: 4px 6px; }
.cs .cs-richting { display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 6px;
  text-decoration: none; color: var(--muted); font-size: 13px; }
.cs .cs-richting:hover { color: var(--action); border-color: var(--action); }

/* Geblokkeerde afzenders: een invoerregel en een smalle tabel eronder. */
.cs .cs-spam-toevoegen { display: flex; gap: 8px; margin-bottom: 10px; }
.cs .cs-spam-toevoegen input { flex: 1; min-width: 0; }
.cs .cs-spam-tabel { width: 100%; border-collapse: collapse; font-size: 13px; }
.cs .cs-spam-tabel td { padding: 5px 0; border-top: 1px solid var(--line); }
.cs .cs-spam-tabel td.rechts { text-align: right; width: 1%; white-space: nowrap; }
.cs .cs-spam-tabel form { display: inline; }

/* De leestaal van het gesprek: twee standen naast elkaar, klein en rustig.
   Hij staat rechts van de zaakgegevens en niet in de tabbladenbalk -- hij gaat
   over dit gesprek en niet over het scherm. */
.cs .cs-zaakrij { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; }
.cs .cs-zaakrij > :first-child { flex: 1 1 auto; min-width: 0; }
.cs .cs-leestaal { display: inline-flex; flex: 0 0 auto; gap: 2px; padding: 2px;
  border-radius: 7px; background: #f4f5f7; }
.cs .cs-leestaal a { padding: 2px 9px; border-radius: 5px; font-size: 11.5px;
  font-weight: 600; color: var(--muted); text-decoration: none; }
.cs .cs-leestaal a.aan { background: #fff; color: var(--text);
  box-shadow: 0 1px 2px rgba(16, 24, 40, .1); }

/* Wat er ná dit antwoord nog moet gebeuren, direct onder de knoppen. Een
   zichtbaar blok en geen stille regel: dit is de vraag die je stelt vóór je op
   versturen drukt. Oranje zolang er iets openstaat, grijs als alles af is --
   de kleur hoort bij werk dat wacht, niet bij de lijst zelf. */
.cs .cs-taakblok { margin-top: 12px; padding: 10px 12px; border-radius: 9px;
  background: var(--page); border: 1px solid var(--line); }
.cs .cs-taakblok.heeft-open { background: var(--warn-bg); border-color: var(--warn-line); }
.cs .cs-taakkop { display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; font-size: 12.5px; margin-bottom: 6px; }
.cs .cs-taakkop a { font-size: 12px; }
.cs .cs-taken-lijst { list-style: none; margin: 0; padding: 0; }
.cs .cs-taak { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 13px; }
.cs .cs-taak + .cs-taak { border-top: 1px solid var(--line); }
.cs .cs-taak.af .cs-taak-wat { color: var(--muted); text-decoration: line-through; }
/* De reden neemt de ruimte die overblijft en kapt af op één regel. Hij staat er
   om te zien waaróm deze taak er is; loopt hij door over drie regels, dan duwt
   hij de knop ernaast van het scherm. De volledige tekst staat in de tooltip. */
.cs .cs-taak-reden { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* "Niet nodig" staat rechts en is bewust stil: het is de uitzondering, niet de
   gewone handeling. Een knop in de kleur van Versturen zou hier even hard om
   aandacht vragen als de taak zelf. */
.cs .cs-taak-weg { margin-left: auto; }
.cs .cs-taak-weg button { font-size: 12px; padding: 2px 8px; }

/* Wat de controle in dit antwoord vond. Geel en niet rood: sinds 2026-10-01
   houdt dit een door een mens geschreven antwoord niet meer tegen -- het is
   iets om te zien vóór je op versturen drukt, geen afwijzing achteraf. */
.cs .cs-feitenwaarschuwing { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.cs .cs-feitenwaarschuwing ul { margin: 0; padding-left: 18px; }
.cs .cs-feitenwaarschuwing p { margin: 0; }

/* De melding dat de klant een bestand deelde dat wij niet kunnen zien. Pal
   boven de knoppen, want dat is waar iemand op het punt staat te drukken. */
.cs .cs-gedeeld { margin: 6px 0 0; }
.cs .cs-gedeeld a { margin-left: 4px; }

/* Bijlagen bij ons antwoord: een stille regel onder het tekstvak. Het is de
   uitzondering en geen vaste stap, dus geen kader en geen kleur. */
.cs .cs-uitbijlagen { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 6px; }
.cs .cs-uitbijlage-lijst { list-style: none; margin: 0; padding: 0; display: flex;
  flex-wrap: wrap; gap: 6px; }
.cs .cs-uitbijlage { display: flex; align-items: center; gap: 6px; font-size: 12px;
  background: var(--page); border: 1px solid var(--line); border-radius: 999px;
  padding: 2px 4px 2px 10px; }
.cs .cs-uitbijlage-naam { max-width: 16rem; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.cs .cs-uitbijlage button { padding: 0 6px; line-height: 1.2; }
.cs .cs-bijlage-kies { font-size: 12px; color: var(--action); cursor: pointer;
  border: 1px dashed var(--line-strong); border-radius: 999px; padding: 3px 10px; }
.cs .cs-bijlage-kies.bezig { opacity: .6; cursor: progress; }
.cs .cs-bijlage-melding { margin: 0; }

/* Het tussenbericht. Twee velden onder elkaar en geen raster: het tekstvak is
   negen regels hoog en een urenveld ernaast zou een kolom van drie tekens
   naast een blok van driehonderd pixels zetten. */
.cs .cs-tussenbericht-form { display: flex; flex-direction: column; gap: 10px;
  max-width: 44rem; }
.cs .cs-tussenbericht-form label { display: flex; flex-direction: column; gap: 4px;
  font-size: 12.5px; color: var(--muted); }
.cs .cs-tussenbericht-form input[type="number"] { width: 7rem; }
.cs .cs-tussenbericht-form textarea { font-size: 13.5px; line-height: 1.6; width: 100%; }
.cs .cs-tussenbericht-form button { align-self: flex-start; }

/* Zelf een taak toevoegen: dicht en stil, want het is de uitzondering. */
.cs .cs-taak-nieuw { margin-top: 8px; }
.cs .cs-taak-nieuw > summary { font-size: 12px; color: var(--muted); cursor: pointer; }
.cs .cs-taak-nieuw form { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.cs .cs-taak-nieuw input { flex: 1; min-width: 12rem; font-size: 12.5px; padding: 4px 8px; }
.cs .cs-taak-nieuw select, .cs .cs-taak-nieuw button { font-size: 12.5px; padding: 4px 8px; }

/* Het zoekveld boven de wachtrij. Op een eigen regel onder de filters: hij
   hoort bij de lijst en niet bij de sortering, en naast elkaar passen ze bij
   een smalle kolom niet. */
.cs .cs-zoek { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.cs .cs-zoek input { flex: 1; min-width: 0; font-size: 12.5px; padding: 4px 8px; }
.cs .cs-zoek button { font-size: 12.5px; padding: 4px 10px; }

/* De melding na een kenniswijziging, bovenaan het tabblad. Één regel met de
   knop erachter: het is een aanbod en geen waarschuwing, dus geen kleur. */
.cs .cs-kennisbij .cs-kennisbij-rij { display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap; font-size: 13px; }
.cs .cs-kennisbij .cs-kennisbij-rij > span { flex: 1; min-width: 14rem; }

/* Het draaiende icoontje en de balk bij een herschrijving.

   De balk loopt op een gemeten schatting (25 seconden) en komt nooit helemaal
   vol: vol betekent klaar, en dat weet alleen de server. Duurt het langer, dan
   blijft hij op 97% staan en draait het icoontje door -- dat is eerlijker dan
   een balk die stilstaat op honderd terwijl er niets gebeurt.

   De overgang is 0.4s lineair en niet een animatie op de breedte zelf: het
   script zet de breedte elke halve seconde, en met een vloeiende overgang
   ertussen leest dat als doorlopen in plaats van als springen. */
.cs .cs-bezigblok { display: flex; flex-direction: column; gap: 8px; }
.cs .cs-bezigrij { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cs .cs-balk { height: 4px; border-radius: 999px; background: var(--line);
  overflow: hidden; }
.cs .cs-balk > span { display: block; height: 100%; width: 0;
  background: var(--action); transition: width .4s linear; }
.cs .cs-tol { width: 13px; height: 13px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--action);
  animation: cs-tol 900ms linear infinite; }
@keyframes cs-tol { to { transform: rotate(360deg); } }
/* Wie beweging uitzet, krijgt geen draaiend wiel. De balk blijft: die draagt
   informatie en geen beweging om de beweging. */
@media (prefers-reduced-motion: reduce) {
  .cs .cs-tol { animation: none; border-top-color: var(--action); }
}

/* Het belletje naast een knop: dezelfde uitklapper als het i-venster, andere
   betekenis. Dat legt uit hoe iets werkt; dit zegt dat er iets aan de hand is,
   en dus draagt hij de waarschuwingskleur. */
.cs .cs-bel > summary { color: var(--warn-line); border-color: var(--warn-line); }

/* Bols caselog, dicht onder het bericht. Kleiner en ingesprongen, zodat het
   leest als achtergrond bij dit bericht en niet als een los gesprek. */
.cs .cs-log { margin-top: 8px; }
.cs .cs-log > summary { cursor: pointer; font-size: 11.5px; color: var(--muted);
  list-style: none; padding: 2px 0; }
.cs .cs-log > summary::-webkit-details-marker { display: none; }
.cs .cs-log > summary::before { content: '▸ '; }
.cs .cs-log[open] > summary::before { content: '▾ '; }
.cs .cs-logregel { margin-top: 6px; padding: 7px 9px; border-radius: 7px;
  background: #f7f8fa; border-left: 2px solid var(--line-strong); }
.cs .cs-logregel.onskant { background: #fff8f0; }
.cs .cs-logkop { display: flex; justify-content: space-between; gap: 10px;
  font-size: 11px; margin-bottom: 3px; }
.cs .cs-logregel .cs-tekst { font-size: 12px; }

/* Vier knoppen op een rij: drie filters en verversen.
   Een knop die niet gekozen is draagt een heel licht grijs vlak, zodat de rij
   als vier knoppen leest en niet als drie stukjes tekst naast een blauw blok. De verversknop groeit niet mee: hij draagt een icoon en geen woord,
   dus even breed als de andere zou een leeg vlak zijn. */
.cs .cs-filters { display: flex; gap: 4px; }
.cs .cs-filters a { flex: 1; text-align: center; padding: 6px 8px; font-size: 12.5px;
  color: var(--muted); text-decoration: none; border-radius: 7px;
  background: #f4f5f7; border: 1px solid transparent; }
.cs .cs-filters a:hover { background: #e9ebef; color: var(--text); }
.cs .cs-filters a.aan { background: var(--action); color: #fff; }
.cs .cs-filters a.aan:hover { background: var(--action); color: #fff; }
.cs .cs-filters a.cs-ververs { flex: 0 0 auto; display: inline-flex;
  align-items: center; justify-content: center; width: 30px; padding: 6px 0; }

/* Een gesprek in de lijst. Vier regels met een vaste opbouw: wie, wanneer,
   waarover, en wat de stand is. Dezelfde volgorde bij elke regel, zodat het oog
   niet hoeft te zoeken. */
.cs .cs-regel { display: block; padding: 10px 12px; border-radius: 9px;
  text-decoration: none; color: inherit; border: 1px solid transparent; }
.cs .cs-regel + .cs-regel { margin-top: 2px; }
.cs .cs-regel:hover { background: var(--page); }
.cs .cs-regel.aan { background: var(--card); border-color: var(--action); }
.cs .cs-regel-kop { display: flex; justify-content: space-between; gap: 8px;
  font-size: 12px; color: var(--muted); }
.cs .cs-zaak { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--muted); }
/* Hoe lang de vraag al openstaat. Bovenaan de regel en niet onderaan: dit is
   de informatie die bepaalt wélke vraag je pakt, en onderaan scrolt hij weg. */
.cs .cs-wacht { flex-shrink: 0; font-variant-numeric: tabular-nums; }
.cs .cs-wacht.dringend { color: var(--bad-text); font-weight: 600; }
.cs .cs-van { display: block; font-weight: 600; color: var(--body); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
.cs .cs-tijd { flex-shrink: 0; }
.cs .cs-onderwerp { display: block; font-size: 13.5px; color: var(--body);
  margin: 1px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cs .cs-tags { display: flex; gap: 4px; flex-wrap: wrap; }
.cs .cs-afgekapt { font-size: 12px; color: var(--muted); margin: 10px 2px 0; }

.cs .cs-gesprek-kop { display: flex; justify-content: space-between;
  align-items: flex-start; gap: 12px; flex-wrap: wrap; position: relative; }
.cs .cs-pillen { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* Het uitlegvenster hangt aan de kop van de kaart en niet aan de i zelf.
   Gemeten en niet bedacht: de i staat in een rij pillen waarvan de breedte
   per gesprek verschilt, dus zijn x-positie ook. Een venster dat links van de
   i begint, steekt op 1280 punten 130 pixels buiten beeld en op 500 punten
   169 -- en de bestaande vlucht-naar-links geldt pas vanaf 640, dus precies
   op een telefoon greep hij niet. Door de i zelf static te maken lost het
   venster op tegen de kop, en die loopt altijd tot de rand van de kaart.
   Nagemeten op 390, 500, 900 en 1280: nergens buiten beeld. */
.cs .cs-pillen .scherm-info { position: static; }
.cs .cs-gesprek-kop .scherm-info .paneel { left: auto; right: 0; top: 100%; }

/* De kant van de klant, met een heel lichte blauwe ondergrond.
   Wat de klant schreef en wat wij antwoorden zijn twee dingen die naast elkaar
   gelezen worden; zonder verschil in ondergrond lopen ze in elkaar over en
   leest iemand het antwoord zonder de vraag. Licht genoeg om er tekst op te
   kunnen lezen -- dit is een scheiding en geen markering. */
.cs .cs-vraagkant { background: #f4f8ff; border: 1px solid #e3ecfb;
  border-radius: 10px; padding: 14px 16px; margin: 0 0 18px; }
.cs .cs-vraagkant > *:last-child { margin-bottom: 0; }

/* Elk bericht een eigen blok, en de kant van het scherm zegt wie het schreef.
   Zonder verschil in uitlijning én kleur lopen vraag en antwoord in elkaar
   over, en dan leest iemand ons eigen antwoord als de klacht.
   De tekst van een klant draagt zijn eigen regeleindes, dus pre-wrap -- en
   daarom staat die tekst op een eigen element zonder kinderen: anders tekent
   de browser de inspringing van de sjabloon mee als witruimte. Dezelfde fout
   als bij de reacties op het feedbackbord. */
.cs .cs-bericht { max-width: 82%; padding: 10px 14px; border-radius: 12px;
  margin: 0 0 12px; background: #f4f8ff; border: 1px solid #dbe7fb; }
.cs .cs-bericht:last-of-type { margin-bottom: 0; }
/* Onze kant: rechts, en heel licht oranje. Oranje en niet groen of rood: die
   twee betekenen op dit platform "goed" en "fout", en een verstuurd antwoord
   is geen van beide. */
.cs .cs-bericht.cs-onskant { margin-left: auto; background: #fff8ef;
  border-color: #f6e3c8; }
.cs .cs-bericht-kop { display: flex; justify-content: space-between; gap: 12px;
  font-size: 12px; margin-bottom: 5px; align-items: baseline; }
.cs .cs-bericht-kop > span:first-child { font-weight: 600; color: var(--text); }
.cs .cs-tekst { white-space: pre-wrap; font-size: 13.5px; line-height: 1.6;
  color: var(--body); margin: 0; overflow-wrap: anywhere; }

/* Ons antwoord staat los van het gesprek, met dezelfde streep erboven als het
   gesprek er zelf een heeft. Zonder die scheiding loopt het antwoordveld tegen
   het laatste bericht aan en lijkt het erbij te horen. */
.cs .cs-detail > .card > .body > .cs-antwoord { border-top: 1px solid var(--line);
  padding-top: 18px; margin-top: 18px; }
/* Een heel lichte grijze ondergrond onder ons eigen antwoord, op verzoek van de
   eigenaar. Tegenhanger van .cs-vraagkant, dat de klantkant lichtblauw zet: wat
   de klant schreef en wat wij terugschrijven worden naast elkaar gelezen, en
   zonder verschil in ondergrond loopt het in elkaar over. Dan leest iemand het
   antwoord zonder de vraag -- precies de fout die dit scherm moet vangen.

   De streep erboven blijft staan: hij scheidt het antwoord van het gesprek, en
   dat doet een ondergrond van vier procent grijs alleen niet. */
.cs .cs-antwoord, .cs .cs-antwoordkant { background: #fafafa; border-radius: 10px;
  padding: 12px 14px; }
.cs .cs-detail > .card > .body > .cs-antwoord { border-radius: 0 0 10px 10px; }
.cs .cs-antwoord h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--body); }
.cs .cs-antwoord textarea { width: 100%; font-size: 13.5px; line-height: 1.6;
  /* Meegroeien met het concept in plaats van een vast aantal regels: een
     antwoord van duizend tekens in een vakje van zeven regels laat je scrollen
     binnen een scrollend scherm, en dan lees je het nooit in zijn geheel.
     Het plafond is er omdat de knop Versturen zichtbaar moet blijven. */
  /* Lager dan het gesprek mag, want er is altijd een gesprek om na te lezen
     en er is altijd een knop om te drukken. 34vh laat bij 900 punten ruimte
     voor ruim tien regels antwoord. */
  max-height: 34vh; resize: vertical; }

.cs .cs-knoppen { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px;
  margin-bottom: 18px; align-items: flex-start; }
/* De knop blijft staan waar hij staat, ook als het paneel opengaat.
   Hij pakte open de volle breedte, en dan springt hij naar de tweede regel met
   Spam eronder -- precies het verspringen dat het lezen onmogelijk maakt. Nu
   is de details een vast blok in de rij en zweeft het paneel eronder, links
   uitgelijnd op de knop. Zwevend kán hier, want de kaart schuift niet meer
   zelf: hij verdeelt, en het paneel valt binnen de knoppenrij die onderaan
   staat.
   Niet met display:contents: dat haalt de doos weg die een details gebruikt
   om zijn inhoud te verbergen, en dan staat het paneel altijd open. Gemeten. */
.cs .cs-knoppen > details.cs-herschrijf { flex: 0 0 auto; position: relative; }

/* Het gesprek schuift vanbinnen in plaats van de knop Versturen weg te duwen.
   Gemeten: een draad van tien berichten zette die knop buiten beeld, en dan is
   de handeling waar dit scherm voor bestaat het enige wat je niet ziet. */
.cs .cs-gesprek { overflow-y: auto; min-height: 0; display: flex;
  flex-direction: column; padding: 2px 2px 8px; }
.cs .cs-eerder-melding { margin: 0 0 10px; font-size: 12px; color: var(--muted); }

/* Wat er automatisch onder het antwoord komt. Geen invoerveld: het is één
   afsluiting voor alle antwoorden, en die verander je bij de instellingen. */
.cs .cs-handtekening { margin-top: 10px; padding: 10px 12px; border-radius: 8px;
  background: var(--page); border: 1px dashed var(--line-strong); }
.cs .cs-handtekening p { margin: 4px 0 0; font-size: 13px; line-height: 1.5;
  white-space: pre-line; color: var(--body); }
.cs .cs-handtekening.leeg { border-color: var(--warn-line); background: #fffdf7; }

/* Het uitleesblok is één regel: kop, twee knoppen, en de uitleg achter de i. */
.cs .cs-uitlezen .cs-knoppen { margin: 0; align-items: center; }
.cs .cs-uitlees-kop { font-weight: 600; font-size: 14px; margin-right: 6px; }
/* De i naast de kop en niet erdoorheen. De klasse scherm-info staat op static binnen
   een kaartkop -- dat is elders juist, maar in een h2 valt het venster dan over
   de tekst. Hier krijgt hij zijn eigen plek in de regel. */
.cs .cs-uitlezen .head h2 { display: flex; align-items: center; gap: 10px; }
.cs .cs-uitlezen .head .scherm-info { position: relative; flex: 0 0 auto; }
.cs .cs-uitlees-stand { margin: 10px 0 0; }

/* Vijftig kennisregels onder elkaar duwen alles eronder van het scherm. */
.cs details.cs-kennisblok > summary { display: flex; justify-content: space-between;
  align-items: center; gap: 12px; padding: 16px 20px; cursor: pointer; font-size: 13px; }
.cs details.cs-kennisblok > summary::-webkit-details-marker { display: none; }
.cs details.cs-kennisblok > summary::before { content: '\25B8'; color: var(--faint);
  transition: transform .15s; }
/* Het pijltje, de titel en de telling: links, links, rechts. Met alleen
   space-between belandt de titel in het midden, want dan zijn het drie items
   die de ruimte verdelen. */
.cs details.cs-kennisblok > summary > span:first-of-type { margin-right: auto; }
.cs details.cs-kennisblok[open] > summary::before { transform: rotate(90deg); }

.cs .cs-poorten { list-style: none; margin: 8px 0 0; padding: 0; font-size: 12.5px; }
.cs .cs-poorten li { padding: 2px 0; color: var(--muted); }
.cs .cs-poorten li.bad { color: var(--bad-text); }

/* De kennisbank. Elke soort vraag is een uitklapper: twaalf open kaarten is
   een muur, en de vraag "welke wil ik aanpassen" gaat over de titel. */
.cs .cs-kennis { display: flex; flex-direction: column; gap: 14px; }
/* De taalknop onder de naam van wie er ingelogd is: even breed als uitloggen,
   zodat de twee onder elkaar één blok vormen in plaats van twee losse knoppen. */
.taal-keuze { margin-top: 10px; }
.taal-keuze button { width: 100%; }

/* De strengheidslijst: één regel per onderwerp, met de stand rechts. Hij deelt
   de klasse met de andere lijsten op dit tabblad, en zonder deze regels staat
   de pil los van zijn label en springt de inspringing per rij. */
.cs .cs-kennislijst > li > details > summary { display: flex; align-items: center;
  gap: 10px; padding: 11px 2px; cursor: pointer; font-size: 13px; list-style: none; }
.cs .cs-kennislijst > li > details > summary::-webkit-details-marker { display: none; }
.cs .cs-kennislijst > li > details > summary::before { content: '\25B8'; color: var(--faint);
  transition: transform .15s; font-size: 11px; }
.cs .cs-kennislijst > li > details[open] > summary::before { transform: rotate(90deg); }
.cs .cs-kennislijst > li > details > summary > span:first-of-type { flex: 1; font-weight: 500; }
.cs .cs-kennislijst > li > details > summary:hover { background: var(--page); }
.cs .cs-kennislijst > li > details > form { display: flex; flex-direction: column; gap: 10px;
  padding: 4px 2px 18px 22px; }
.cs .cs-kennislijst > li > details > form > label { display: flex; flex-direction: column;
  gap: 4px; font-size: 12.5px; font-weight: 500; color: var(--muted); }
.cs .cs-kennislijst > li > details textarea,
.cs .cs-kennislijst > li > details select { width: 100%; font-family: inherit; font-size: 13px; }
.cs .cs-kennislijst > li > details button { align-self: flex-start; }
/* Het raster met de drie grenzen: gelijke kolommen, en het vinkje op de
   basislijn van de invoervelden ernaast in plaats van erboven. */
/* Bovenaan uitlijnen en niet onderaan: één cel draagt drie regels uitleg, en
   met align-items:end zakken de andere twee velden mee. Dan staan drie
   labels op drie verschillende hoogtes en leest het niet als één rij. */
.cs .cs-grid { display: grid; gap: 14px 18px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); align-items: start; }
.cs .cs-grid > label { display: flex; flex-direction: column; gap: 4px;
  font-size: 12.5px; font-weight: 500; color: var(--muted); }
.cs .cs-grid input[type="text"], .cs .cs-grid input:not([type]) { width: 100%; }
.cs .cs-grid .cs-vinkje { flex-direction: row; align-items: center; gap: 8px;
  padding-top: 22px; }
.cs .cs-grid .cs-vinkje input { width: auto; }
.cs .cs-grid small { font-weight: 400; line-height: 1.45; }

/* De gekozen soort vraag, als open blok onder de tabel. Een eigen ondergrond
   en een lijn erboven, zodat te zien is dat hij bij de aangeklikte rij hoort
   en niet los onder de tabel zweeft. */
.cs .cs-situatie { border-top: 1px solid var(--line-strong); background: var(--page);
  margin: 0 -20px -16px; padding: 16px 20px 20px; }
.cs .cs-situatie-kop { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.cs .cs-situatie-kop .cs-situatie-naam { font-size: 14px; font-weight: 600; color: var(--text); }
.cs .cs-situatie-kop .cs-situatie-stand { margin-right: auto; }
.cs .cs-situatie-sluit { margin-left: auto; color: var(--faint); text-decoration: none;
  font-size: 20px; line-height: 1; padding: 0 4px; }
.cs .cs-situatie-sluit:hover { color: var(--text); }
.cs .cs-situatie.botst .cs-situatie-naam { color: var(--bad-text); }
.cs .cs-situatie-body > form { display: flex; flex-direction: column; gap: 8px; margin: 0 0 16px; }
.cs .cs-situatie-body textarea { width: 100%; font-family: inherit; font-size: 13px; }
.cs .cs-situatie-body label { font-size: 12.5px; font-weight: 600; color: var(--body); }
.cs .cs-situatie-body .cs-auto { flex-direction: row; align-items: center; gap: 10px;
  flex-wrap: wrap; margin-bottom: 0; }
.cs .cs-situatie-body button { align-self: flex-start; }

.cs details.cs-situatie-oud { border-bottom: 1px solid var(--line); }
.cs .cs-situatie-oud:last-child { border-bottom: 0; }
.cs .cs-situatie-oud > summary { display: flex; justify-content: space-between;
  align-items: center; gap: 10px; padding: 11px 4px; cursor: pointer;
  list-style: none; font-size: 13.5px; }
.cs .cs-situatie-oud > summary::-webkit-details-marker { display: none; }
.cs .cs-situatie-oud > summary:hover { color: var(--action); }
.cs .cs-situatie-naam { font-weight: 500; }
.cs .cs-situatie-stand { display: flex; gap: 6px; flex-wrap: wrap; }
.cs .cs-situatie-oud.botst > summary { color: var(--bad-text); }
.cs .cs-situatie-body { padding: 4px 4px 18px; display: flex;
  flex-direction: column; gap: 14px; }
.cs .cs-situatie-body textarea { width: 100%; }
.cs .cs-auto { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.cs .cs-varianten { list-style: none; margin: 8px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.cs .cs-varianten li { display: flex; gap: 8px; align-items: baseline;
  flex-wrap: wrap; font-size: 12.5px; }
.cs .cs-variant { color: var(--body); }

.cs .cs-kennislijst { list-style: none; margin: 0; padding: 0; }
.cs .cs-kennislijst > li { border-bottom: 1px solid var(--line); padding: 2px 0; }
.cs .cs-kennislijst > li:last-child { border-bottom: 0; }
.cs .cs-kennislijst summary { display: flex; gap: 10px; align-items: center;
  padding: 10px 4px; cursor: pointer; font-size: 13.5px; }
.cs .cs-kennislijst form { padding: 4px 4px 16px; display: flex;
  flex-direction: column; gap: 10px; }
.cs .cs-nieuw { margin-top: 12px; }
.cs .cs-nieuw > summary { font-size: 13px; color: var(--action); cursor: pointer; padding: 6px 0; }
.cs .cs-nieuw form { display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }

.cs .cs-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px; }
.cs .cs-vinkje { display: flex; align-items: center; gap: 8px; }
.cs .cs-vragen { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px; margin-bottom: 14px; }
.cs .cs-vraag { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.cs .cs-vraag small { font-size: 11.5px; line-height: 1.45; }

.cs .cs-log { display: flex; flex-direction: column; gap: 14px; }
.cs .cs-zoek { display: flex; gap: 8px; }
.cs .cs-zoek input { flex: 1; }
.cs .cs-log .cs-kennislijst > li { display: flex; align-items: center;
  gap: 10px; padding: 8px 4px; font-size: 13px; }

/* De leestaalknop, rechts in de tabbladenbalk. Een knop en geen keuzelijst:
   er zijn twee standen, en een lijst met twee waarden is een knop met een
   omweg. */
/* De uitleg en de taalknop staan allebei rechts, los van de tabbladen: het
   zijn geen plekken om heen te gaan maar schakelaars over wat je ziet. Zonder
   deze duw leest de i als een vijfde tabblad. */
.cs .cs-tabs .cs-setup { margin-left: auto; align-self: center; }
.cs .cs-vertaalregel { margin: 0 0 14px; font-size: 12.5px; }

/* De harde gegevens van een zaak: nummer, bestelling, EAN, datum. Een
   definitielijst in plaats van losse regels, want het zijn paren -- en op een
   smal scherm moeten ze vouwen zonder dat een waarde onder de verkeerde naam
   belandt. */
.cs .cs-zaakregel { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 10px 0 0; }
.cs .cs-zaakregel > div { display: flex; gap: 6px; align-items: baseline; font-size: 12.5px; }
.cs .cs-zaakregel dt { color: var(--muted); }
.cs .cs-zaakregel dd { margin: 0; color: var(--body); font-weight: 500;
  font-variant-numeric: tabular-nums; }
.cs .cs-zaakregel > div.dringend dd { color: var(--bad-text); }

/* Wat de klant meestuurde. Een raster met een vaste hoogte per tegel: foto's
   komen in alle formaten binnen, en zonder vaste hoogte springt de hele pagina
   bij elke plaat die laadt. */
.cs .cs-bijlagen { margin: 4px 0 18px; }
.cs .cs-bijlagen h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--body); }
.cs .cs-bijlagen ul { list-style: none; margin: 0; padding: 0; display: flex;
  flex-wrap: wrap; gap: 10px; }
.cs .cs-bijlage { display: flex; flex-direction: column; gap: 4px; max-width: 120px; }
/* Klein in de lijst; groot bij een klik. Vierkant en bijgesneden, zodat een
   staande foto de rij niet uit elkaar trekt -- de hele foto zie je in de
   vergroting. */
.cs .cs-bijlage .cs-mini img, .cs .cs-bijlage video { width: 120px; height: 90px;
  object-fit: cover; border-radius: 9px; border: 1px solid var(--line-strong);
  background: var(--page); display: block; }
.cs .cs-bijlage .cs-mini:hover img { border-color: var(--action); }

/* De vergroting, zonder een regel JavaScript: de miniatuur wijst naar het id
   hieronder, en 'target' maakt die laag zichtbaar. Dicht is de standaard,
   dus een pagina die opent zonder hash toont niets. */
.cs .cs-groot { display: none; }
.cs .cs-groot:target { display: flex; position: fixed; inset: 0; z-index: 60;
  align-items: center; justify-content: center; flex-direction: column; gap: 12px;
  padding: 32px; background: rgb(16 24 40 / .82); }
.cs .cs-groot img { max-width: min(1100px, 92vw); max-height: 78vh;
  object-fit: contain; border-radius: 10px; background: #fff; }
.cs .cs-groot-sluit { position: absolute; top: 18px; right: 22px; font-size: 30px;
  line-height: 1; color: #fff; text-decoration: none; }
.cs .cs-groot-los { color: #fff; font-size: 13px; }
.cs .cs-bijlage.bestand, .cs .cs-bijlage.mist { border: 1px solid var(--line-strong);
  border-radius: 9px; padding: 10px 12px; justify-content: center; min-height: 54px; }
.cs .cs-bijlage.mist { border-style: dashed; color: var(--muted); }

/* De taken die uit deze vraag voortkwamen: één stille regel onder het
   antwoord. Dit was een oranje kader bóven het antwoord, en dat brak het paar
   vraag-antwoord waar dit scherm voor bestaat -- terwijl de tekst zelf zei dat
   je er hier niets mee kunt. De kleur is verdiend op het tabblad Taken. */
.cs .cs-taakregel { font-size: 12.5px; color: var(--muted); margin: 12px 0 0; }

/* Het antwoord opnieuw laten schrijven. Dicht standaard: het is de uitzondering
   en niet de gewone gang van zaken. */
/* De productkennis als lijst: één regel per stuk, en alleen het gekozen stuk
   als formulier eronder. Zie de uitleg bij productKennis -- dit tabblad woog
   159 kB waarvan 94 kB aan formulieren die niemand zag. */
/* Eigen klasse, want cs-kennislijst wordt ook gebruikt voor de strengheid en
   de geblokkeerde afzenders. Die twee zijn uitklappers gebleven -- ze zijn
   begrensd op zeven regels en groeien niet mee met de klant. */
.cs .cs-kennisrijen > li { border-bottom: 1px solid var(--line); padding: 0; }
.cs .cs-kennisregel { display: flex; align-items: center; gap: 10px; padding: 11px 2px;
  text-decoration: none; color: var(--text); font-size: 13px; }
.cs .cs-kennisregel:hover { background: var(--page); }
.cs .cs-kennisregel > span:first-child { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.cs .cs-kennisrijen > li.aan > .cs-kennisregel { font-weight: 600; color: var(--brand); }
.cs .cs-kennisrijen > li > form { display: flex; flex-direction: column; gap: 8px;
  padding: 4px 2px 16px; }
.cs .cs-kennisrijen textarea { width: 100%; font-family: inherit; }
/* De velden over de volle breedte. Een titel van tachtig tekens in een invoer
   van tweehonderd pixels laat je raden wat er staat, terwijl er ruimte zat is. */
.cs .cs-kennisrijen > li > form > label { display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; color: var(--muted); }
.cs .cs-kennisrijen > li > form > label > input { flex: 1; min-width: 0; }
.cs .cs-kennisrijen > li > form > label:has(textarea) { display: block; }
.cs .cs-kennisrijen > li > form > label > textarea { margin-top: 6px; }

/* Tijdens het halen blijft het oude scherm staan met een dun balkje bovenin.
   Leegmaken zou de pagina laten springen, en dat springen is precies wat een
   herlading traag laat voelen -- de bytes waren het probleem niet. */
.cs { position: relative; }
.cs.cs-bezig::before { content: ''; position: fixed; left: 0; right: 0; top: 0; height: 3px;
  z-index: 60; background: var(--brand);
  animation: cs-balk 1s linear infinite; transform-origin: left; }
@keyframes cs-balk { 0% { transform: scaleX(0); } 60% { transform: scaleX(.8); }
  100% { transform: scaleX(1); } }
.cs.cs-bezig .cs-detail, .cs.cs-bezig .cs-lijst { opacity: .55; transition: opacity .12s; }
/* Alleen zichtbaar maken wat er gebeurt, nooit klikken tegenhouden: het script
   negeert een tweede klik zelf, en een scherm dat niet reageert op de muis
   leest als vastgelopen. */

/* Opnieuw schrijven staat als knop tussen Versturen en Spam, en opent een
   venster op zijn plek. Hij erft van .pa-uitleg het zweven en het sluiten bij
   een klik ernaast; wat hier overschreven wordt is de ronde i-vorm, want dit
   is een knop met een woord erop. */
.cs .cs-herschrijf { margin: 0; }
.cs .cs-herschrijf > summary.knop { display: inline-flex; align-items: center;
  width: auto; height: auto; border-radius: 10px;
  /* Gemeten en niet afgeleid: een knop is 38 hoog, en met deze padding plus de
     rand van 1px komt de summary daar precies op uit. Een details-element krijgt zijn
     hoogte anders dan een knop -- de regelhoogte valt binnen een inline-flex
     lager uit -- dus "dezelfde padding" gaf 36 tegen 38, en dat zie je op een
     rij van drie. */
  padding: 10px 17px;
  font-size: 13px; font-weight: 600; color: var(--body); background: var(--card);
  border: 1px solid var(--line-strong); cursor: pointer; list-style: none; }
.cs .cs-herschrijf > summary.knop::-webkit-details-marker { display: none; }
.cs .cs-herschrijf > summary.knop:hover { background: var(--page); border-color: var(--brand);
  color: var(--brand); }
/* Dicht is dicht, met zoveel woorden.
   Een browser verbergt de inhoud van een gesloten details zelf, en overal
   elders op dit platform leunen we daarop. Hier niet: dit paneel draagt een
   formulier dat een modelaanroep start, en als het per ongeluk openstaat is
   dat een knop die zichtbaar is zonder dat iemand erom vroeg. Eén regel is
   goedkoper dan erop vertrouwen. */
.cs .cs-herschrijf:not([open]) > .paneel { display: none; }
.cs .cs-herschrijf > .paneel { position: absolute; z-index: 40; left: 0; bottom: calc(100% + 8px);
  width: 420px; max-width: 78vw; padding: 16px; border-radius: 10px;
  background: var(--card); border: 1px solid var(--line-strong);
  box-shadow: 0 12px 32px rgba(15, 23, 42, .16); }
/* Het paneel past altijd op het scherm, en knipt nooit zijn eigen invoerveld
   af. Gemeten: het is 336 pixels hoog en opent omhoog vanaf de knop; staat die
   knop lager dan dat, dan valt de bovenkant -- met het invoerveld erin -- weg.
   Dat is precies wat er gemeld werd: "I cannot see what I'm writing here". */
.cs .cs-herschrijf > .paneel { max-height: calc(100vh - 24px); overflow-y: auto; }

/* ── Een laag venster is een gewone pagina ────────────────────────────────
   De detailkolom stond op een vaste hoogte (100vh - 182px) met overflow:
   hidden eromheen. Dat verdeelt mooi zolang de inhoud past, en zodra dat niet
   meer zo is verdwijnt het overschot zonder schuifbalk en zonder melding --
   dezelfde stille vorm die hierboven voor het antwoordblok al een keer
   gerepareerd is, nu voor de kaart als geheel.

   Gemeten op zaak #108 van JDL Market, met het herschrijfvenster open:

     1600x900  alles in beeld
     1366x650  Send, Close case en Sluiten bij bol vallen eruit (8 elementen)
     1024x600  idem, en het herschrijfpaneel staat 977 pixels onder de vouw
      390x844  idem, 1458 pixels eronder

   Op een laptop is 650 tot 700 pixels werkruimte heel gewoon. Daar hoort het
   scherm een pagina te worden die schuift in plaats van een raam dat zijn
   eigen knoppen verbergt. De lijst blijft wél staan: die is sticky en houdt
   zijn eigen hoogte, dus je verliest je plek in de wachtrij niet.

   De grens staat op 820px en niet op een breedte: dit gaat over hoogte. Een
   breed maar laag venster heeft precies hetzelfde probleem. */
@media (max-height: 820px) {
  .cs .cs-detail { position: static; height: auto; }
  .cs .cs-detail > .card > .body { overflow: visible; }
  .cs .cs-detail > .card > .body > .cs-gesprek,
  .cs .cs-detail > .card > .body > .cs-antwoord { overflow: visible; max-height: none; }
  /* Omlaag in plaats van omhoog: boven de knop is hier geen ruimte, eronder
     groeit de pagina gewoon mee. */
  .cs .cs-herschrijf > .paneel { bottom: auto; top: calc(100% + 8px); }
}

.cs .cs-paneel-kop { display: flex; justify-content: space-between; align-items: center;
  gap: 12px; margin-bottom: 10px; font-size: 12.5px; font-weight: 600; color: var(--body); }
.cs .cs-sluit { background: none; border: 0; padding: 0 2px; font-size: 18px; line-height: 1;
  color: var(--faint); cursor: pointer; }
.cs .cs-sluit:hover { color: var(--text); background: none; }
/* Een label dat er voor een schermlezer moet zijn maar niet in beeld. */
.visueel-weg { position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; }

/* Het teken dat een aanpassing bewaard is. Zonder dit weet je niet of er iets
   gebeurd is, en dan lijkt het scherm niet te reageren. */
.cs .cs-antwoord textarea.bezig { border-color: var(--brand); }
.cs .cs-antwoord textarea.klaar { border-color: var(--ok-line); background: #f6fffb; }
.cs .cs-antwoord textarea.mis { border-color: var(--bad-line); background: #fff7f7; }
.cs .cs-herschrijf form { display: flex; flex-direction: column; gap: 8px; }
.cs .cs-herschrijf textarea { width: 100%; }
.cs .cs-herschrijf label { font-size: 12.5px; font-weight: 500; color: var(--muted); }
.cs .cs-herschrijf-stand { margin: 12px 0 0; font-size: 12.5px; }

/* Versturen is de bevestigende handeling van dit scherm en de enige knop die
   post de deur uit doet. Groen, en niet het blauw van elke andere knop: op een
   rij van drie hoort de onomkeerbare eruit te springen. */
.cs button.ja { background: #16a34a; color: #fff; border: 1px solid #16a34a; }
.cs button.ja:hover { background: #15803d; border-color: #15803d; }
.cs button.ja[disabled] { background: var(--card); color: var(--muted);
  border-color: var(--line); }

/* En de leeshulp zelf heeft een plafond. Hij is de reden dat de hoogte van dit
   blok niet meer te voorspellen is: een vertaling is net zo lang als het
   concept, dus het antwoord staat er twee keer. Boven de tien regels schuift
   hij vanbinnen -- wie de hele vertaling wil lezen, leest hem daar, en het
   invoerveld eronder blijft in beeld. */
.cs .cs-leeshulp { max-height: 11rem; overflow-y: auto; }
.cs .cs-leeshulp { border-left: 2px solid var(--action); padding-left: 12px;
  margin: 0 0 12px; }
.cs .cs-leeshulp h4 { font-size: 12px; font-weight: 600; margin: 0 0 4px; color: var(--muted); }

/* De geschiedenis van deze klant: context, geen werk. Dicht standaard, en met
   een eigen schuifvenster zodat het de vraag die je beantwoordt niet wegduwt. */
.cs .cs-geschiedenis { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 12px; }
.cs .cs-geschiedenis > summary { font-size: 13px; color: var(--action); cursor: pointer; }
.cs .cs-geschiedenis-venster { max-height: 22rem; overflow-y: auto; margin-top: 10px;
  padding-right: 6px; display: flex; flex-direction: column; gap: 14px; }
.cs .cs-geschiedenis-venster article { border-left: 2px solid var(--line-strong);
  padding-left: 12px; }
.cs .cs-geschiedenis-venster header { display: flex; justify-content: space-between;
  gap: 8px; margin-bottom: 4px; font-size: 12.5px; }
.cs .cs-geschiedenis-venster header a { font-weight: 600; }

/* Strengheid en vragenlijst achter één uitklapper: inrichting die je één keer
   doet, onder het onderhoud dat wekelijks terugkomt. */
.cs .cs-inrichting > summary { display: flex; justify-content: space-between;
  align-items: center; gap: 12px; padding: 14px 16px; cursor: pointer;
  font-size: 13.5px; list-style: none; }
.cs .cs-inrichting > summary::-webkit-details-marker { display: none; }
.cs .cs-inrichting > summary:hover { color: var(--action); }
.cs .cs-inrichting-body { padding: 0 16px 16px; display: flex;
  flex-direction: column; gap: 14px; }
.cs .cs-inrichting-body > .card { border: 0; border-top: 1px solid var(--line);
  border-radius: 0; }
.cs .cs-inrichting-body > .card > .head { padding-left: 0; padding-right: 0; }
.cs .cs-inrichting-body > .card > .body { padding-left: 0; padding-right: 0; }

/* De installatie-uitleg. Genummerde stappen met lucht ertussen; wie hem
   openslaat leest hem één keer helemaal. */
.cs .cs-setup .paneel { width: min(560px, calc(100vw - 60px)); }
.cs .cs-stappen { margin: 0 0 14px; padding-left: 20px; font-size: 13px;
  color: var(--body); line-height: 1.55; }
.cs .cs-stappen li { margin-bottom: 12px; }
.cs .cs-stappen li > span { color: var(--muted); }
.cs .cs-stappen code { font-size: 12px; background: var(--page); padding: 1px 5px;
  border-radius: 4px; }
.cs .cs-stappen .waarschuwing { color: var(--bad-text); }

/* Het takenoverzicht. Een tabel en geen kaarten: het is een werklijst die je
   van boven naar beneden afwerkt, en dan telt dat elke regel dezelfde kolommen
   op dezelfde plek heeft. */
.cs .cs-taken .cs-gesprek-kop { align-items: center; }
/* Alles op één rij, op verzoek van de eigenaar. Een cel die afbreekt maakt van
   elke regel twee of drie, en dan is een lijst van twintig taken een scherm vol
   -- en valt niet meer in één oogopslag te zien welke er nog openstaan.

   De reden is de enige kolom die lang kan worden; die krijgt een plafond en
   kapt af met een tooltip, zoals elders op dit platform. De tabel schuift zelf
   al horizontaal (.card.scroll.rijen), dus er valt niets buiten beeld. */
.cs .cs-taken td, .cs .cs-taken th { white-space: nowrap; }
.cs .cs-taken td.cs-taak-reden { max-width: 420px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
.cs .cs-taken tr.af td { color: var(--muted); }
.cs .cs-taken tr.af td strong { font-weight: 500; text-decoration: line-through; }
.cs .cs-vink { width: 22px; height: 22px; padding: 0; border-radius: 6px;
  border: 1px solid var(--line-strong); background: var(--card); color: var(--ok-text);
  font-size: 13px; line-height: 1; cursor: pointer; }
.cs .cs-vink:hover { border-color: var(--action); }

/* Onder de 900 punten passen twee kolommen niet meer naast elkaar. De lijst
   verliest dan zijn vaste hoogte en zijn sticky: op een telefoon is een
   binnenschuivende kolom in een schuivende pagina niet te bedienen.
   Nagemeten op 390 en 1280 punten. */
@media (max-width: 900px) {
  .cs .cs-split { grid-template-columns: minmax(0, 1fr); }
  .cs .cs-lijst { position: static; max-height: 22rem; }
  /* Onder elkaar hoort het gesprek gewoon mee te groeien met de pagina; een
     plafond zou het hier tot een kort schuifvenster maken. */
  .cs .cs-detail { position: static; max-height: none; display: block; }
}

/* Een láag venster is een eigen geval, en het is niet hetzelfde als een smal
   venster. Deze kaart verdeelt een vaste hoogte over het gesprek, het antwoord
   en de knoppen -- en onder ongeveer 700 punten hoog past de som van hun
   minimumhoogtes daar niet meer in. Gemeten op zaak #46 met de Engelse leeshulp
   erin: bij een kaart van 420 punten vielen de knoppen nog 63 punten buiten de
   kaart, en overflow: hidden snijdt dat stil af.

   Dan hoort het frame los te laten in plaats van te knijpen: de kaart groeit
   mee met zijn inhoud en de pagina schuift, precies zoals onder de 900 punten
   breed. Een schuifbalk is zichtbaar; een afgesneden knop is dat niet. */
@media (max-height: 700px) and (min-width: 901px) {
  .cs .cs-detail { position: static; height: auto; display: block; }
  .cs .cs-detail > .card { display: block; }
  .cs .cs-detail > .card > .body { display: block; overflow: visible; }
  .cs .cs-detail > .card > .body > .cs-gesprek { overflow-y: visible; }
  .cs .cs-detail > .card > .body > .cs-antwoord { overflow-y: visible; }
  .cs .cs-leeshulp { max-height: none; }
}
