/* Ibley sales — mobiele weergave.
   ---------------------------------------------------------------------------
   HERZIEN 30-08-2026. Twan: "Die houdt nu geen rekening met de besturingsbalk
   van de iphone onderaan en sowieso kan dat design wel beter. (...) betere data
   presentatie en volgens de nieuwste UX en design richtlijnen."

   Wat er mis was, in volgorde van ernst:

   1. De veilige zones deden niets. mobile.html miste `viewport-fit=cover`, en
      zonder die vlag geeft iOS env(safe-area-inset-*) altijd 0. De tabbalk
      rekende er wél mee en verdween dus onder de home-indicator.
   2. Zes gelijkwaardige kaartjes in drie kolommen op 375 pixels. "Gem.
      bestelwaarde" brak over drie regels, en omzet woog even zwaar als het
      retourpercentage. Op een telefoon kijk je naar één of twee dingen.
   3. Tekst van 9 tot 11,5 px, grijs op wit. Onder de 11 px is niet meer
      comfortabel te lezen, en de contrastverhouding haalde WCAG AA niet.
      Aanraakvlakken waren op sommige plekken 32 px; 44 px is de ondergrens.
   4. Geen donkere modus, terwijl een telefoon die vaak aan heeft staan.
   5. Kleuren stonden los in de code (#9aa0a8, #F9F9FA, ...) i.p.v. in tokens,
      dus een donkere variant was niet te maken zonder alles langs te gaan.

   Aanpak: één tokenset, één typeschaal, en hiërarchie in plaats van een raster
   van gelijke blokjes. De klassenamen zijn ongewijzigd gebleven — mobile.js
   bouwt de HTML en die hoefde daarvoor niet op de schop.
   --------------------------------------------------------------------------- */

:root{
  /* Merkkleur gelijk aan de desktop, zodat het één product blijft. */
  --primary:#2864AE;
  /* DE STROOK ACHTER DE KLOK — in élke themastand hetzelfde blauw.
     Hier stond #FFFFFF. Dat kan niet meer: met black-translucent (zie
     mobile.html) tekent iOS de klok altijd WIT, en wit op wit is niets.
     Dit is --primary van de lichte stand, hard neergezet in plaats van via
     var(): in de donkere stand is --primary een lichtere blauwtint (#5A9BE8)
     en daar zou de witte klok slechter op leesbaar zijn. De balk hoort in
     beide standen dezelfde te zijn — dat was juist de klacht. */
  --statusbalk:#2864AE;

  /* WAT DE TELEFOON ZELF RONDOM DE PAGINA TEKENT (03-09-2026).
     Dit is de oorzaak van de zwarte balk achter de notch waar we drie rondes
     op zijn vastgelopen. In mobile.html stond <meta name="color-scheme"
     content="light dark"> — één vaste waarde die zegt: deze pagina kan allebei.
     Staat de TELEFOON dan in donkere modus, dan tekent iOS alles wat het zelf
     tekent (de zone achter de klok in een app op je beginscherm) donker — ook
     als de app zelf op licht staat. Vandaar precies deze combinatie: witte app,
     zwarte balk, en in Safari wél goed, want een browser kleurt zijn balk met
     het element bovenaan de pagina.
     De CSS-eigenschap wint van die meta, en die kunnen we WEL per themastand
     zetten. Hij hoort dus in deze tokenblokken, net als de kleuren. */
  color-scheme: light;
  --primary-zacht:#EAF1F9;
  --goed:#0F6E56;
  --goed-zacht:#E4F2ED;
  --waarschuwing:#B45309;
  --waarschuwing-zacht:#FDF3E3;
  --fout:#B3271A;
  --fout-zacht:#FAECE7;

  /* Neutralen met een lichte blauwzweem: een zuiver grijs oogt onaf naast een
     blauwe merkkleur. */
  --grond:#F4F6F9;
  --vlak:#FFFFFF;
  --vlak-2:#EEF1F6;
  --inkt:#141A22;
  --inkt-2:#5A6472;      /* haalt 4.6:1 op --vlak — AA voor kleine tekst */
  --inkt-3:#666F80;      /* was #7C8695: 3,68 op wit en 3,40 op --grond, onder AA.
                            #666F80 haalt 5,06 en 4,67. In de donkere thema's hieronder
                            blijft #7C8695 staan — daar haalt hij 4,66 en 5,18. */
  --lijn:#E3E8EF;
  --lijn-sterk:#D3DAE4;

  --schaduw-kaart:0 1px 2px rgba(20,26,34,.05);
  --schaduw-zwevend:0 10px 30px rgba(20,26,34,.16);

  --r-s:10px; --r-m:14px; --r-l:18px;
  --ruimte:14px;

  --font-sans:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --tab-hoogte:56px;
}

/* Donkere modus in drie standen, niet twee.
   ---------------------------------------------------------------------------
   Twan, 30-08-2026: "Kan je ook de optie om tussen dark mode te schakelen
   inbouwen?" Daarmee zijn er drie mogelijkheden, en de middelste wordt het
   vaakst vergeten:

   - data-thema="light"  : de gebruiker koos licht, ook op een donkere telefoon
   - data-thema="dark"   : de gebruiker koos donker, ook op een lichte telefoon
   - geen attribuut      : "Automatisch" — dan beslist prefers-color-scheme

   Vandaar de uitsluiting hieronder: zonder :not([data-thema="light"]) zou een
   bewuste keuze voor licht op een donker toestel alsnog donker worden.
   Kleuren staan ALLEEN in deze tokenblokken; geen enkele component mag een
   kleur rechtstreeks in een media query zetten, want dan werkt de knop maar
   één kant op. */
