/* Cave Field — mobile first, desktop enhanced. */

:root {
  --bg: #f5f6f8;
  --surface: #ffffff;
  --surface-2: #eef0f4;
  --border: #dce0e7;
  --border-soft: #e008;
  --text: #1a1d23;
  --text-dim: #5b6472;
  --text-faint: #8a93a2;
  --accent: #d95f30;
  --accent-ink: #ffffff;
  --accent-soft: #fdeee7;
  --blue: #2f6fbf;
  --green: #2e8b57;
  --amber: #b8860b;
  --red: #c0392b;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(16, 20, 28, .06), 0 4px 12px rgba(16, 20, 28, .06);
  --nav-h: 58px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #12151a;
    --surface: #191d24;
    --surface-2: #212630;
    --border: #2c3341;
    --text: #e6e9ef;
    --text-dim: #98a1b3;
    --text-faint: #6b7688;
    --accent: #e8734a;
    --accent-soft: #2a1a14;
    --blue: #5aa2ea;
    --green: #4bb573;
    --amber: #d9a441;
    --red: #e05d5d;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 14px rgba(0, 0, 0, .3);
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.45 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; padding: 0; }
input, select, textarea { font-size: 16px; }  /* stops iOS zooming on focus */

/* ---------------------------------------------------------------- layout -- */

#app { display: flex; flex-direction: column; min-height: 100%; }

.screen { display: none; flex-direction: column; flex: 1; }
/*
 * Screens take focus on a route change so screen-reader users land in the new
 * content. That is a positioning device, not a control, so it must never draw
 * a ring around the whole page.
 */
.screen:focus, .screen:focus-visible { outline: none; }
.screen.active { display: flex; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  padding: calc(var(--safe-t) + 10px) 14px 10px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
}
.topbar h1 { margin: 0; font-size: 19px; font-weight: 650; letter-spacing: -.02em; flex: 1; }
.topbar .sub { font-size: 12px; color: var(--text-dim); font-weight: 400; }

.content {
  flex: 1;
  padding: 12px 14px calc(var(--nav-h) + var(--safe-b) + 24px);
  -webkit-overflow-scrolling: touch;
}

/* ------------------------------------------------------------------- nav -- */

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: var(--safe-b);
}
.tabbar button {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  height: var(--nav-h);
  color: var(--text-faint);
  font-size: 11px; font-weight: 500;
}
.tabbar button.on { color: var(--accent); }
.tabbar button svg { width: 22px; height: 22px; }
/* Five tabs on a 390px screen leaves ~78px each; keep labels on one line. */
.tabbar button span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 400px) { .tabbar button { font-size: 10px; } }
.tabbar .badge {
  position: absolute; transform: translate(14px, -12px);
  background: var(--red); color: #fff;
  min-width: 17px; height: 17px; border-radius: 9px;
  font-size: 10px; font-weight: 700;
  display: grid; place-items: center; padding: 0 4px;
}

/* ----------------------------------------------------------------- cards -- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 12px;
  overflow: hidden;
}
.card-head {
  padding: 12px 14px 0;
  font-size: 12px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-faint);
}
.card-body { padding: 14px; }

.section-title {
  font-size: 12px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-faint);
  margin: 18px 2px 8px;
}

/* ----------------------------------------------------------------- lists -- */

.list { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  width: 100%; text-align: left;
  min-height: 60px;
}
.row:last-child { border-bottom: none; }
.row:active { background: var(--surface-2); }
.row .grow { flex: 1; min-width: 0; }
.row .title { font-weight: 550; line-height: 1.3; }
.row .meta { font-size: 13px; color: var(--text-dim); margin-top: 2px; }
.row .meta.truncate, .row .title.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row .chev { color: var(--text-faint); flex-shrink: 0; }

.avatar {
  width: 40px; height: 40px; border-radius: 11px;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent);
  font-weight: 700; font-size: 14px; flex-shrink: 0;
  border: 1px solid var(--border);
}

/* ----------------------------------------------------------------- chips -- */

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; font-weight: 550; white-space: nowrap;
}
.chip.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.chip .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chip-scroll {
  display: flex; gap: 6px; overflow-x: auto; padding: 2px 14px 10px;
  margin: 0 -14px; scrollbar-width: none;
}
.chip-scroll::-webkit-scrollbar { display: none; }

