/*
 * FastLocated — shopper app.
 *
 * Phone first. Somebody is holding this one-handed in an aisle with a trolley in the other
 * hand, so: bottom tab bar within thumb reach, 44px minimum targets, and the primary action
 * pinned above the bar rather than scrolled off the end of a list. The desktop layout is a
 * widening of the same information architecture, not a different app.
 */

:root {
  --bg: #f2f5f9;
  --panel: #ffffff;
  --ink: #0c1424;
  --muted: #5a6b85;
  --faint: #93a2b8;
  --line: #e4eaf1;
  --line-strong: #cfd9e6;

  --accent: #f26308;
  --accent-dark: #d24f00;
  --accent-soft: #fff3ea;
  --on-accent: #ffffff;
  /* Text on --accent-soft. Darker than --accent in the light theme, lighter in the dark one:
     one token so a component does not have to know which theme it is in. */
  --accent-ink: #b34500;

  --warn: #a1590b;
  --warn-soft: #fef5e7;
  --danger: #c62a20;
  --danger-soft: #fdefee;
  --ok: #12703a;
  --ok-soft: #eaf7ef;

  --floor: #f6f9fc;
  --hull: #ffffff;
  --hull-line: #c5d1e0;
  --garden-hull: #edfaf1;
  --garden-line: #b2e2c4;
  --walkway: #e8eff7;
  --rack: #b5c3d5;

  --d-bouw: #ecdfcd;      --d-bouw-head: #dcc7a9;
  --d-wand: #d7e6f4;      --d-wand-head: #b6d2ec;
  --d-install: #dde2ef;   --d-install-head: #c1cade;
  --d-ijzer: #e0e5eb;     --d-ijzer-head: #c3cbd6;
  --d-afwerk: #e8daef;    --d-afwerk-head: #d1bade;
  --d-tuin: #d5edda;      --d-tuin-head: #b0dcbf;
  --d-overig: #e5e9ef;    --d-overig-head: #ced5df;

  --shadow-sm: 0 1px 2px rgba(12,20,36,.06);
  --shadow: 0 1px 2px rgba(12,20,36,.05), 0 8px 24px rgba(12,20,36,.07);
  --shadow-lg: 0 -2px 20px rgba(12,20,36,.09);
  --r: 14px;
  --tab-h: 58px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #070c16; --panel: #121a29; --ink: #e9eef8; --muted: #94a3b9; --faint: #67768e;
    --line: #202b40; --line-strong: #31405a;
    --accent-soft: #2a1a0c; --accent-ink: #ff9a52;
    --warn-soft: #2a2010; --danger-soft: #2c1513; --ok-soft: #112a1c;
    --floor: #0b1220; --hull: #121a29; --hull-line: #29354c;
    --garden-hull: #0f2118; --garden-line: #224531; --walkway: #17203180; --rack: #384863;
    --d-bouw: #2a2318;      --d-bouw-head: #3b3122;
    --d-wand: #152639;      --d-wand-head: #1d344e;
    --d-install: #191f31;   --d-install-head: #222b44;
    --d-ijzer: #1b2130;     --d-ijzer-head: #252d40;
    --d-afwerk: #241a2f;    --d-afwerk-head: #322342;
    --d-tuin: #13281c;      --d-tuin-head: #1b3927;
    --d-overig: #191f2e;    --d-overig-head: #232b3c;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.5);
    --shadow: 0 1px 2px rgba(0,0,0,.5), 0 10px 28px rgba(0,0,0,.4);
    --shadow-lg: 0 -2px 24px rgba(0,0,0,.5);
  }
}

/* A hidden element is hidden. Component `display` rules otherwise silently beat the
   browser's own [hidden] rule, which is how empty cards ended up on screen. */