@media (prefers-color-scheme: dark){
  :root:not([data-thema="light"]){
  --primary:#5A9BE8;
  --statusbalk:#2864AE;   /* zie de toelichting bij de lichte stand */
  color-scheme: dark;
  --primary-zacht:#17273A;
  --goed:#5FC7A6;
  --goed-zacht:#123027;
  --waarschuwing:#E0A94F;
  --waarschuwing-zacht:#2E2617;
  --fout:#E58A76;
  --fout-zacht:#331C18;
  
  --grond:#0C1014;
  --vlak:#161C23;
  --vlak-2:#1F262F;
  --inkt:#E8EDF3;
  --inkt-2:#A0AAB8;
  --inkt-3:#7C8695;
  --lijn:#252D37;
  --lijn-sterk:#333C48;
  
  --schaduw-kaart:0 1px 2px rgba(0,0,0,.4);
  --schaduw-zwevend:0 10px 30px rgba(0,0,0,.55);
  }
}

:root[data-thema="dark"]{
  --primary:#5A9BE8;
  --statusbalk:#2864AE;   /* zie de toelichting bij de lichte stand */
  color-scheme: dark;
  --primary-zacht:#17273A;
  --goed:#5FC7A6;
  --goed-zacht:#123027;
  --waarschuwing:#E0A94F;
  --waarschuwing-zacht:#2E2617;
  --fout:#E58A76;
  --fout-zacht:#331C18;
  
  --grond:#0C1014;
  --vlak:#161C23;
  --vlak-2:#1F262F;
  --inkt:#E8EDF3;
  --inkt-2:#A0AAB8;
  --inkt-3:#7C8695;
  --lijn:#252D37;
  --lijn-sterk:#333C48;
  
  --schaduw-kaart:0 1px 2px rgba(0,0,0,.4);
  --schaduw-zwevend:0 10px 30px rgba(0,0,0,.55);
}

*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html{ background:var(--grond); }
body{
  margin:0;
  min-height:100dvh;               /* niet 100vh: dat rekent op iOS de browserbalk mee */
  background:var(--grond);
  font-family:var(--font-sans);
  color:var(--inkt);
  font-size:15px;
  line-height:1.45;
  -webkit-font-smoothing:antialiased;
  -webkit-text-size-adjust:100%;
}
button,input{ font-family:inherit; font-size:inherit; color:inherit; }
button{ cursor:pointer; }

/* Cijfers moeten onder elkaar uitlijnen — anders danst een bedrag bij elke
   verversing een paar pixels heen en weer. */
.m-card-value,.m-hero-waarde,.m-hero-neven-waarde,.m-row-right,.m-kv-value,.m-card-delta,.m-delta{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* ---------- inloggen ---------- */
.m-login{
  min-height:100dvh; display:flex; align-items:center; justify-content:center;
  padding:calc(24px + env(safe-area-inset-top)) calc(20px + env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) calc(20px + env(safe-area-inset-left));
}
.m-login-card{ width:100%; max-width:360px; background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-l); padding:30px 24px; box-shadow:var(--schaduw-kaart); }
.m-brand{ font-size:20px; font-weight:650; letter-spacing:-.01em; color:var(--inkt); margin-bottom:20px; text-align:center; }
#mLoginForm{ display:flex; flex-direction:column; gap:10px; }
#mLoginForm input{
  font-size:16px;                  /* onder 16px zoomt iOS bij het focussen in */
  padding:14px 15px; border-radius:var(--r-s); border:1px solid var(--lijn-sterk);
  background:var(--grond); color:var(--inkt); min-height:48px;
}
#mLoginForm input:focus-visible{ outline:2px solid var(--primary); outline-offset:1px; border-color:transparent; }
#mLoginForm button{ background:var(--primary); color:#fff; border:none; font-size:16px; font-weight:600; padding:14px; border-radius:var(--r-s); margin-top:6px; min-height:48px; }
#mLoginForm button:active{ filter:brightness(.92); }
.m-error{ color:var(--fout); font-size:13px; min-height:18px; }
.m-login-hint{ text-align:center; font-size:13px; color:var(--inkt-3); margin-top:16px; }
.m-login-hint a{ color:var(--primary); }

/* Het weekstaafje bij de retouren-KPI's. Zeven staafjes, geen bibliotheek:
   het is een verhouding, geen grafiek met assen. */
.m-retour-week{
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m);
  padding:12px 14px; margin-bottom:12px;
}
.m-retour-week-kop{ font-size:12.5px; font-weight:600; color:var(--inkt); margin-bottom:10px; }
.m-retour-staven{ display:flex; align-items:flex-end; gap:6px; height:56px; }
.m-retour-staaf{
  flex:1; display:flex; flex-direction:column; justify-content:flex-end; align-items:center;
  height:100%; gap:4px; font-size:10.5px; color:var(--inkt-3);
}
.m-retour-staaf-vul{ width:100%; min-height:2px; border-radius:3px 3px 0 0; background:var(--primary); }

/* De bel in de kop, met een telling erop. Staat op de plek van de oude
   verversknop, dus dezelfde 44px aanraakmaat. */
.m-icon-btn{ position:relative; }
.m-icon-btn.aan{ background:var(--primary-zacht); color:var(--primary); }
.m-belteller{
  position:absolute; top:5px; right:5px; min-width:16px; height:16px; padding:0 4px;
  border-radius:999px; background:var(--fout); color:#fff;
  font-size:10px; font-weight:600; line-height:16px; text-align:center;
}
.m-belteller:empty{ display:none; }

/* Dagscheiding in de bestellijsten. Twan (02-09-2026): "Ik zou verder met
   datumscheidingen gaan werken zoals we ook bij 'bestellingen' op de desktop
   doen." Zelfde rol als .day-separator-row daar: een rustige regel die de dag
   noemt, zodat elke rij alleen nog de tijd hoeft te tonen. Sticky, want op een
   telefoon scrollt een dag lang door, maar plakken kan hier niet: de kop van
   de app plakt zelf al op top:0, dus die twee zouden over elkaar heen vallen.
   Desktop's .day-separator-row scrollt ook gewoon mee. */