.pill {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
}
.pill.gold   { background: #f6e6bf; color: #6b5310; }
.pill.silver { background: #e3e6ea; color: #4a5160; }
.pill.bronze { background: #f0ddd0; color: #7a4a2a; }
.pill.iron   { background: #dfe3e8; color: #4a5464; }
.pill.website{ background: #dbe8f7; color: #23557f; }
.pill.warn   { background: #fbe3c9; color: #7a4a10; }
.pill.due    { background: #f8d7d3; color: #94271b; }
@media (prefers-color-scheme: dark) {
  .pill.gold   { background: #4a3c14; color: #f0d78a; }
  .pill.silver { background: #333a45; color: #cdd4de; }
  .pill.bronze { background: #4a3323; color: #e8b58a; }
  .pill.iron   { background: #333a45; color: #b3bcc8; }
  .pill.website{ background: #1e3a54; color: #9ccbf0; }
  .pill.warn   { background: #4a3616; color: #e8be7a; }
  .pill.due    { background: #4d1f1b; color: #f0a49c; }
}

/* --------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; padding: 0 16px;
  border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border);
  font-weight: 550; font-size: 15px;
  /* Some buttons are anchors (mailto:, maps); keep them looking like buttons. */
  color: var(--text); text-decoration: none; cursor: pointer;
}
.btn:active { transform: scale(.985); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn-danger { color: var(--red); }
.btn-block { width: 100%; }
.btn-sm { min-height: 36px; font-size: 14px; padding: 0 12px; }
.btn:disabled { opacity: .45; }

.action-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ---------------------------------------------------------------- search -- */

.search {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0 12px;
  min-height: 44px;
}
.search input { flex: 1; background: none; border: none; outline: none; min-width: 0; }

/*
 * Keyboard focus.
 *
 * There was none outside form fields, so anyone navigating by keyboard had no
 * idea where they were — the manager screens are used at a desk, which is
 * exactly where that happens. `:focus-visible` rather than `:focus`, so it
 * appears for keyboard users and never on a tap: the phone experience is
 * unchanged.
 */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.row:focus-visible, .tabbar button:focus-visible { outline-offset: -3px; }
.search svg { color: var(--text-faint); flex-shrink: 0; }

/* ----------------------------------------------------------------- forms -- */

.field { margin-bottom: 14px; }
.field label {
  display: block; margin-bottom: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-faint);
}
.field input, .field select, .field textarea {
  width: 100%; padding: 11px 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); outline: none;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.field textarea { min-height: 90px; resize: vertical; line-height: 1.5; }
.field .hint { font-size: 12px; color: var(--text-faint); margin-top: 5px; }

.opt-grid { display: flex; flex-wrap: wrap; gap: 7px; }
.opt-grid button {
  padding: 9px 13px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  font-size: 14px; font-weight: 500;
}
.opt-grid button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.switch-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--border);
}
/* A switch row is often a <label> sitting inside a .field — the SKU pickers
   are built that way. Without this the field's own label styling wins on
   specificity and renders the row uppercase, bold and stacked, with the
   checkbox dropped below the text. */
.field label.switch-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 0;
  font-size: 15px; font-weight: 400; letter-spacing: normal;
  text-transform: none; color: var(--text);
}
.field label.switch-row small { color: var(--text-faint); }
.switch-row:last-child { border-bottom: none; }
.switch-row .grow { flex: 1; }
.switch-row .grow small { display: block; color: var(--text-faint); font-size: 13px; }
.switch-row input[type=checkbox] { width: 22px; height: 22px; accent-color: var(--accent); }

/* ----------------------------------------------------------------- sheet -- */

.scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(12, 16, 22, .45);
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
.scrim.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  max-height: 92vh;
  background: var(--surface);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -8px 40px rgba(0, 0, 0, .28);
  transform: translateY(100%);
  transition: transform .24s cubic-bezier(.32, .72, 0, 1);
  display: flex; flex-direction: column;
}
.sheet.open { transform: translateY(0); }
.sheet-grip { width: 38px; height: 4px; border-radius: 2px; background: var(--border); margin: 8px auto 0; flex-shrink: 0; }
.sheet-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.sheet-head h2 { margin: 0; font-size: 17px; font-weight: 650; flex: 1; }
.sheet-body { padding: 16px; overflow-y: auto; flex: 1; -webkit-overflow-scrolling: touch; }
.sheet-foot {
  padding: 12px 16px calc(12px + var(--safe-b));
  border-top: 1px solid var(--border);
  display: flex; gap: 10px;
}
.sheet-foot .btn { flex: 1; }

/* ---------------------------------------------------------------- toasts -- */

#toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--nav-h) + var(--safe-b) + 16px);
  z-index: 60; display: flex; flex-direction: column; gap: 8px;
  align-items: center; pointer-events: none; width: max-content; max-width: 92vw;
}
.toast {
  background: #1f2530; color: #f0f2f6;
  padding: 11px 16px; border-radius: 999px;
  font-size: 14px; font-weight: 500;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .3);
  animation: rise .2s ease;
}
.toast.err { background: var(--red); }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }

/* ----------------------------------------------------------------- misc  -- */

.empty { text-align: center; padding: 48px 24px; color: var(--text-faint); }
.empty h3 { margin: 0 0 6px; color: var(--text-dim); font-size: 16px; }
.empty p { margin: 0 0 16px; font-size: 14px; line-height: 1.55; }

/*
 * Fits whatever it is given rather than assuming three.
 * Three across stays three across; four fits on a 390px screen; five would
 * wrap badly, so no screen asks for five.
 */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr)); gap: 10px; }
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 10px; text-align: center;
}
.stat .v { font-size: 22px; font-weight: 700; line-height: 1.1; }
.stat .k { font-size: 11px; color: var(--text-faint); margin-top: 3px; text-transform: uppercase; letter-spacing: .04em; }

.offline-bar {
  display: none; background: var(--amber); color: #fff;
  padding: 6px 14px; font-size: 13px; font-weight: 550; text-align: center;
}
body.offline .offline-bar { display: block; }

.timeline-item { display: flex; gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.timeline-item:last-child { border-bottom: none; }
.timeline-icon {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text-dim);
}
.timeline-icon.visit { background: var(--accent-soft); color: var(--accent); }
.timeline-item .when { font-size: 12px; color: var(--text-faint); }
.timeline-item .note { font-size: 14px; margin-top: 4px; color: var(--text-dim); white-space: pre-wrap; }

.detail-grid { display: grid; grid-template-columns: 40% 1fr; }
.detail-grid dt, .detail-grid dd {
  padding: 9px 14px; margin: 0; font-size: 14px;
  border-bottom: 1px solid var(--border);
}
.detail-grid dt { color: var(--text-faint); }
.detail-grid dd { word-break: break-word; }
.detail-grid dt:last-of-type, .detail-grid dd:last-of-type { border-bottom: none; }

.tabs { display: flex; gap: 4px; padding: 0 14px; background: var(--surface); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 10; }
.tabs button {
  padding: 12px 4px; font-size: 15px; font-weight: 550; color: var(--text-faint);
  border-bottom: 2px solid transparent; flex: 1;
}
.tabs button.on { color: var(--accent); border-bottom-color: var(--accent); }

/* The map fills what is left of the viewport rather than scrolling — stopping
   above the tab bar, which is fixed, or the map's own controls sit under it.

   `dvh`, not `vh`: on a phone 100vh is the viewport with the browser's address
   bar hidden, which is taller than what you can actually see, so a vh-based
   height still ran the map off the bottom of the screen. `dvh` tracks the
   space really available. The vh line above it is the fallback for anything
   too old to know what dvh means. */
#screen-map.active {
  display: flex; flex-direction: column;
  /* `.screen` sets flex: 1, which grows the screen to fill its parent and
     overrides any height. The map is the one screen that must be exactly as
     tall as the space above the tab bar, so it opts out of growing. */
  flex: none;
  height: calc(100vh - var(--nav-h) - var(--safe-b));
  height: calc(100dvh - var(--nav-h) - var(--safe-b));
}
#screen-map .topbar { flex-shrink: 0; }
@media (min-width: 860px) { #screen-map.active { height: 100%; } }

.hidden { display: none !important; }
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2.5px solid var(--border); border-top-color: var(--accent);
  animation: spin .7s linear infinite; margin: 24px auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------- desktop  -- */

@media (min-width: 860px) {
  :root { --nav-h: 0px; }

  #app { flex-direction: row; height: 100vh; }

  .tabbar {
    position: static; flex-direction: column; width: 208px;
    border-top: none; border-right: 1px solid var(--border);
    padding: 14px 10px; gap: 4px; flex-shrink: 0;
  }
  .tabbar button {
    flex: none; flex-direction: row; justify-content: flex-start;
    height: 44px; gap: 12px; padding: 0 12px;
    border-radius: var(--radius-sm); font-size: 15px;
  }
  .tabbar button.on { background: var(--accent-soft); }
  .tabbar .badge { position: static; transform: none; margin-left: auto; }

  .screen { overflow: hidden; }
  .screen.active { display: flex; }
  .content { overflow-y: auto; padding: 18px 24px 40px; }
  .topbar { padding: 16px 24px; }

  .content-inner { max-width: 940px; margin: 0 auto; }

  .sheet {
    left: 50%; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -46%) scale(.98);
    width: 560px; max-height: 84vh;
    border-radius: 16px; opacity: 0;
    transition: opacity .18s, transform .18s;
  }
  .sheet.open { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .sheet-grip { display: none; }
  .sheet-foot { padding-bottom: 12px; }

  #toasts { bottom: 24px; }

  .stat-row { grid-template-columns: repeat(4, 1fr); }
  .row { min-height: 56px; }
}