[hidden] { display: none !important; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; margin: 0; overscroll-behavior: none; }
body {
  background: var(--bg); color: var(--ink);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
button, input { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; padding: 0; }
h1, h2, h3 { margin: 0; }

/* ------------------------------------------------------------------ shell --- */

.app {
  display: grid;
  /* topbar / views / plan bar / tab bar. The plan bar collapses to nothing when hidden, so the
     same grid serves both states without a second layout. */
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  height: 100dvh;
  max-width: 1400px; margin: 0 auto;
  background: var(--bg);
}

.topbar {
  background: var(--panel); border-bottom: 1px solid var(--line);
  padding: max(8px, env(safe-area-inset-top)) 14px 10px;
  display: grid; gap: 10px; z-index: 5;
}
.brandrow { display: flex; align-items: center; gap: 9px; min-width: 0; }
.mark { width: 30px; height: 30px; border-radius: 9px; flex: 0 0 30px; background: var(--accent); display: grid; place-items: center; box-shadow: var(--shadow-sm); }
.mark svg { width: 18px; height: 18px; }
.brandrow h1 { font-size: 17px; letter-spacing: -.02em; font-weight: 780; }
.brandrow .store { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.brandrow .store b { color: var(--ink); font-weight: 650; }
.brandrow .spacer { flex: 1; }
.pill-meta { font-size: 11.5px; color: var(--faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .pill-meta { display: none; } }

.searchbar { position: relative; display: flex; gap: 8px; }
.searchbar .icon { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 17px; height: 17px; color: var(--faint); pointer-events: none; }
#q { flex: 1; min-width: 0; height: 44px; padding: 0 12px 0 38px; border-radius: 12px; border: 1px solid var(--line-strong); background: var(--bg); }
#q:focus { outline: 2px solid var(--accent); outline-offset: -1px; background: var(--panel); }
.btn { height: 44px; padding: 0 17px; border-radius: 12px; background: var(--accent); color: var(--on-accent); font-weight: 680; white-space: nowrap; display: inline-flex; align-items: center; justify-content: center; gap: 7px; }
.btn:active { background: var(--accent-dark); }
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn.ghost { background: transparent; color: var(--muted); border: 1px solid var(--line-strong); font-weight: 550; }
.btn.block { width: 100%; }

/* ------------------------------------------------------------------ views --- */

main { overflow: hidden; display: grid; min-height: 0; }
.view { overflow: auto; -webkit-overflow-scrolling: touch; padding: 12px 14px 18px; display: none; }
.view.on { display: block; }
.view.flush { padding: 0; overflow: hidden; }

.sectionhead { display: flex; align-items: baseline; gap: 8px; margin: 4px 2px 10px; }
.sectionhead h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .09em; color: var(--faint); font-weight: 780; }
.sectionhead .count { background: var(--panel); border: 1px solid var(--line); color: var(--muted); border-radius: 99px; padding: 1px 8px; font-size: 11px; }
.sectionhead .spacer { flex: 1; }
.sectionhead button { font-size: 12.5px; color: var(--accent); font-weight: 620; }

/* ---- hero (home) ---- */
.hero { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); padding: 16px; margin-bottom: 14px; }
.hero h3 { font-size: 19px; letter-spacing: -.02em; margin-bottom: 5px; }
.hero p { margin: 0; color: var(--muted); font-size: 13.5px; }
.hero .compare { display: flex; gap: 10px; margin-top: 13px; }
.hero .compare > div { flex: 1; border-radius: 11px; padding: 9px 11px; border: 1px solid var(--line); }
.hero .compare .before { background: var(--bg); }
.hero .compare .after { background: var(--accent-soft); border-color: var(--accent); }
.hero .compare span { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--faint); font-weight: 720; }
.hero .compare b { font-size: 14.5px; font-weight: 700; }
.hero .compare .after b { color: var(--accent); }

/* ---- department grid ---- */
.deptgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.deptcard {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 13px; text-align: left; box-shadow: var(--shadow-sm);
  display: grid; gap: 8px; min-height: 92px; align-content: start;
  transition: transform .12s ease, border-color .12s ease;
}
.deptcard:active { transform: scale(.985); }
.deptcard:hover { border-color: var(--accent); }
.deptcard .swatch { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; }
.deptcard .swatch svg { width: 19px; height: 19px; stroke: var(--ink); opacity: .75; }
.deptcard .nm { font-weight: 660; font-size: 14px; line-height: 1.25; }
.deptcard .sub { font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }

/* ---- product rows ---- */
.list { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-sm); overflow: hidden; }
.row { display: flex; gap: 11px; align-items: flex-start; padding: 11px 13px; border-top: 1px solid var(--line); }
.row:first-child { border-top: 0; }
.row .grow { flex: 1; min-width: 0; }
.row .nm { font-weight: 570; line-height: 1.35; font-size: 14.5px; }
.row .meta { font-size: 12.5px; color: var(--muted); margin-top: 4px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.row .pricerow { display: flex; align-items: baseline; gap: 8px; margin-top: 5px; }
.price { font-variant-numeric: tabular-nums; font-weight: 720; font-size: 15px; }
.unit { font-size: 11.5px; color: var(--faint); }

.bin { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 7px; padding: 2px 8px; font-size: 12px; white-space: nowrap; }
.bin.coarse { color: var(--muted); background: var(--bg); font-weight: 600; }
/*
 * The bin badge is the payload of the row, and it was sliding out from under itself: a
 * nowrap flex item with no min-width does not shrink, it overflows, so on a phone the badge
 * ran straight under the buttons and took "Niveau 2" with it. Measured at 375 px it wanted
 * 198 px inside a 164 px column.
 *
 * It wraps rather than truncating on purpose. Cutting the end off is exactly the wrong half
 * to lose - the tier is the part the retailer's own website does not give you.
 */
.row .meta .bin { min-width: 0; }
@media (max-width: 460px) {
  .row .meta .bin { white-space: normal; }
}
.tag { font-size: 11px; padding: 2px 8px; border-radius: 99px; font-weight: 600; }
.tag.stock { color: var(--ok); background: var(--ok-soft); }
.tag.warn { color: var(--warn); background: var(--warn-soft); }
.tag.danger { color: var(--danger); background: var(--danger-soft); }
.tag.mute { color: var(--faint); background: var(--bg); }

.add { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px; border: 1px solid var(--line-strong); color: var(--accent); font-size: 20px; display: grid; place-items: center; }
.add:hover { background: var(--accent-soft); border-color: var(--accent); }
.add.added { background: var(--accent); color: var(--on-accent); border-color: transparent; }

.stepper { display: flex; align-items: center; gap: 2px; border: 1px solid var(--line-strong); border-radius: 11px; overflow: hidden; flex: 0 0 auto; }
/* 44px is the smallest reliable touch target; a stepper gets hit repeatedly and
   in a hurry, so it is the last control that should be cramped. */
.stepper button { width: 42px; height: 44px; display: grid; place-items: center; color: var(--muted); font-size: 18px; }
.stepper button:hover { background: var(--bg); color: var(--accent); }
.stepper .n { min-width: 26px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 680; font-size: 14px; }

.empty { color: var(--muted); font-size: 13.5px; padding: 26px 16px; text-align: center; }
.empty strong { display: block; color: var(--ink); font-size: 15px; margin-bottom: 4px; }
.err { color: var(--danger); background: var(--danger-soft); border-radius: 10px; padding: 10px 12px; font-size: 13px; margin-bottom: 12px; }

.chips { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 12px; justify-content: center; }
.chips button { border: 1px solid var(--line-strong); border-radius: 99px; padding: 7px 13px; font-size: 13px; color: var(--muted); background: var(--panel); }
.chips button:hover { border-color: var(--accent); color: var(--accent); }

.skeleton { height: 62px; border-top: 1px solid var(--line); background: linear-gradient(90deg, var(--panel), var(--bg), var(--panel)); background-size: 200% 100%; animation: sh 1.15s infinite; }
@keyframes sh { to { background-position: -200% 0; } }

/* ---- cart ---- */
.carttotal { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-sm); padding: 13px; margin-top: 12px; display: grid; gap: 4px; }
.carttotal .line { display: flex; justify-content: space-between; align-items: baseline; }
.carttotal .line span { color: var(--muted); font-size: 13px; }
.carttotal .line.total b { font-size: 21px; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }

.dock { position: sticky; bottom: 0; padding: 12px 0 2px; background: linear-gradient(to top, var(--bg) 72%, transparent); }

/* ---- route ---- */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-sm); overflow: hidden; margin-bottom: 12px; }
.stats div { padding: 11px 13px; border-left: 1px solid var(--line); }
.stats div:first-child { border-left: 0; }
.stats span { display: block; font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .07em; font-weight: 740; }
.stats b { font-size: 21px; font-variant-numeric: tabular-nums; letter-spacing: -.025em; }

.list-row .btn.ghost { flex: 0 0 auto; padding: 0 14px; height: 40px; font-size: 13px; }
.acct { border: 1px solid var(--line); border-radius: 14px; padding: 13px; background: var(--surface); margin-bottom: 18px; }
.acct-note { margin: 0 0 10px; font-size: 13px; color: var(--muted); line-height: 1.45; }
.acct-creds { display: flex; flex-direction: column; gap: 6px; margin-bottom: 11px; }
.acct-cred { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.acct-cred .who { font-weight: 620; }
.acct-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* ------------------------------------------------------------- account --- */
/*
 * Its own screen, reached from the header. An account is a short errand run once, not a panel
 * to scroll past on the way to the shopping list.
 */
.acctbtn {
  position: relative; flex: 0 0 36px; width: 36px; height: 36px; border-radius: 11px;
  border: 1px solid var(--line-strong); color: var(--muted); display: grid; place-items: center;
}
.acctbtn svg { width: 19px; height: 19px; }
.acctbtn:hover { color: var(--accent); border-color: var(--accent); }
.acctbtn .dot {
  position: absolute; right: -2px; top: -2px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--ok); border: 2px solid var(--panel);
}