.m-dagkop{
  margin:14px 0 6px; padding:5px 2px;
  font-size:11.5px; font-weight:600; letter-spacing:.02em;
  color:var(--inkt-2); background:var(--grond);
}
.m-dagkop:first-child{ margin-top:2px; }

/* ---------- het omhulsel ---------- */
.m-header{
  position:sticky; top:0; z-index:10;
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:10px 16px 10px; padding-top:calc(10px + env(safe-area-inset-top));
  /* Twan, 01-09-2026: "Ook de bovenkant van deze schermen zie ik liever in
     wit." Die balk was 88% wit met een blur erachter, dus de grijze pagina
     (--gray, #F8F9FA) schemerde erdoorheen en de strook las als lichtgrijs —
     zeker in de veilige zone bovenaan, waar niets overheen scrolt. Nu dekkend
     var(--vlak): wit in de lichte stand, en in de donkere stand gewoon donker,
     want dat is hetzelfde token. De blur kan daarmee weg; die deed achter een
     dekkend vlak toch niets meer. */
  background:var(--vlak);
  border-bottom:1px solid var(--lijn);
}
.m-header .m-brand{ margin:0; font-size:17px; text-align:left; }
.m-icon-btn{
  border:none; background:var(--vlak-2); color:var(--inkt);
  width:44px; height:44px; border-radius:var(--r-s);   /* 44px: de ondergrens voor een aanraakvlak */
  font-size:18px; display:flex; align-items:center; justify-content:center;
}
.m-icon-btn:disabled{ opacity:.45; }
.m-icon-btn:active{ background:var(--lijn); }
.m-icon-btn.spin i,.m-spin-icon{ animation:m-spin .9s linear infinite; display:inline-block; }
@keyframes m-spin{ from{transform:rotate(0)} to{transform:rotate(360deg)} }

.m-content{
  padding:var(--ruimte);
  padding-bottom:calc(var(--tab-hoogte) + env(safe-area-inset-bottom) + 24px);
  padding-left:calc(var(--ruimte) + env(safe-area-inset-left));
  padding-right:calc(var(--ruimte) + env(safe-area-inset-right));
  max-width:560px; margin:0 auto;
}

/* DE TABBALK EN DE HOME-INDICATOR.
   Dit was de klacht. De balk zelf is 56px hoog; daaronder komt de veilige zone
   erbij, zodat de knoppen nooit onder het streepje van de iPhone vallen. */
.m-tabbar{
  position:fixed; bottom:0; left:0; right:0; z-index:10;
  display:flex; align-items:stretch;
  height:calc(var(--tab-hoogte) + env(safe-area-inset-bottom));
  padding-bottom:env(safe-area-inset-bottom);
  padding-left:env(safe-area-inset-left); padding-right:env(safe-area-inset-right);
  background:color-mix(in srgb, var(--vlak) 88%, transparent);
  -webkit-backdrop-filter:saturate(180%) blur(14px); backdrop-filter:saturate(180%) blur(14px);
  border-top:1px solid var(--lijn);
}
.m-tab{
  flex:1; min-width:0; border:none; background:transparent;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  padding:6px 2px; font-size:11px; font-weight:500; color:var(--inkt-3); position:relative;
}
.m-tab i{ font-size:22px; line-height:1; }
.m-tab span{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
.m-tab.active{ color:var(--primary); }
.m-tab.active i{ transform:translateY(-1px); }
.m-tab:active{ opacity:.6; }
.m-badge{
  position:absolute; top:4px; left:calc(50% + 6px);
  background:var(--fout); color:#fff; font-size:10px; font-weight:700;
  min-width:17px; height:17px; border-radius:9px;
  display:flex; align-items:center; justify-content:center; padding:0 4px;
  border:2px solid var(--vlak);
}

/* ---------- "Meer"-menu ---------- */
.m-more-backdrop{ position:fixed; inset:0; z-index:19; background:rgba(10,14,18,.28); }
.m-more-menu{
  position:fixed; right:12px; left:12px; z-index:20;
  bottom:calc(var(--tab-hoogte) + env(safe-area-inset-bottom) + 10px);
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-l);
  box-shadow:var(--schaduw-zwevend); padding:8px;
  max-width:340px; margin-left:auto;
}
.m-more-item{
  display:flex; align-items:center; gap:12px; width:100%; border:none; background:transparent;
  color:var(--inkt); font-size:15px; padding:13px 12px; border-radius:var(--r-s); text-align:left; min-height:48px;
}
.m-more-item i{ font-size:19px; width:22px; text-align:center; color:var(--inkt-3); }
.m-more-item:active{ background:var(--vlak-2); }
.m-more-item.active{ color:var(--primary); background:var(--primary-zacht); }
.m-more-item.active i{ color:var(--primary); }

/* ---------- filter- en periodepillen ---------- */
.m-pill-tabs{
  display:flex; gap:6px; margin-bottom:12px; overflow-x:auto;
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
  margin-left:calc(var(--ruimte) * -1); margin-right:calc(var(--ruimte) * -1);
  padding:2px var(--ruimte);
}
.m-pill-tabs::-webkit-scrollbar{ display:none; }
.m-pill-tabs button{
  flex-shrink:0; border:1px solid var(--lijn); background:var(--vlak); color:var(--inkt-2);
  /* 44px is de ondergrens voor een aanraakvlak (Apple HIG en WCAG 2.5.8);
     deze stonden op 40. */
  font-size:14px; font-weight:500; padding:0 16px; border-radius:999px; white-space:nowrap;
  min-height:44px; display:inline-flex; align-items:center;
}
.m-pill-tabs button.active{ background:var(--primary); border-color:var(--primary); color:#fff; font-weight:600; }
.m-pill-tabs button:active{ transform:scale(.97); }

/* ---------- het hoofdgetal ----------
   Op een telefoon kijk je naar één of twee dingen. Omzet en winst krijgen
   daarom het formaat dat daarbij hoort; de rest zit eronder in een raster. */
.m-hero{
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-l);
  box-shadow:var(--schaduw-kaart); padding:18px 18px 16px; margin-bottom:10px;
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
}
/* Met grafiek erin wordt de kaart tweeregelig: bedragen boven, staven eronder.
   flex-wrap i.p.v. een tweede container, zodat de bestaande twee kolommen hun
   uitlijning houden. */
.m-hero.met-grafiek{ flex-wrap:wrap; }
.m-hero-grafiek{ flex:1 0 100%; margin-top:16px; }
.m-hero-hoofd{ min-width:0; }
.m-hero-label{ font-size:13px; color:var(--inkt-2); margin-bottom:2px; }
.m-hero-waarde{ font-size:34px; line-height:1.05; font-weight:680; letter-spacing:-.025em; color:var(--inkt); }
.m-hero-neven{ text-align:right; flex-shrink:0; padding-left:16px; border-left:1px solid var(--lijn); }
.m-hero-neven-waarde{ font-size:20px; font-weight:650; letter-spacing:-.015em; margin-top:1px; }
.m-hero-neven-waarde.goed{ color:var(--goed); }
.m-hero-neven-waarde.slecht{ color:var(--fout); }
.m-hero-marge{ font-size:12px; color:var(--inkt-3); margin-top:2px; }
.m-delta{ font-size:13px; margin-top:6px; display:inline-flex; align-items:center; gap:4px; }
.m-delta.good{ color:var(--goed); }
.m-delta.bad{ color:var(--fout); }
.m-delta.vlak{ color:var(--inkt-3); }

/* ---------- kaarten ---------- */
.m-cards{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:18px; }
.m-cards-3{ grid-template-columns:1fr 1fr; }   /* drie kolommen past niet op 375px */
.m-card{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:14px 15px; box-shadow:var(--schaduw-kaart); }
.m-cards-3 .m-card{ padding:14px 15px; }
.m-card-label{ font-size:13px; color:var(--inkt-2); margin-bottom:3px; }
.m-card-value{ font-size:22px; font-weight:650; letter-spacing:-.02em; color:var(--inkt); line-height:1.15; }
.m-cards-3 .m-card-value{ font-size:22px; }
.m-card-delta{ font-size:12.5px; margin-top:4px; }
.m-card-delta.good{ color:var(--goed); }
.m-card-delta.bad{ color:var(--fout); }

.m-section-title{
  font-size:13px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  color:var(--inkt-3); margin:22px 0 9px;
  display:flex; align-items:center; justify-content:space-between; gap:8px;
}
.m-section-title:first-child{ margin-top:0; }
.m-empty{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:22px 16px; text-align:center; color:var(--inkt-3); font-size:14px; }