.authlead { margin: 0 2px 14px; font-size: 13.5px; color: var(--muted); line-height: 1.5; }
.authdoors { display: grid; gap: 9px; }
.authnote { margin: 6px 2px 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }

.authform { display: grid; gap: 12px; }
.field { display: grid; gap: 5px; }
.field > span { font-size: 12px; color: var(--muted); font-weight: 640; }
.field > span i { font-style: normal; color: var(--faint); font-weight: 500; }
.field input {
  height: 48px; padding: 0 13px; border-radius: 12px;
  border: 1px solid var(--line-strong); background: var(--bg); width: 100%;
}
.field input:focus { outline: 2px solid var(--accent); outline-offset: -1px; background: var(--panel); }
/* The code is read off one screen and typed on another, so it is set the way the pickup code
   and the transfer code are: large, monospaced, and spaced out. */
#inCode { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 23px; letter-spacing: 7px; font-weight: 700; }

.authhint { margin: 0; font-size: 12.5px; color: var(--muted); background: var(--accent-soft); border-radius: 10px; padding: 10px 12px; }
#authError { margin: 0; }

/* The ways out, spelled out rather than hidden behind a link nobody finds. */
.authalt { display: grid; gap: 2px; margin-top: 2px; }
.authlink { text-align: left; font-size: 13px; color: var(--accent-ink); font-weight: 620; padding: 7px 2px; }
.authlink:hover { text-decoration: underline; }

.authprofile { display: grid; gap: 14px; }
.whoami { display: flex; align-items: center; gap: 12px; }
.whoami .avatar {
  flex: 0 0 46px; height: 46px; border-radius: 14px; background: var(--accent);
  color: var(--on-accent); display: grid; place-items: center; font-size: 20px; font-weight: 800;
}
.whoami .grow { min-width: 0; }
.whoami b { display: block; font-size: 17px; font-weight: 720; }
.whoami span { font-size: 12.5px; color: var(--muted); }

.acct-creds { display: flex; flex-direction: column; gap: 6px; }
.acct-cred { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.acct-cred .who { font-weight: 620; }
.acct-actions { display: grid; gap: 8px; }
.acct-code { padding: 13px; border-radius: 11px; background: var(--accent-soft); text-align: center; }
.acct-code b { display: block; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 26px; letter-spacing: 4px; font-weight: 800; }
.acct-code span { font-size: 12px; color: var(--muted); }

/* Destructive and permanent, so it is set apart from the things that are not. */
.danger-zone { border: 1px solid var(--danger); border-radius: var(--r); padding: 13px; background: var(--danger-soft); }
.danger-zone b { display: block; font-size: 14px; font-weight: 700; color: var(--danger); }
.danger-zone p { margin: 5px 0 11px; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.danger-zone .confirm p { margin: 11px 0 8px; font-weight: 640; color: var(--ink); }
.danger-zone .row-btns { display: flex; gap: 8px; }
.danger-zone .row-btns .btn { flex: 1; }
.btn.danger { background: var(--danger); color: #fff; }
.btn.danger:active { background: #a3221a; }

/* ------------------------------------------------------------ plan bar --- */
/*
 * Sits directly above the tab bar so it is the first thing the thumb meets, and carries the
 * count so the shopper can see what they are about to be routed around without opening it.
 */
.planbar {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: var(--panel); border-top: 1px solid var(--line);
  box-shadow: var(--shadow-lg); z-index: 6;
}
.planbar .grow { flex: 1; min-width: 0; }
.planbar b { display: block; font-size: 14px; font-weight: 700; }
.planbar span { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.planbar .btn { flex: 0 0 auto; height: 46px; padding: 0 20px; }

/* ---- history lines ---- *//* ---- history lines ---- */
.list-toggle { margin-top: 7px; font-size: 12.5px; color: var(--accent-ink); font-weight: 660; padding: 4px 0; }
.list-lines { background: var(--panel); border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--r) var(--r); margin: -6px 0 10px; overflow: hidden; }
.list-lines .line-row { padding: 10px 13px; }
.list-lines .line-row .nm { font-size: 14px; }
.list-lines .rowacts { flex-direction: row; gap: 6px; align-items: center; }
.acct-actions .btn { flex: 1 1 auto; height: 44px; font-size: 13px; }
/* The transfer code is read off one screen and typed into another, so it is set large and
   monospaced with generous letter-spacing - the same reasoning as the pickup code. */
.acct-code { margin: 0 0 11px; padding: 13px; border-radius: 11px; background: var(--accent-soft); text-align: center; }
.acct-code b { display: block; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 26px; letter-spacing: 4px; font-weight: 800; }
.acct-code span { font-size: 12px; color: var(--muted); }
.stop-row { cursor: pointer; }
/* 44px, like the steppers: this gets tapped one-handed while pushing a trolley. */
.tick { flex: 0 0 auto; width: 44px; height: 44px; border: 1px solid var(--line-strong); border-radius: 11px; display: grid; place-items: center; color: var(--muted); font-size: 17px; font-weight: 800; background: var(--surface); }
.tick:hover { background: var(--ok, #157f3b); border-color: transparent; color: #fff; }
.stop-row:hover { background: var(--accent-soft); }
.seq { flex: 0 0 27px; height: 27px; border-radius: 50%; background: var(--accent); color: var(--on-accent); display: grid; place-items: center; font-size: 12.5px; font-weight: 800; font-variant-numeric: tabular-nums; }
.seq.done { background: var(--ok); }

/* ------------------------------------------------------------ navigation --- */
/*
 * Navigation is the map with guidance laid over it, not a card on a separate page.
 *
 * The order of importance for somebody standing in a warehouse aisle, phone in one hand,
 * trolley in the other:
 *
 *   1. which way now      -> the banner, top, accent, unmissable
 *   2. where that is      -> the map, filling everything between
 *   3. what comes next    -> the sheet, bottom, within thumb reach
 *   4. where the item is  -> the sheet again, on arrival
 *
 * Nothing here draws the shopper. When a position estimate arrives it becomes another layer
 * on the map underneath; none of this chrome has to move.
 */

.solobar {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
  background: var(--accent-soft); border: 1px solid var(--accent); border-radius: var(--r);
  padding: 10px 13px;
}
.solobar .grow { flex: 1; min-width: 0; }
.solobar b { display: block; font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.solobar span { font-size: 11.5px; color: var(--muted); }
.solobar button { flex: 0 0 auto; color: var(--accent-ink); font-weight: 660; font-size: 13px; padding: 8px; }

/* ---- the instruction banner ---- */
.navbar {
  position: absolute; left: 0; right: 0; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 13px;
  background: var(--accent); color: var(--on-accent);
  padding: 13px 14px calc(13px + 6px);
  box-shadow: 0 6px 20px rgba(12,20,36,.22);
}
.nav-icon { flex: 0 0 46px; height: 46px; border-radius: 13px; background: rgba(255,255,255,.19); display: grid; place-items: center; }
.nav-icon svg { width: 28px; height: 28px; fill: none; stroke: var(--on-accent); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* Right-hand manoeuvres are the mirror of the left-hand ones, so one glyph serves both. The
   flip is on the svg rather than the tile, or the tile mirrors with it. */
.nav-icon svg.flip { transform: scaleX(-1); }
.navbar-say { flex: 1; min-width: 0; display: grid; gap: 0; }
.navbar-say b { font-size: 29px; line-height: 1.05; letter-spacing: -.03em; font-weight: 800; font-variant-numeric: tabular-nums; }
.navbar-say span { font-size: 15.5px; font-weight: 640; line-height: 1.25; }
.navbar-aisle {
  flex: 0 0 auto; background: rgba(255,255,255,.2); border-radius: 99px;
  padding: 4px 11px; font-size: 12.5px; font-weight: 720; white-space: nowrap;
}

/* ---- the sheet ---- */
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  background: var(--panel); border-top: 1px solid var(--line);
  border-radius: 16px 16px 0 0; padding: 11px 14px calc(10px + env(safe-area-inset-bottom));
  box-shadow: var(--shadow-lg);
}
/* Which of how many, always on screen. The bar is the same fact in a shape the eye reads
   without counting, and it moves only when the shopper taps. */
.sheet-progress { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; }
.sheet-progress span { font-size: 11px; color: var(--muted); font-weight: 640; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sheet-progress .bar { flex: 1; height: 4px; border-radius: 99px; background: var(--line); overflow: hidden; }
.sheet-progress .bar::after { content: ""; display: block; height: 100%; width: var(--at, 0%); background: var(--accent); border-radius: 99px; }

.sheet-then { display: flex; align-items: center; gap: 11px; }
.sheet-then svg { width: 26px; height: 26px; flex: 0 0 26px; fill: none; stroke: var(--ink); stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }
.sheet-then svg.flip { transform: scaleX(-1); }
.sheet-then b { min-width: 0; font-size: 16px; font-weight: 700; line-height: 1.3; }

/* ---- arrival ---- */
.sheet-dest { border-radius: 12px; background: var(--accent-soft); border: 1px solid var(--accent); padding: 11px 12px; }
.sheet-dest .hand { font-size: 19px; font-weight: 800; color: var(--accent-ink); letter-spacing: -.02em; line-height: 1.2; }
.sheet-dest > b { display: block; font-size: 14px; font-weight: 620; margin-top: 3px; }
/* Set apart and tabular: this string gets read off the screen and matched against a plate on
   a rack upright, so the digits have to line up. */
.sheet-dest .bin { display: block; margin-top: 6px; font-size: 16px; font-weight: 760; font-variant-numeric: tabular-nums; }
.sheet-dest .from { display: block; margin-top: 3px; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sheet-dest .meta { display: flex; flex-wrap: wrap; gap: 6px; }
.sheet-dest .meta:not(:empty) { margin-top: 8px; }

/* ---- located article ---- */
.sheet-found b { display: block; font-size: 16px; font-weight: 700; line-height: 1.25; }
.sheet-found .bin { display: inline-block; margin-top: 7px; font-size: 15px; font-weight: 760; font-variant-numeric: tabular-nums; }
.sheet-found .foundmeta { display: block; margin-top: 5px; font-size: 12px; color: var(--muted); }

.sheet-ctl { display: flex; gap: 8px; margin-top: 10px; }
.sheet-ctl .btn { flex: 1; height: 46px; font-size: 14px; }
.sheet-ctl .btn:not(:first-of-type):last-of-type { flex: 0 0 96px; }

.sheet-honest { margin: 7px 2px 0; font-size: 10.5px; line-height: 1.3; color: var(--faint); }

/* While guiding, the shell gets out of the way of the map. Everything removed here is
   reachable from the tab bar, which stays. */
body.guiding .searchbar { display: none; }
body.guiding .topbar { padding-bottom: 8px; gap: 0; }

/* The top strip belongs to the banner and the bottom to the sheet, so everything else that
   lives at either edge moves out of the way. Zoom controls hidden behind the banner would be
   worse than no banner: the map is where you go when an instruction has confused you. */
.mapwrap.navigating .maptools { top: 86px; }
.mapwrap.navigating .maphint, .mapwrap.locating .maphint { top: 86px; }
.mapwrap.navigating .legend, .mapwrap.locating .legend { display: none; }
.mapwrap.locating .maptools { top: 11px; }

/* ---- search-result actions ---- */
.rowacts { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; }
.act {
  height: 34px; padding: 0 10px; border-radius: 10px; font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: flex-start; gap: 6px;
  border: 1px solid var(--line-strong); color: var(--muted); background: var(--panel);
  white-space: nowrap;
}
.act svg { width: 15px; height: 15px; flex: 0 0 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.act.find { border-color: var(--line-strong); }
.act.find:active { background: var(--bg); }
.act.go { border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }
.act.go:active { background: var(--accent); color: var(--on-accent); }

details.steps { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); margin-top: 12px; overflow: hidden; }
details.steps summary { padding: 12px 13px; cursor: pointer; font-size: 13.5px; color: var(--muted); font-weight: 600; }
details.steps ol { margin: 0; padding: 0 13px 12px 34px; }
details.steps li { font-size: 13px; color: var(--muted); padding: 3px 0; }

/* ------------------------------------------------------------------- map --- */

.mapwrap { position: relative; height: 100%; background: var(--floor); }
#map { width: 100%; height: 100%; display: block; touch-action: none; cursor: grab; }
#map.dragging { cursor: grabbing; }

.hull { fill: var(--hull); stroke: var(--hull-line); stroke-width: .35; }
.hull-garden { fill: var(--garden-hull); stroke: var(--garden-line); }
.walkway { fill: var(--walkway); }
.walkway-label { fill: var(--faint); font-weight: 720; letter-spacing: .14em; }

.dept-zone { fill: var(--d-overig); }
.dept-head { fill: var(--d-overig-head); }
.dept-bouw    .dept-zone { fill: var(--d-bouw); }     .dept-bouw    .dept-head { fill: var(--d-bouw-head); }
.dept-wand    .dept-zone { fill: var(--d-wand); }     .dept-wand    .dept-head { fill: var(--d-wand-head); }
.dept-install .dept-zone { fill: var(--d-install); }  .dept-install .dept-head { fill: var(--d-install-head); }
.dept-ijzer   .dept-zone { fill: var(--d-ijzer); }    .dept-ijzer   .dept-head { fill: var(--d-ijzer-head); }
.dept-afwerk  .dept-zone { fill: var(--d-afwerk); }   .dept-afwerk  .dept-head { fill: var(--d-afwerk-head); }
.dept-tuin    .dept-zone { fill: var(--d-tuin); }     .dept-tuin    .dept-head { fill: var(--d-tuin-head); }

.dept { transition: opacity .16s ease; cursor: pointer; }
.dept.dim { opacity: .32; }
.rack { fill: var(--rack); }
.dept-label { fill: var(--ink); font-weight: 760; pointer-events: none; }
.aisle-label { fill: var(--faint); font-weight: 680; font-variant-numeric: tabular-nums; pointer-events: none; }

.poi circle { stroke: var(--floor); }
.poi-entrance circle { fill: #0d7a63; }
.poi-checkout circle { fill: #7b3aed; }
.poi text { fill: var(--muted); font-weight: 720; }

.route-halo { fill: none; stroke: var(--floor); stroke-linejoin: round; stroke-linecap: round; opacity: .95; }
.route-line { fill: none; stroke: var(--accent); stroke-linejoin: round; stroke-linecap: round; }
.route-line.draw { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); animation: draw 1.2s cubic-bezier(.4,0,.2,1) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/*
 * Direction chevrons on the route.
 *
 * Open strokes rather than filled triangles: a solid arrowhead the width of the line reads
 * as a kink in the route at a glance, and at full-store zoom the route is only about a line
 * width wide to begin with. White works on the accent in both themes, since --accent does
 * not flip. They are decoration over the line, so they take no pointer events - the stop
 * pins underneath stay clickable.
 */
.route-arrow { fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; opacity: .96; pointer-events: none; }

/* The turn the banner is describing, marked on the line. A hollow ring on purpose: the
   filled-disc-with-an-arrow idiom is reserved for a real position marker, and using it here
   would teach the shopper the wrong thing about what this app knows. */
.turn-ring circle { fill: var(--panel); stroke: var(--ink); opacity: .9; }

/* The article being asked about. A teardrop pointing at the bay - "the thing is here",
   as opposed to a disc, which reads as "someone is here". */
.focus-pin .halo { fill: var(--accent); opacity: .16; }
.focus-pin .body { fill: var(--accent); stroke: #fff; }
.focus-pin .eye { fill: #fff; }
.focus-pin .focus-label { fill: var(--ink); font-weight: 780; text-anchor: middle; paint-order: stroke; stroke: var(--floor); stroke-width: .6; }

.stop-dot { cursor: pointer; }
.stop-dot circle.pin { fill: var(--accent); stroke: #fff; transition: r .13s ease; }
.stop-dot text { fill: #fff; font-weight: 820; pointer-events: none; }
/* Emphasis by ring, not by radius. A hardcoded r is in store units and so means a different
   thing at every zoom - at walking scale it grew the highlighted pin off the screen. */
.stop-dot.active circle.pin, .stop-dot:hover circle.pin { stroke: var(--ink); }
.scalebar path { fill: none; stroke: var(--faint); stroke-width: .3; }
.scalebar text { fill: var(--faint); font-weight: 680; }

.maptools { position: absolute; right: 11px; top: 11px; display: flex; flex-direction: column; gap: 7px; }
.maptools button { background: var(--panel); border: 1px solid var(--line-strong); border-radius: 10px; width: 38px; height: 38px; display: grid; place-items: center; color: var(--muted); box-shadow: var(--shadow-sm); font-size: 16px; }
.maptools button:hover { color: var(--accent); border-color: var(--accent); }

.legend { position: absolute; left: 11px; bottom: 11px; display: flex; gap: 4px 11px; flex-wrap: wrap; max-width: calc(100% - 76px);
  background: color-mix(in srgb, var(--panel) 93%, transparent); border: 1px solid var(--line); border-radius: 11px;
  padding: 8px 11px; font-size: 11px; color: var(--muted); backdrop-filter: blur(8px); }
.legend button { display: flex; align-items: center; gap: 5px; font-size: 11px; color: inherit; }
.legend button:hover { color: var(--ink); }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

.maphint { position: absolute; left: 50%; top: 11px; transform: translateX(-50%); background: color-mix(in srgb, var(--panel) 93%, transparent);
  border: 1px solid var(--line); border-radius: 99px; padding: 6px 13px; font-size: 12px; color: var(--muted); backdrop-filter: blur(8px); box-shadow: var(--shadow-sm); }

/* ------------------------------------------------------------------ tabs --- */

.tabbar {
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: var(--panel); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: var(--shadow-lg); z-index: 6;
}
.tabbar button { height: var(--tab-h); display: grid; place-items: center; gap: 3px; color: var(--faint); font-size: 10.5px; font-weight: 640; position: relative; }
.tabbar button svg { width: 21px; height: 21px; stroke-width: 1.9; }
.tabbar button.on { color: var(--accent); }
.tabbar button .badge {
  position: absolute; top: 6px; left: 50%; margin-left: 5px;
  background: var(--accent); color: var(--on-accent); border-radius: 99px;
  font-size: 10px; font-weight: 750; min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center; font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- desktop --- */

@media (min-width: 900px) {
  .app { grid-template-rows: auto minmax(0, 1fr); grid-template-columns: 1fr; }
  main { grid-template-columns: 420px 1fr; gap: 14px; padding: 14px; overflow: hidden; }

  /* On a wide screen the map is always up, and the tabs become the left column's pages. */
  .view { display: none; }
  .view.on { display: block; }
  .view.pane { grid-column: 1; border-radius: var(--r); }
  #view-map { display: block !important; grid-column: 2; padding: 0; overflow: hidden;
    border-radius: var(--r); border: 1px solid var(--line); box-shadow: var(--shadow); }
  .tabbar { grid-template-columns: repeat(4, 1fr); position: fixed; bottom: 14px; left: 14px; width: 392px;
    border: 1px solid var(--line); border-radius: 14px; }
  .view.pane { padding-bottom: calc(var(--tab-h) + 22px); }
}

/* ------------------------------------------------------------ thumbnails --- */

.thumb {
  flex: 0 0 46px; width: 46px; height: 46px; border-radius: 11px;
  background: var(--bg); border: 1px solid var(--line); object-fit: cover;
}
.stars { width: 66px; height: 12px; color: #e8a317; vertical-align: -1px; }
.ratingrow { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); }

/* ---------------------------------------------------------------- scan --- */

.tabbar.tabs-5 { grid-template-columns: repeat(5, 1fr); }
@media (min-width: 900px) { .tabbar.tabs-5 { grid-template-columns: repeat(4, 1fr); } }

.scanbox {
  position: relative; border-radius: var(--r); overflow: hidden; background: #05070c;
  aspect-ratio: 4 / 3; display: grid; place-items: center; border: 1px solid var(--line);
}
.scanbox video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scanframe {
  position: absolute; inset: 18% 12%; border: 2px solid rgba(255,255,255,.9); border-radius: 12px;
  box-shadow: 0 0 0 100vmax rgba(0,0,0,.35); pointer-events: none;
}
.scanhint {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  margin: 0; color: #fff; font-size: 12.5px; background: rgba(0,0,0,.55);
  padding: 6px 12px; border-radius: 99px; text-align: center; max-width: 90%;
}
.manualrow { display: flex; gap: 8px; }
.manualrow input {
  flex: 1; min-width: 0; height: 44px; padding: 0 12px; border-radius: 12px;
  border: 1px solid var(--line-strong); background: var(--panel);
  font-variant-numeric: tabular-nums;
}
.manualrow input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* --------------------------------------------------------- reservation --- */

.ticket {
  margin-top: 12px; background: var(--panel); border: 1px solid var(--accent);
  border-radius: var(--r); padding: 14px; box-shadow: var(--shadow);
}
.ticket .code {
  font-size: 34px; font-weight: 820; letter-spacing: .16em; text-align: center;
  color: var(--accent); font-variant-numeric: tabular-nums; padding: 6px 0 2px;
}
.ticket .ticketmeta { margin: 0 0 10px; text-align: center; font-size: 12.5px; color: var(--muted); }
.dock .btn + .btn { margin-top: 8px; }

/* ------------------------------------------------------------ you are here --- */

.herepill {
  background: var(--ok-soft); color: var(--ok); border: 1px solid currentColor;
  border-radius: 10px; padding: 7px 11px; font-size: 12.5px; font-weight: 640;
}
.herepill::before { content: "◎ "; }

#cartSaved { color: var(--ok); font-size: 12.5px; font-weight: 640; justify-content: flex-end; }