/* ---------- rijen ---------- */
.m-row{
  display:flex; align-items:center; gap:12px;
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m);
  padding:12px 14px; margin-bottom:8px; cursor:pointer; min-height:60px;
}
.m-row:active{ background:var(--vlak-2); }
.m-row-thumb{ width:42px; height:42px; border-radius:var(--r-s); object-fit:contain; background:#FFFFFF; flex-shrink:0; }
/* Het lege plaatsvervangervakje (een <div>, geen <img>) blijft wél grijs — een
   wit vierkant zou eruitzien als een foto die niet laadt. */
div.m-row-thumb{ background:var(--vlak-2); }
.m-row-body{ flex:1; min-width:0; }
.m-row-title{ font-size:15px; font-weight:550; color:var(--inkt); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; letter-spacing:-.006em; }
/* Eén regel, met puntjes als het niet past. Zonder dit brak "0x op voorraad"
   over twee regels bij lange EAN's en werden de rijen ongelijk hoog — dat
   maakt een lijst onrustig om doorheen te scannen. */
.m-row-sub,.m-row-sub2{ font-size:13px; color:var(--inkt-2); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.m-row-right{ text-align:right; flex-shrink:0; }
.m-row-right b{ font-size:16px; font-weight:650; letter-spacing:-.015em; }
.m-dot{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:7px; flex-shrink:0; }
.m-status-chip{ display:flex; align-items:center; font-size:13px; color:var(--inkt-2); margin-top:3px; }
.m-chip{ display:inline-block; font-size:11.5px; font-weight:650; padding:2px 8px; border-radius:999px; margin-left:6px; vertical-align:middle; }
.m-chip-red{ background:var(--fout-zacht); color:var(--fout); }
.m-chip-orange{ background:var(--waarschuwing-zacht); color:var(--waarschuwing); }
.m-chip-primary{ background:var(--primary-zacht); color:var(--primary); }
/* Een webhook die al dagen zwijgt terwijl de sync wél orders binnenhaalt. Het
   blauwe label zei "webhook" zolang wij ooit een abonnement hadden aangemaakt —
   ook toen bol ze op 15-09-2026 had uitgezet (21-09-2026). */
.m-chip-warn{ background:var(--waarschuwing-zacht); color:var(--waarschuwing); }

/* ---------- detailschermen ---------- */
.m-detail-header{ display:flex; align-items:center; gap:10px; margin-bottom:16px; }
.m-detail-title{ font-size:19px; font-weight:650; letter-spacing:-.015em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.m-detail-section{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:14px 15px; margin-bottom:8px; font-size:14px; line-height:1.5; }
.m-kv-row{ display:flex; justify-content:space-between; gap:12px; padding:8px 0; }
.m-kv-row:not(:last-child){ border-bottom:1px solid var(--lijn); }
.m-kv-label{ color:var(--inkt-2); flex-shrink:0; }
.m-kv-value{ text-align:right; font-weight:500; }

/* ---------- zoeken ---------- */
.m-search{
  width:100%; font-size:16px; padding:13px 15px; border-radius:var(--r-m);
  border:1px solid var(--lijn-sterk); background:var(--vlak); color:var(--inkt);
  margin-bottom:14px; min-height:48px;
}
.m-search:focus-visible{ outline:2px solid var(--primary); outline-offset:1px; border-color:transparent; }
.m-search::placeholder{ color:var(--inkt-3); }

/* ---------- meldingen ---------- */
.m-notif-strip{
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m);
  padding:13px 15px; margin-bottom:14px; display:flex; align-items:center;
  justify-content:space-between; gap:10px; cursor:pointer; min-height:52px;
}
.m-notif-strip:active{ background:var(--vlak-2); }
.m-notif-strip-label{ font-size:15px; font-weight:550; }
.m-notif{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:13px 14px; margin-bottom:8px; display:flex; gap:11px; align-items:flex-start; }
.m-notif-icon{ width:28px; height:28px; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:14px; flex-shrink:0; margin-top:1px; }
.m-notif-icon.info{ background:var(--primary-zacht); color:var(--primary); }
.m-notif-icon.warn{ background:var(--waarschuwing-zacht); color:var(--waarschuwing); }
.m-notif-icon.error{ background:var(--fout-zacht); color:var(--fout); }
.m-notif-text{ flex:1; font-size:14px; line-height:1.45; }
.m-notif-date{ font-size:12.5px; color:var(--inkt-3); margin-top:3px; }
.m-notif-dismiss{ border:none; background:transparent; color:var(--inkt-3); font-size:18px; width:44px; height:44px; flex-shrink:0; margin:-8px -8px 0 0; }

/* ---------- koppelingen ---------- */
.m-conn-row{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:14px 15px; margin-bottom:9px; }
.m-conn-top{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.m-conn-name{ font-size:15px; font-weight:600; }
.m-conn-sub{ font-size:13px; color:var(--inkt-2); margin-top:3px; }
.m-conn-error{ font-size:13px; color:var(--fout); margin-top:5px; }
.m-conn-btns{ display:flex; gap:8px; flex-shrink:0; }
.m-conn-sync-btn{ flex-shrink:0; border:1px solid var(--lijn); background:var(--vlak-2); color:var(--inkt); font-size:14px; font-weight:600; padding:0 14px; min-height:44px; border-radius:var(--r-s); display:flex; align-items:center; gap:6px; }
.m-conn-sync-btn:disabled{ opacity:.55; }
.m-conn-sync-btn:active{ background:var(--lijn); }
.m-conn-webhook-btn{ border:1px solid var(--lijn); background:var(--vlak-2); color:var(--inkt); width:44px; height:44px; border-radius:var(--r-s); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.m-conn-webhook-btn.active{ background:var(--primary-zacht); border-color:var(--primary-zacht); color:var(--primary); }
.m-refresh-all-btn{ width:100%; border:none; background:var(--primary); color:#fff; font-size:16px; font-weight:600; padding:0; min-height:50px; border-radius:var(--r-m); margin-bottom:14px; display:flex; align-items:center; justify-content:center; gap:8px; }
.m-refresh-all-btn:disabled{ opacity:.6; }
.m-refresh-all-btn:active{ filter:brightness(.92); }

/* ---------- instellingen ---------- */
.m-settings-card{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:2px 16px; margin-bottom:16px; }
.m-settings-row{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:15px 0; border-bottom:1px solid var(--lijn); min-height:56px; }
.m-settings-row:last-child{ border-bottom:none; }
.m-settings-row-label{ font-size:15px; font-weight:500; }
.m-settings-row-sub{ font-size:13px; color:var(--inkt-2); margin-top:3px; }
.m-settings-toggle{ width:24px; height:24px; flex-shrink:0; accent-color:var(--primary); }
.m-account-card{ background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-m); padding:18px 16px; margin-bottom:16px; display:flex; align-items:center; gap:14px; }
.m-avatar{ width:48px; height:48px; border-radius:50%; background:var(--vlak-2); object-fit:cover; flex-shrink:0; }
.m-avatar-fallback{ width:48px; height:48px; border-radius:50%; background:var(--primary); color:#fff; display:flex; align-items:center; justify-content:center; font-size:17px; font-weight:650; flex-shrink:0; }
.m-logout-btn{ width:100%; border:1px solid var(--lijn); background:var(--vlak); color:var(--fout); font-size:16px; font-weight:600; min-height:50px; border-radius:var(--r-m); }
.m-logout-btn:active{ background:var(--fout-zacht); }

.m-loading{ text-align:center; padding:48px 0; color:var(--inkt-3); font-size:14px; }

/* ---------------------------------------------------------------------------
   Voorstellen 3, 4 en 5 (30-08-2026), goedgekeurd na de mockups.
   --------------------------------------------------------------------------- */

/* ---- 3. periode als schuifknop, winkel in de kop ---- */
.m-segment{
  display:flex; background:var(--vlak-2); border-radius:11px; padding:3px; margin-bottom:12px;
}
.m-segment button{
  flex:1; border:none; background:transparent; color:var(--inkt-2);
  font-size:14px; font-weight:500; min-height:38px; border-radius:8px;
}
.m-segment button.aan{
  background:var(--vlak); color:var(--inkt); font-weight:650;
  box-shadow:0 1px 3px rgba(20,26,34,.12);
}
.m-segment button:active{ opacity:.7; }

/* .m-winkelkop is vervallen (03-09-2026): de winkelkiezer stond LINKS als de
   kop zelf en is een knop RECHTS geworden, naast de bel — zie .m-kop-knop.
   Twan: "Maak van de winkelselector ook een knop die rechts staat naast
   meldingen en dan het logo links." */
.m-winkelmenu-backdrop{ position:fixed; inset:0; z-index:29; background:rgba(10,14,18,.28); }
.m-winkelmenu{
  position:fixed; z-index:30; left:auto; right:12px; max-width:340px;
  /* Op een smal scherm mag hij alsnog de volle breedte pakken; anders wordt
     een lange koppelingsnaam onleesbaar. */
  min-width:min(340px, calc(100vw - 24px));
  top:calc(env(safe-area-inset-top) + 62px);
  background:var(--vlak); border:1px solid var(--lijn); border-radius:var(--r-l);
  box-shadow:var(--schaduw-zwevend); padding:8px;
}
.m-winkelmenu button{
  display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%;
  border:none; background:transparent; color:var(--inkt); font-size:15px;
  padding:12px; border-radius:var(--r-s); text-align:left; min-height:48px;
}
.m-winkelmenu button:active{ background:var(--vlak-2); }
.m-winkelmenu button.aan{ color:var(--primary); background:var(--primary-zacht); font-weight:600; }

/* ---- 4. status als kleurstreep, en een pijltje dat zegt: hier kun je op tikken ---- */
.m-row{ position:relative; }
.m-streep{
  position:absolute; left:0; top:0; bottom:0; width:3px;
  border-top-left-radius:var(--r-m); border-bottom-left-radius:var(--r-m);
}
/* Twan vond het orderdetail niet, en dat is geen wonder: een rij zag er niet
   uit alsof je erop kon tikken. Een pijltje is de conventie op iOS. */
.m-pijl{ font-size:16px; color:var(--inkt-3); flex-shrink:0; margin-left:2px; }

/* ---- 5. voorraad als staafje ---- */
.m-balk{
  height:4px; border-radius:2px; background:var(--vlak-2);
  overflow:hidden; margin-top:5px; max-width:150px;
}
.m-balk i{ display:block; height:100%; border-radius:2px; }
.m-op{ color:var(--fout); }
.m-op b{ font-weight:650; }
.m-bijna{ color:var(--waarschuwing); }
.m-bijna b{ font-weight:650; }

/* De status stond achteraan in de subregel en werd daar afgekapt — precies het
   woord dat ertoe doet. Nu vooraan, in dezelfde kleur als de streep links, zodat
   je hem ook ziet als de winkelnaam niet past. */
.m-status{ font-weight:600; }

/* Lange teksten in een detailkaart moeten afbreken. De uitleg bij een
   ontbrekende track & trace liep anders buiten de kaart door. */
.m-detail-section{ overflow-wrap:anywhere; word-break:break-word; }

/* Kleine knop in een instellingenrij (proefmelding). 44 px hoog, net als elk
   ander aanraakvlak in deze app. */
.m-knop-klein{
  appearance:none; border:1px solid var(--lijn-sterk); background:var(--vlak);
  color:var(--primary); font-family:inherit; font-size:14px; font-weight:600;
  min-height:44px; padding:0 16px; border-radius:var(--r-s); cursor:pointer;
}
.m-knop-klein:disabled{ opacity:.5; }

/* ---- staafgrafiek omzet (voorstel 7) ----
   De staven zijn <button>: ze zijn aan te tikken en dus ook met een
   toetsenbord of VoiceOver te bereiken. Een <div> met een klikafhandeling
   ziet er hetzelfde uit maar bestaat niet voor wie de app niet ziet. */
.m-grafiek{
  display:flex; align-items:flex-end; gap:2px; height:68px;
  margin:0 0 6px; padding:0 2px;
}
/* Een uur dat vandaag nog moet komen. Sinds 03-09-2026 staan alle 24 uren er
   altijd, zodat de grafiek in de loop van de dag van vorm verandert en niet van
   breedte — vlak na middernacht leek hij anders stuk (twee staafjes). */
.m-balkje.komt-nog{ opacity:.12; }
.m-balkje{
  flex:1; min-width:0; padding:0; border:0; border-radius:3px 3px 0 0;
  background:var(--primary); opacity:.35; cursor:pointer;
  transition:opacity .12s ease;
  /* Het aanraakvlak doortrekken tot de volle hoogte van de grafiek: een staaf
     van 4 pixels is anders niet te raken. */
  position:relative;
}
.m-balkje::after{ content:''; position:absolute; left:0; right:0; bottom:0; top:-68px; }
.m-balkje.top{ opacity:.6; }
.m-balkje.gekozen{ opacity:1; background:var(--inkt); }
.m-grafiek-as{
  display:flex; justify-content:space-between;
  font-size:11px; color:var(--inkt-3); font-variant-numeric:tabular-nums;
}
.m-grafiek-detail{
  display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  margin-top:8px; padding-top:8px; border-top:1px solid var(--lijn);
  font-size:13px; color:var(--inkt-2);
}
.m-grafiek-detail b{ font-size:16px; color:var(--inkt); font-variant-numeric:tabular-nums; white-space:nowrap; }
.m-grafiek-orders{ font-size:13px; font-weight:400; color:var(--inkt-2); }
.m-grafiek-hint{
  margin-top:8px; padding-top:8px; border-top:1px solid var(--lijn);
  font-size:12px; color:var(--inkt-3);
}
.m-grafiek-leeg{ font-size:13px; color:var(--inkt-3); padding:10px 0; }

/* ---- twee pagina's kaarten met een veeg (voorstel 8) ----
   scroll-snap, geen eigen touch-afhandeling: de browser levert de vaart en
   het vastklikken die bij het toestel horen. `overscroll-behavior-x: contain`
   voorkomt dat een veeg aan het einde de terug-navigatie van Safari opent. */
.m-schuif{
  display:flex; overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x mandatory; overscroll-behavior-x:contain;
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
  margin-bottom:6px;
}
.m-schuif::-webkit-scrollbar{ display:none; }
.m-schuif-pagina{ flex:0 0 100%; scroll-snap-align:start; }
.m-schuif .m-cards{ margin-bottom:0; }

.m-stippen{ display:flex; justify-content:center; gap:6px; margin:0 0 18px; }
.m-stippen i{
  width:6px; height:6px; border-radius:99px; background:var(--lijn-sterk);
  transition:width .16s ease, background .16s ease;
}
.m-stippen i.aan{ width:16px; background:var(--primary); }

/* Een kaart die ook een knop is (Bijna op → de productenlijst). */
.m-card-knop{
  appearance:none; font-family:inherit; text-align:left; width:100%;
  cursor:pointer; color:inherit;
}
.m-card-leeg{ font-size:16px; font-weight:500; color:var(--inkt-3); }

/* ===========================================================================
   BEWEGING EN GEBAREN (31-08-2026)
   ---------------------------------------------------------------------------
   Twan: "Ook kan het handig zijn om meer mobiele elementen zoals swipes toe te
   voegen en wat animaties om laadtijd te verbloemen. Bijvoorbeeld bij het
   opstarten kan een animatie van het logo de paar seconden al een stuk korter
   aan laten voelen." Goedgekeurd: voorstel 1, 2, 3, 4, 6 en 7. Voorstel 5
   (vegen op een bestelling) verviel: "het WMS hebben we niet in de mobiele
   versie nodig".

   Alles hieronder respecteert prefers-reduced-motion; zie het blok onderaan.
   Dat is geen formaliteit: bewegingsgevoeligheid is een echte instelling op
   een telefoon, en een app die daar doorheen walst is onbruikbaar.
   =========================================================================== */

/* ---- voorstel 1: opstartscherm ---- */
.m-splash{
  position:fixed; inset:0; z-index:200;
  background:var(--grond);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:26px;
  /* Onder de notch door doorkleuren, anders zie je een witte rand op een
     donkere telefoon. */
  padding:env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}
.m-splash.weg{ opacity:0; transform:scale(1.04); transition:opacity .3s ease, transform .3s ease; pointer-events:none; }

/* Om dezelfde reden stond hier een strook op het opstart- en inlogscherm. */

/* Het woordmerk in twee stukken. Eén afbeelding, twee keer uitgesneden: het
   donkere "Ibl" en het blauwe "ey" komen los binnen. De snijlijn ligt op 49%
   omdat de "l" daar eindigt in favicon.png (799px breed, de l stopt op ~395). */
.m-splash-merk{ position:relative; width:172px; height:86px; }
/* Het woordmerk als MASKER, niet als plaatje.
   ---------------------------------------------------------------------------
   Eerst stond hier `background:url('/favicon.png')`. Dat brak in donkere
   modus: de "Ibl" in favicon.png is donkerblauw (#1E2749) en dat is op de
   donkere achtergrond (#0C1014) nagenoeg onzichtbaar — je zag alleen "ey"
   zweven. Gezien op een schermafdruk, niet bedacht.

   Met een masker bepaalt de PNG alleen de VORM en komt de kleur uit de
   tokens. Daarmee volgt het logo het thema: "Ibl" in --inkt (donker op licht,
   bijna wit op donker) en "ey" in --primary, die zelf al per thema verschilt.
   De PNG heeft een doorzichtige achtergrond, dus het alfakanaal is de vorm. */
.m-splash-merk span{
  position:absolute; inset:0; opacity:0;
  background:var(--merk-kleur);
  -webkit-mask:url('/favicon.png') no-repeat center / 100% auto;
  mask:url('/favicon.png') no-repeat center / 100% auto;
}
.m-splash-merk .ibl{ --merk-kleur:var(--inkt); clip-path:inset(0 51% 0 0); animation:m-ibl .52s cubic-bezier(.22,1,.36,1) forwards; }
.m-splash-merk .ey{ --merk-kleur:var(--primary); clip-path:inset(0 0 0 49%); animation:m-ey .58s cubic-bezier(.22,1,.36,1) .16s forwards; }
@keyframes m-ibl{ from{ opacity:0; transform:translateX(-13px); } to{ opacity:1; transform:none; } }
@keyframes m-ey{ from{ opacity:0; transform:translateX(15px); } to{ opacity:1; transform:none; } }

.m-splash-onder{ display:flex; flex-direction:column; align-items:center; gap:9px; }
.m-splash-balk{ width:132px; height:3px; border-radius:2px; background:var(--lijn-sterk); overflow:hidden; }
.m-splash-balk i{ display:block; height:100%; width:0; background:var(--primary); border-radius:2px; transition:width .28s ease; }
.m-splash-stap{ font-size:11.5px; color:var(--inkt-3); height:16px; letter-spacing:.02em; }

/* ---- voorstel 2: skeletschermen ---- */
.m-sk{ background:var(--vlak-2); border-radius:6px; position:relative; overflow:hidden; }
.m-sk::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform:translateX(-100%); animation:m-glans 1.25s infinite;
}
@keyframes m-glans{ 100%{ transform:translateX(100%); } }
.m-skelet{ padding-top:4px; }
.m-skelet .m-card, .m-skelet .m-hero{ pointer-events:none; }
.m-skelet-rij{ display:flex; align-items:center; gap:10px; padding:11px 0; border-bottom:1px solid var(--lijn); }

/* ---- voorstel 4: trekken om te verversen ---- */
.m-trek{
  position:fixed; left:0; right:0; z-index:40;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
  color:var(--primary); font-size:19px;
  opacity:0; pointer-events:none;
  will-change:transform, opacity;
}
/* De versheid staat hier en niet permanent in de kop. Op een telefoon is
   verticale ruimte het schaarste dat er is — daar is eerder een hele
   filterrij voor gesneuveld (voorstel 3, 30-08-2026). Onder je duim tijdens
   het trekken is precies het moment dat je je afvraagt hoe oud dit is. */
.m-trek span{ font-size:11.5px; font-weight:600; color:var(--inkt-3); letter-spacing:.01em; }
.m-trek.draait i{ animation:m-draai .7s linear infinite; }
@keyframes m-draai{ to{ transform:rotate(360deg); } }

/* ---- voorstel 6 en 7: het scherm ernaast ---- */
.m-naast{
  position:fixed; left:0; right:0; z-index:30;
  overflow:hidden; background:var(--grond);
  display:none;
  will-change:transform;
}
.m-naast .m-naast-binnen{ padding:0 var(--ruimte); height:100%; overflow:hidden; }
/* Bij terugvegen ligt het detailscherm bovenop en hoort er een rand-schaduw
   op, zodat je ziet dat er iets onder ligt in plaats van naast. */
.m-content.m-schuift{ will-change:transform; }
.m-content.m-boven{ box-shadow:-8px 0 24px rgba(20,26,34,.14); }


@media (prefers-reduced-motion: reduce){
  .m-splash-merk span{ animation:none; opacity:1; }
  .m-splash.weg{ transition:none; }
  .m-sk::after{ animation:none; }
  .m-trek.draait i{ animation:none; }
}

/* ---- kopbalk: logo links, acties rechts (03-09-2026) ----
   Twan: "Maak van de winkelselector ook een knop die rechts staat naast
   meldingen en dan het logo links want dan kan dit zo door de gehele app
   uniform gemaakt worden."
   En over het logo: "Niet het IB icoontje maar echt het Ibley logo van de
   animatie wanneer de app opstart." Dus dezelfde maskertechniek als
   .m-splash-merk hierboven: favicon.png bepaalt de VORM, de kleur komt uit de
   tokens. Daarmee volgt het logo het thema in plaats van weg te vallen op een
   donkere achtergrond — dat was daar al een keer misgegaan. */
.m-merk{ position:relative; display:block; width:68px; height:34px; flex-shrink:0; }
.m-merk span{
  position:absolute; inset:0;
  background:var(--merk-kleur);
  -webkit-mask:url('/favicon.png') no-repeat center / 100% auto;
  mask:url('/favicon.png') no-repeat center / 100% auto;
}
.m-merk .ibl{ --merk-kleur:var(--inkt); clip-path:inset(0 51% 0 0); }
.m-merk .ey{ --merk-kleur:var(--primary); clip-path:inset(0 0 0 49%); }

.m-kop-acties{ display:flex; align-items:center; gap:6px; }
.m-kop-knop{
  display:flex; align-items:center; gap:6px;
  font:inherit; font-size:13px; padding:0 12px;
  /* Dezelfde vorm als .m-icon-btn hierboven: 44 punten hoog (de ondergrens
     voor een aanraakvlak), var(--r-s) ronding, geen rand.
     Hier stond var(--radius-veld) — dat token bestaat alleen in het
     DESKTOP-stylesheet, dus de knop had in het geheel géén ronding. */
  height:44px; border-radius:var(--r-s); border:none;
  background:var(--vlak-2); color:var(--inkt); cursor:pointer;
  max-width:160px;
}
.m-kop-knop:active{ background:var(--lijn); }
/* De winkelnaam mag krimpen; het logo en de pijl niet. Zonder dit duwt een
   lange koppelingsnaam de bel van het scherm af.
   Twan (03-09-2026): "Zet anders een Shopify of Bol icoontje ervoor en snijd
   aan de achterkant af. Je kan geen 2 gelijknamige Bol accounts hebben namelijk
   dus zo is het onderscheid wel duidelijk." Klopt: met het platform in het logo
   mag het woord "Bol"/"Shopify" uit de tekst, en binnen één platform zijn de
   namen per definitie uniek. */
.m-kop-knop #mWinkelNaam{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.m-kop-knop > i{ flex-shrink:0; font-size:15px; }
/* De logo's zijn PNG's met een eigen breedte (bol 22x8, Shopify 13x15); die
   niet laten krimpen, anders vervormen ze bij een lange naam. */
.m-kop-logo{ flex-shrink:0; display:inline-flex; align-items:center; }
.m-kop-logo img{ margin-right:0 !important; }
/* In de lijst staat het logo vóór de naam, met wat lucht ertussen. */
.m-winkelmenu button span{ display:inline-flex; align-items:center; gap:6px; }
/* Het neutrale winkelicoon bij "Alle winkels" (03-09-2026). De merklogo's zijn
   PNG's van 22x8 (bol) en 13x15 (Shopify); dit is een letterglyph. Op 15px en
   met een vaste breedte van 22px staat hij op dezelfde lijn als de bolPNG, de
   breedste van de twee — anders springt de tekst per regel een paar pixels op
   en neer. */
.m-winkel-icoon{ font-size:15px; width:22px; flex-shrink:0; text-align:center; color:var(--inkt-3); }
.m-kop-knop .m-kop-pijl{ font-size:13px; opacity:.7; }

/* Hier stond een .m-header::before die de zone achter de klok blauw verfde.
   Die zone is niet van ons: iOS tekent er zijn eigen ondoorzichtige strook en
   zet onze pagina daaronder, ook met black-translucent. env(safe-area-inset-top)
   is binnen de pagina dan nul, dus die strook was nul pixels hoog. Zie de
   uitleg bovenaan mobile.html. */
