/* ============================================================
   POKEMAP — Pokémon Card Map (Unofficial Fan Service)
   Design Tokens: Navy/Charcoal + Electric Blue + Holo Cyan
   ============================================================ */

:root {
  /* Surface */
  --bg-base: #0F172A;
  --bg-elev-1: #111827;
  --bg-elev-2: #1E293B;
  --surface: #FFFFFF;
  --surface-soft: #F8FAFC;
  --surface-mid: #E2E8F0;

  /* Text */
  --text-strong: #0F172A;
  --text-on-dark: #F8FAFC;
  --text-muted: #64748B;
  --text-subtle: #94A3B8;

  /* Brand */
  --brand: #2563EB;
  --brand-hover: #1D4ED8;
  --brand-soft: #DBEAFE;
  --holo: #06B6D4;
  --holo-soft: #CFFAFE;
  --accent-yellow: #FACC15;

  /* Stock states */
  --st-ample: #22C55E;
  --st-normal: #2563EB;
  --st-low: #F97316;
  --st-soldout: #94A3B8;
  --st-incoming: #06B6D4;
  --st-preorder: #FACC15;

  /* Energy / danger */
  --danger: #EF4444;
  --danger-soft: #FEE2E2;

  /* Borders & shadows */
  --border: rgba(15, 23, 42, 0.08);
  --border-strong: rgba(15, 23, 42, 0.16);
  --border-dark: rgba(248, 250, 252, 0.08);
  --shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.04);
  --shadow-2: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
  --shadow-3: 0 12px 32px rgba(15, 23, 42, 0.12);
  --shadow-overlay: 0 -8px 24px rgba(15, 23, 42, 0.08);

  /* Radii */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-pill: 999px;

  /* Spacing */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-12: 48px;

  /* Type */
  --f-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  /* Numeric badges/counts/prices used to render in JetBrains Mono. Per spec
     the entire app should be Pretendard — keep the --f-mono token (it's
     referenced widely) but point it at the same Pretendard chain so legacy
     call sites automatically follow. tabular-nums feature still applied via
     `.mono` class for digit alignment where it matters. */
  --f-mono: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* Layout */
  --bottomnav-h: 64px;
  --header-h: 56px;
  --side-panel-w: 420px;
  --side-panel-w-xl: 480px;

  /* Z layers */
  --z-toast: 80;
  --z-modal: 70;
  --z-sheet: 60;
  --z-nav: 50;
  --z-header: 40;
  --z-marker: 20;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--f-sans);
  /* Pretendard supports tabular numerals — opt in globally so badge/count
     digits stay column-aligned even though we no longer use a mono font. */
  font-feature-settings: "tnum" 1, "ss03" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--text-strong);
  background: var(--surface-soft);
  line-height: 1.5;
  font-size: 16px;
}
input, button, select, textarea {
  font-family: inherit;
  font-feature-settings: inherit;
}

body {
  min-height: 100vh;
  overflow-x: hidden;
}

button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); }

img { max-width: 100%; display: block; }

/* ===== Typography ===== */

h1, h2, h3, h4 { margin: 0; line-height: 1.25; letter-spacing: -0.01em; color: var(--text-strong); }
h1 { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; }
h2 { font-size: 22px; font-weight: 700; }
h3 { font-size: 17px; font-weight: 600; }
h4 { font-size: 15px; font-weight: 600; }
p { margin: 0; }

.mono { font-family: var(--f-mono); font-feature-settings: "tnum" 1; }
.muted { color: var(--text-muted); }
.subtle { color: var(--text-subtle); }

/* ===== Buttons ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--r-md);
  font-size: 14px;
  font-weight: 600;
  border: 1px solid transparent;
  background: var(--surface-mid);
  color: var(--text-strong);
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease, transform 120ms ease;
  min-height: 40px;
  white-space: nowrap;
}
.btn:hover { background: #CBD5E1; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.btn-primary {
  background: var(--brand);
  color: #fff;
}
.btn-primary:hover { background: var(--brand-hover); }

.btn-ghost {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-strong);
}
.btn-ghost:hover { background: var(--surface-soft); }

.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #DC2626; }

.btn-sm { padding: 6px 12px; min-height: 32px; font-size: 13px; }
.btn-lg { padding: 14px 22px; min-height: 48px; font-size: 15px; }
.btn-icon {
  width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-strong);
}
.btn-icon:hover { background: var(--surface-soft); }

.btn-block { width: 100%; }

/* ===== Form ===== */

.input,
.select,
.textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-strong);
  font-size: 14px;
  min-height: 40px;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
}
.textarea { min-height: 96px; resize: vertical; }
.label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.field { margin-bottom: 14px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* ===== Badges ===== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--surface-soft);
  color: var(--text-muted);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.badge.ample    { color: #15803D; background: #DCFCE7; border-color: #BBF7D0; }
.badge.normal   { color: #1D4ED8; background: var(--brand-soft); border-color: #BFDBFE; }
.badge.low      { color: #C2410C; background: #FFEDD5; border-color: #FED7AA; }
.badge.sold_out { color: #475569; background: #F1F5F9; border-color: #E2E8F0; }
.badge.incoming { color: #0E7490; background: var(--holo-soft); border-color: #A5F3FC; }
.badge.preorder { color: #92400E; background: #FEF3C7; border-color: #FDE68A; }
.badge.holo {
  color: #fff;
  background: linear-gradient(90deg, #06B6D4 0%, #2563EB 50%, #06B6D4 100%);
  border-color: transparent;
}

.badge.lang-ko { color: #1E40AF; background: var(--brand-soft); border-color: #BFDBFE; }
.badge.lang-jp { color: #B91C1C; background: var(--danger-soft); border-color: #FECACA; }
.badge.lang-en { color: #334155; background: var(--surface-mid); border-color: #CBD5E1; }

.badge.partner { color: #fff; background: var(--brand); border-color: transparent; }
.badge.hidden  { color: #475569; background: #E2E8F0; border-color: #CBD5E1; }

/* Provider badges */
.badge.provider-google { color: #1F2937; background: #fff; border-color: #E5E7EB; }
.badge.provider-kakao  { color: #3D2E00; background: #FEE500; border-color: #F2D200; }
.badge.provider-naver  { color: #fff; background: #03C75A; border-color: transparent; }
.badge.provider-email  { color: #475569; background: #F1F5F9; border-color: #CBD5E1; }

/* Status (applications) */
.badge.status-none      { color: #475569; background: #F1F5F9; }
.badge.status-pending   { color: #92400E; background: #FEF3C7; border-color: #FDE68A; }
.badge.status-review    { color: #0E7490; background: var(--holo-soft); border-color: #A5F3FC; }
.badge.status-approved  { color: #15803D; background: #DCFCE7; border-color: #BBF7D0; }
.badge.status-rejected  { color: #B91C1C; background: var(--danger-soft); border-color: #FECACA; }

/* ===== Cards / Panels ===== */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.card-pad { padding: 18px; }

.divider { height: 1px; background: var(--border); border: 0; margin: 12px 0; }

.toast-stack {
  position: fixed;
  bottom: calc(var(--bottomnav-h) + 12px);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: 92vw;
}
.toast {
  background: var(--bg-elev-2);
  color: var(--text-on-dark);
  padding: 10px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow-3);
  pointer-events: auto;
  animation: toast-in 220ms ease both;
  border: 1px solid rgba(255,255,255,0.06);
}
.toast.error { background: #7F1D1D; }
.toast.holo  { background: linear-gradient(90deg, #06B6D4 0%, #2563EB 100%); }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== App Shell ===== */

.app-shell {
  min-height: 100vh;
  padding-bottom: var(--bottomnav-h);
  background: var(--surface-soft);
}

.page-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: rgba(255,255,255,0.92);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--border);
}
.page-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-h);
  padding: 0 16px;
  max-width: 1440px;
  margin: 0 auto;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.01em;
  color: var(--text-strong);
}
.brand-mark {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: linear-gradient(135deg, #2563EB 0%, #06B6D4 100%);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.25);
}
.brand-name small { color: var(--text-muted); font-weight: 500; font-size: 11px; display: block; letter-spacing: 0.06em; text-transform: uppercase; }

.header-actions { display: flex; gap: 8px; align-items: center; }

/* ===== Bottom nav ===== */

.bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-nav);
  height: var(--bottomnav-h);
  background: rgba(255,255,255,0.96);
  backdrop-filter: saturate(160%) blur(8px);
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
.bottom-nav button, .bottom-nav a {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
  position: relative;
  transition: color 160ms ease;
}
.bottom-nav button.active, .bottom-nav a.active { color: var(--brand); }
.bottom-nav button.active::before,
.bottom-nav a.active::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  width: 24px; height: 2px;
  background: var(--brand);
  border-radius: 0 0 2px 2px;
  transform: translateX(-50%);
}
.bottom-nav svg { width: 22px; height: 22px; }

/* ===== Map page ===== */

/* v16 layout tokens — single source of truth for the panel widths.
   #map-canvas / .search-bar / .map-fab use .map-shell[data-layout=...] to pick
   the correct left offset so no panel ever overlaps the map. */
.map-shell {
  --rail-w: 80px;
  --list-w: 380px;
  /* detail panel matches list width — same panel size for parity. */
  --detail-w: var(--list-w);
  position: relative;
  height: calc(100vh - var(--bottomnav-h));
  min-height: 320px;
  background: #E5E7EB; /* light neutral so failed tiles don't reveal navy */
  overflow: hidden;
}
@media (min-width: 1440px) {
  .map-shell { --list-w: 420px; }
}
@media (max-width: 1023px) {
  .map-shell { --list-w: 320px; }
}
@media (max-width: 600px) {
  .map-shell { --rail-w: 56px; }
}

/* v17 — search shell + chip row positioned independently.
   - search-shell-anchor: rides INSIDE the open list sidebar, centered horizontally;
     when no sidebar is open, sits at the top-left of the map area with a fixed width.
   - chip-row-anchor: ALWAYS over map-only area. left offset follows data-layout. */
.search-shell-anchor {
  position: absolute;
  top: 12px;
  left: calc(var(--rail-w) + 12px);
  width: 400px;
  z-index: 28;        /* above sidebar(24) so the field rides on top of the panel */
  transition: left 240ms ease-out, width 240ms ease-out;
}
.map-shell[data-layout="rail-list"] .search-shell-anchor,
.map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
  left: calc(var(--rail-w) + 12px);
  width: calc(var(--list-w) - 24px);
}

.chip-row-anchor {
  position: absolute;
  top: 12px;
  left: calc(var(--rail-w) + 12px + 400px + 12px); /* default: right after search shell */
  right: 16px;
  z-index: 28;
  transition: left 240ms ease-out;
  pointer-events: none;  /* the inner row picks up clicks; container ignores */
}
.chip-row-anchor > .chip-row { pointer-events: auto; }
.map-shell[data-layout="rail-list"] .chip-row-anchor {
  left: calc(var(--rail-w) + var(--list-w) + 12px);
}
.map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
  /* floating detail right edge = rail+list+12 (gap) +detail. Add 22 for toggle + 12 gap. */
  left: calc(var(--rail-w) + var(--list-w) + var(--detail-w) + 46px);
}
@media (max-width: 600px) {
  .search-shell-anchor,
  .map-shell[data-layout="rail-list"] .search-shell-anchor,
  .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
    left: calc(var(--rail-w) + 8px);
    width: calc(100vw - var(--rail-w) - 16px);
  }
  .chip-row-anchor,
  .map-shell[data-layout="rail-list"] .chip-row-anchor,
  .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
    /* on small screens, chips wrap below the search */
    top: 60px;
    left: calc(var(--rail-w) + 8px);
    right: 8px;
  }
}

.search-shell {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 6px 10px;
  box-shadow: var(--shadow-2);
  position: relative;
  overflow: hidden;
}
.search-shell::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent 0%, var(--holo) 50%, transparent 100%);
  opacity: 0;
  transition: opacity 200ms ease;
}
.search-shell:focus-within::before { opacity: 1; }

.search-shell .search-icon { color: var(--text-muted); }
.search-shell input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: 15px;
  color: var(--text-strong);
  padding: 8px 4px;
  min-width: 0;
}
.search-shell input::placeholder { color: var(--text-subtle); }
.search-clear {
  background: transparent; border: 0; padding: 4px;
  color: var(--text-muted); border-radius: 50%;
  display: none;
}
.search-shell.has-value .search-clear { display: inline-flex; }

.chip-row {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.chip-row::-webkit-scrollbar { display: none; }
.chip {
  flex-shrink: 0;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,0.92);
  border: 1px solid var(--border);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-strong);
  box-shadow: var(--shadow-1);
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.chip:hover { background: var(--brand-soft); color: var(--brand); border-color: #BFDBFE; }
.chip.active { background: var(--brand); color: #fff; border-color: var(--brand); }

/* Desktop vs mobile chip rows live in the same anchor; only one is visible. */
.chip-row--mobile { display: none; }
@media (max-width: 768px) {
  .chip-row--desktop { display: none; }
  /* Mobile chips wrap onto multiple lines instead of overflowing horizontally
     so long featured-pack labels (e.g. "MEGA 확장팩 「니힐제로」") aren't
     clipped at the right edge of the viewport. The base .chip-row uses
     overflow-x:auto for desktop horizontal scroll — override here. */
  .chip-row--mobile {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    overflow: visible;
    width: 100%;
    max-width: 100%;
    padding-bottom: 2px;
  }
  /* Each chip stays one-line; chips themselves wrap onto next row if needed. */
  .chip-row--mobile .chip {
    white-space: nowrap;
    max-width: 100%;
  }
}

/* Type toggle chips (모바일 전용) — distinguish from search-keyword chips.
   Inactive: white/ghost. Active: brand-fill (matches generic .chip.active). */
.chip--toggle {
  background: #fff;
  color: var(--text-strong);
  border: 1px solid var(--border);
  font-weight: 600;
}
.chip--toggle.active {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
  box-shadow: 0 1px 4px rgba(37,99,235,0.25);
}
.chip--toggle:not(.active):hover {
  background: var(--surface-soft);
  color: var(--text-strong);
  border-color: var(--border);
}
/* Featured-pack chips (mobile): visually distinct with a subtle accent so
   testers can tell toggles apart from "click to search" chips. */
.chip--featured {
  font-weight: 500;
  background: rgba(37,99,235,0.06);
  border-color: rgba(37,99,235,0.20);
}
.chip--featured:hover { background: var(--brand-soft); color: var(--brand); border-color: var(--brand); }

#map-canvas {
  position: absolute;
  /* left is set per layout; right/top/bottom anchor to shell. */
  left: var(--rail-w);
  top: 0; right: 0; bottom: 0;
  z-index: 1;
  background: #E5E7EB;
  min-height: 320px;
  transition: left 240ms ease-out;
}
.map-shell[data-layout="rail-list"] #map-canvas,
.map-shell[data-layout="rail-list-detail"] #map-canvas {
  /* Detail is a floating overlay (see .map-detail) so the map keeps the same
     left offset whether detail is open or not — the panel sits ON TOP of the
     map, never splitting it. */
  left: calc(var(--rail-w) + var(--list-w));
}
@media (max-width: 1023px) {
  /* tablet/mobile: panels float over the map (no canvas push), keep inset */
  #map-canvas,
  .map-shell[data-layout="rail-list"] #map-canvas,
  .map-shell[data-layout="rail-list-detail"] #map-canvas {
    left: 0;
  }
}

#map-canvas > div {
  width: 100% !important;
  height: 100% !important;
}

.map-fab {
  position: absolute;
  right: 14px;
  bottom: 18px;
  z-index: 30;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-3);
  display: flex; align-items: center; justify-content: center;
  color: var(--brand);
}
.map-fab:hover { background: var(--brand); color: #fff; }

/* ===== Custom zoom column (+/-) — desktop right-bottom, above locate FAB.
   Replaces Naver SDK's built-in zoomControl, which silently dropped its
   position option (Position.RIGHT_BOTTOM) on some SDK builds and fell back
   to TOP_LEFT. This DOM-owned version is positioned deterministically. */
.map-zoom {
  position: absolute;
  right: 14px;
  bottom: 132px;          /* sits above locate FAB (bottom 72px + 48px + ~12px gap) */
  z-index: 30;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.map-zoom-btn {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}
.map-zoom-btn + .map-zoom-btn { border-top: 1px solid var(--border); }
.map-zoom-btn:hover  { background: rgba(15, 23, 42, 0.05); }
.map-zoom-btn:active { background: rgba(15, 23, 42, 0.1); }
.map-zoom-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Custom scale bar — Naver-style line + tick + distance label.
   Width (--scale-px) is set inline by JS to match a "nice" distance at the
   current zoom (50m / 100m / 200m / 500m / 1km / …). */
.map-scale {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  pointer-events: none;
  user-select: none;
}
.map-scale-label {
  font-size: 11px;
  font-weight: 600;
  color: #0F172A;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.9),
    0 0 4px rgba(255, 255, 255, 0.7);
  letter-spacing: 0.01em;
  line-height: 1;
}
.map-scale-bar {
  display: block;
  width: var(--scale-px, 100px);
  height: 6px;
  /* U-shape: left tick + right tick + bottom line — Naver-style scale. */
  border-left:   2px solid #0F172A;
  border-right:  2px solid #0F172A;
  border-bottom: 2px solid #0F172A;
  background: rgba(255, 255, 255, 0.55);
  transition: width 180ms ease-out;
}

/* Map provider attribution — sits inside the actual map viewport (right of
   the rail on desktop, above the cat-bar on mobile). Subtle text-only — no
   pill, no green status dot, no shadow. Should NOT look interactive. */
.map-status {
  position: absolute;
  /* Desktop default: inside the map area, just right of the rail. Use the same
     --rail-w token the rail itself reads so the offset stays in sync. */
  bottom: 10px;
  left: calc(var(--rail-w, 80px) + 12px);
  z-index: 10;          /* below rail (25) + cat bar (40) + sheets (30/31) */
  background: transparent;
  color: rgba(100, 116, 139, 0.55);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  user-select: none;
}
/* Hide the legacy status dot — not needed in the subtle attribution form. */
.map-status .dot { display: none; }
.map-status.demo,
.map-status.demo-fail { color: rgba(120, 53, 15, 0.7); }

/* Mock map */
.mock-map {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 20% 25%, rgba(37,99,235,0.18) 0%, transparent 40%),
    radial-gradient(circle at 80% 70%, rgba(6,182,212,0.16) 0%, transparent 45%),
    linear-gradient(180deg, #0F172A 0%, #1E293B 100%);
  overflow: hidden;
}
.mock-map .grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(148,163,184,0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148,163,184,0.06) 1px, transparent 1px);
  background-size: 48px 48px;
}
.mock-map .roads {
  position: absolute; inset: 0;
  pointer-events: none;
}

.mock-marker {
  position: absolute;
  transform: translate(-50%, -100%);
  cursor: pointer;
  z-index: var(--z-marker);
  transition: opacity 180ms ease, transform 180ms ease, filter 180ms ease;
}
.mock-marker:hover { transform: translate(-50%, -103%) scale(1.06); }
.mock-marker.is-dim { opacity: 0.32; filter: saturate(0.4); }
.mock-marker.is-highlight { filter: drop-shadow(0 0 8px rgba(6,182,212,0.7)) drop-shadow(0 0 18px rgba(37,99,235,0.45)); }
.mock-marker.is-active { transform: translate(-50%, -100%); }

/* Naver-rendered marker.
   IMPORTANT: NO `transform: translate(-50%, -100%)` here. Naver's overlay
   already positions the icon so its anchor pixel lands on the lat/lng (we set
   the anchor in NaverMapAdapter via icon.anchor). A CSS translate would shift
   the icon by a CONSTANT pixel offset on top of that, which translates to a
   zoom-DEPENDENT geographic offset (e.g. 56px = ~1km at zoom 13 vs ~30m at
   zoom 18) — making markers appear to "drift" as the user zooms. */
.naver-pack-marker {
  width: 44px;
  height: 56px;
  display: block;
  transition: opacity 180ms ease, filter 180ms ease;
}
.naver-pack-marker.is-dim { opacity: 0.32; filter: saturate(0.4); }
.naver-pack-marker.is-highlight { filter: drop-shadow(0 0 8px rgba(6,182,212,0.7)) drop-shadow(0 0 18px rgba(37,99,235,0.45)); }
/* active = visual emphasis only — anchor / position unchanged. */
.naver-pack-marker.is-active { /* no transform; only z-index + halo via .is-active svg */ }

.user-location-marker,
.naver-user-marker {
  position: absolute;
  width: 24px;
  height: 24px;
  transform: translate(-50%, -50%);
  border-radius: 999px;
  background: rgba(37, 99, 235, 0.18);
  border: 1px solid rgba(37, 99, 235, 0.3);
  box-shadow: 0 0 0 8px rgba(37, 99, 235, 0.12);
  pointer-events: none;
}
.naver-user-marker {
  position: relative;
  transform: none;
}
.user-location-marker::before,
.naver-user-marker span {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: inherit;
  background: var(--brand);
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.25);
}

/* Result panel - mobile bottom sheet */

.result-panel {
  position: fixed;
  left: 0; right: 0;
  bottom: var(--bottomnav-h);
  z-index: var(--z-sheet);
  background: var(--surface);
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  box-shadow: var(--shadow-overlay);
  max-height: 75vh;
  display: flex;
  flex-direction: column;
  transform: translateY(calc(100% - 96px));
  transition: transform 280ms cubic-bezier(.2,.7,.2,1);
}
.result-panel.expanded { transform: translateY(0); }
.result-panel.collapsed { transform: translateY(calc(100% - 56px)); }

.sheet-handle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0 4px;
  cursor: grab;
}
.sheet-handle::before {
  content: "";
  width: 36px; height: 4px;
  border-radius: 2px;
  background: var(--surface-mid);
}

.sheet-tabs {
  display: flex;
  gap: 4px;
  padding: 4px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 1;
}
.sheet-tab {
  flex: 1;
  padding: 10px 12px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  position: relative;
}
.sheet-tab.active { color: var(--brand); background: var(--brand-soft); }
.sheet-tab .count { font-family: var(--f-mono); font-size: 11px; margin-left: 4px; opacity: 0.8; }

.sheet-body {
  overflow-y: auto;
  padding: 8px 12px 24px;
  flex: 1;
}

/* Result cards */

.store-card {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 12px;
  width: 100%;
  padding: 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  margin-bottom: 8px;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.store-card:hover { border-color: var(--brand); box-shadow: var(--shadow-2); }
.store-card.is-active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }

.store-card .thumb {
  width: 56px; height: 56px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--bg-base), var(--bg-elev-2));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  position: relative;
}
.store-card .thumb svg { width: 32px; height: 32px; color: var(--holo); }
.store-card .body { min-width: 0; display: grid; gap: 6px; }
.store-card .row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.store-card .title-row { justify-content: space-between; gap: 8px; }
.store-card .name {
  font-size: 14.5px; font-weight: 700; color: var(--text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1; min-width: 0; line-height: 1.3; margin: 0;
}
.store-card .rating { font-size: 12px; color: var(--text-strong); white-space: nowrap; flex-shrink: 0; display: inline-flex; align-items: baseline; gap: 2px; }
.store-card .rating .muted { color: var(--text-muted); margin-left: 4px; }
.store-card .addr { font-size: 12.5px; color: var(--text-muted); }
.store-card .addr .muted { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.store-card .badges { flex-wrap: nowrap; overflow: hidden; }
.store-card .badges .badge { white-space: nowrap; flex-shrink: 0; }
.store-card .meta { justify-content: space-between; font-size: 12px; color: var(--text-muted); }
.store-card .meta .holo.today {
  background: linear-gradient(120deg, #06B6D4, #2563EB, #06B6D4);
  background-size: 200% 200%;
  animation: holo-shift 2.4s ease infinite;
  color: #fff;
  border: 0;
}
@keyframes holo-shift {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

.product-card {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.product-card:hover { border-color: var(--brand); box-shadow: var(--shadow-1); }
.product-card .icon {
  width: 44px; height: 44px;
  border-radius: var(--r-sm);
  background: var(--surface-soft);
  display: flex; align-items: center; justify-content: center;
  color: var(--holo);
}
.product-card .info h4 { font-size: 14px; margin-bottom: 2px; }
.product-card .info .meta { font-size: 12px; color: var(--text-muted); }
.product-card .info .badges { display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap; }
.product-card .right { text-align: right; font-size: 11px; color: var(--text-muted); display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.product-card .right .count { font-family: var(--f-mono); font-size: 13px; font-weight: 600; color: var(--brand); }

.empty {
  text-align: center;
  padding: 36px 16px;
  color: var(--text-muted);
  font-size: 14px;
}
.empty svg { color: var(--text-subtle); margin-bottom: 12px; }

.section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--text-muted);
  padding: 12px 4px 6px;
}
.section-title .count { font-family: var(--f-mono); }

/* Filter drawer */
.filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-strong);
  box-shadow: var(--shadow-1);
}
.filter-toggle.has-active { background: var(--brand); color: #fff; border-color: var(--brand); }
.filter-toggle .pill-count {
  background: rgba(255,255,255,0.32);
  font-family: var(--f-mono);
  font-size: 11px;
  padding: 0 6px;
  border-radius: 999px;
  min-width: 18px;
  text-align: center;
}

.filter-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(2px);
  display: none;
  align-items: flex-end;
  justify-content: center;
}
.filter-modal.open { display: flex; }
.filter-modal-inner {
  background: var(--surface);
  width: 100%;
  max-width: 560px;
  max-height: 86vh;
  border-radius: 16px 16px 0 0;
  padding: 16px;
  overflow-y: auto;
  box-shadow: var(--shadow-3);
  animation: sheet-up 240ms ease;
}
@keyframes sheet-up { from { transform: translateY(20px); opacity: 0;} to { transform: translateY(0); opacity: 1;} }

.filter-section { padding: 12px 0; border-bottom: 1px solid var(--border); }
.filter-section:last-child { border-bottom: 0; }
.filter-section h4 { margin-bottom: 8px; font-size: 13px; }
.filter-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-pill {
  padding: 6px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  font-size: 13px;
  color: var(--text-strong);
}
.filter-pill:hover { border-color: var(--brand); color: var(--brand); }
.filter-pill.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.filter-pill[disabled] { opacity: 0.5; cursor: not-allowed; }

.filter-actions { display: flex; gap: 8px; margin-top: 12px; }

/* Store detail panel */
.detail-panel {
  position: fixed;
  inset: auto 0 var(--bottomnav-h) 0;
  z-index: var(--z-modal);
  background: var(--surface);
  max-height: 88vh;
  border-radius: 16px 16px 0 0;
  box-shadow: var(--shadow-3);
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.detail-panel.open { display: flex; animation: sheet-up 260ms ease; }

.detail-header {
  position: relative;
  padding: 16px;
  background: linear-gradient(180deg, var(--bg-base) 0%, var(--bg-elev-1) 100%);
  color: var(--text-on-dark);
}
.detail-close {
  position: absolute;
  top: 12px; right: 12px;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  color: #fff;
  border: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.detail-header h2 { color: var(--text-on-dark); font-size: 20px; margin-bottom: 4px; padding-right: 36px; }
.detail-header .meta { font-size: 13px; color: var(--text-subtle); display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.detail-header .meta .badge { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.14); color: #fff; }

.detail-body {
  overflow-y: auto;
  padding: 16px;
  background: var(--surface-soft);
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}
.summary-cell {
  padding: 10px 8px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  text-align: center;
}
.summary-cell .num { font-family: var(--f-mono); font-size: 18px; font-weight: 700; }
.summary-cell .label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.summary-cell.ample .num    { color: var(--st-ample); }
.summary-cell.low .num      { color: var(--st-low); }
.summary-cell.soldout .num  { color: var(--st-soldout); }

.detail-info { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 12px; margin-bottom: 16px; }
.detail-info .row { display: flex; gap: 8px; padding: 6px 0; font-size: 13px; align-items: flex-start; }
.detail-info .row .k { width: 72px; flex-shrink: 0; color: var(--text-muted); }
.detail-info .row .v { flex: 1; color: var(--text-strong); }

.detail-products { display: flex; flex-direction: column; gap: 8px; }
.detail-product {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.detail-product .name { font-weight: 600; font-size: 14px; }
.detail-product .meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.detail-product .badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.detail-product .right { text-align: right; }
.detail-product .stock-num { font-family: var(--f-mono); font-size: 16px; font-weight: 700; color: var(--text-strong); }
.detail-product .stock-num.zero { color: var(--st-soldout); }
.detail-product .price { font-family: var(--f-mono); font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.detail-product .small { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

details.soldout-block {
  margin-top: 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-soft);
}
details.soldout-block summary {
  padding: 10px 12px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  list-style: none;
}
details.soldout-block summary::-webkit-details-marker { display: none; }
details.soldout-block summary::after { content: "▾"; float: right; transition: transform 200ms; }
details.soldout-block[open] summary::after { transform: rotate(180deg); }
details.soldout-block .detail-products { padding: 8px 12px 12px; }

/* Nearby + FAQ in sheet */
.nearby-section { margin-bottom: 18px; }
.nearby-section .section-title svg { color: var(--brand); }

.faq-list { display: flex; flex-direction: column; gap: 6px; }
.faq-item {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-md);
}
.faq-item summary {
  cursor: pointer;
  padding: 12px;
  font-weight: 600;
  font-size: 14px;
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; float: right; font-weight: 400; color: var(--text-muted); transition: transform 200ms; }
.faq-item[open] summary::after { content: "−"; }
.faq-item .answer { padding: 0 12px 12px; font-size: 13px; color: var(--text-muted); line-height: 1.6; }

/* ===== Owner login ===== */

.center-shell {
  min-height: calc(100vh - var(--bottomnav-h));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}

.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  box-shadow: var(--shadow-2);
  border: 1px solid var(--border);
}
.login-card h1 { margin-bottom: 6px; }
.login-card p.lead { color: var(--text-muted); font-size: 14px; margin-bottom: 24px; }

.oauth-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-weight: 600;
  font-size: 14px;
  border: 1px solid transparent;
  min-height: 48px;
  position: relative;
  transition: filter 160ms ease;
}
.oauth-btn:hover { filter: brightness(0.96); }
.oauth-btn .spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  display: none;
  animation: spin 700ms linear infinite;
}
.oauth-btn.loading .spinner { display: inline-block; }
.oauth-btn.loading .icon { display: none; }
@keyframes spin { to { transform: rotate(360deg); } }

.oauth-google { background: #fff; color: #1F2937; border-color: #E5E7EB; }
.oauth-kakao  { background: #FEE500; color: #3D2E00; }
.oauth-kakao .spinner { color: #3D2E00; }
.oauth-naver  { background: #03C75A; color: #fff; }

.oauth-divider { display: flex; align-items: center; gap: 10px; color: var(--text-muted); font-size: 12px; margin: 14px 0; }
.oauth-divider::before, .oauth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.guest-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-weight: 600;
  background: var(--surface-soft);
  border: 1px dashed var(--border-strong);
  color: var(--text-strong);
  min-height: 48px;
}

.login-links { display: flex; justify-content: center; gap: 16px; margin-top: 18px; font-size: 13px; }
.login-foot { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-subtle); text-align: center; line-height: 1.6; }

/* ===== Dashboard ===== */

.dash-grid {
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px;
  display: grid;
  gap: 16px;
}

.state-switcher {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #FEF3C7;
  border: 1px dashed #FBBF24;
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-size: 12px;
  color: #92400E;
}
.state-switcher select { padding: 4px 8px; border-radius: var(--r-sm); }

.dash-banner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  padding: 14px;
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #0F172A 100%);
  color: #fff;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(6, 182, 212, 0.18);
}
.dash-banner::before {
  content: "";
  position: absolute;
  top: -2px; right: -2px; bottom: -2px; left: -2px;
  background: linear-gradient(120deg, transparent 30%, rgba(6,182,212,0.18) 50%, transparent 70%);
  pointer-events: none;
}
.dash-banner .row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.dash-banner .pill {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.16);
  padding: 6px 12px;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 600;
}
.dash-banner .pill.warn { background: rgba(249,115,22,0.18); border-color: rgba(249,115,22,0.32); }
.dash-banner .pill.danger { background: rgba(239,68,68,0.18); border-color: rgba(239,68,68,0.32); }
.dash-banner .updated-at { font-family: var(--f-mono); font-size: 11px; color: var(--text-subtle); }

.dash-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px;
}
.dash-section h2 { font-size: 16px; margin-bottom: 8px; }
.dash-section .section-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dash-section .section-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; gap: 8px; flex-wrap: wrap; }

/* Product table */
.product-table-wrap { overflow-x: auto; }
.product-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.product-table th, .product-table td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.product-table th {
  background: var(--surface-soft);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.product-table tr:hover td { background: rgba(37,99,235,0.04); }
.product-table .stock-cell { font-family: var(--f-mono); font-weight: 700; }
.product-table .actions { display: flex; gap: 4px; }
.product-table input[type=checkbox] { width: 16px; height: 16px; }

.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.qty-stepper button {
  background: var(--surface);
  border: 0;
  padding: 4px 8px;
  font-size: 14px;
  color: var(--text-strong);
  min-width: 28px;
  min-height: 30px;
}
.qty-stepper input {
  width: 48px;
  text-align: center;
  border: 0;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  padding: 4px 2px;
  font-family: var(--f-mono);
  font-size: 13px;
  outline: 0;
  min-height: 30px;
}

/* Product card list (mobile) */
.product-cards { display: none; flex-direction: column; gap: 8px; }
.product-cards .pcard {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-md);
  padding: 12px;
}
.product-cards .pcard header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.product-cards .pcard h3 { font-size: 14px; }
.product-cards .pcard .meta { font-size: 12px; color: var(--text-muted); }
.product-cards .pcard .row { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.product-cards .pcard .badges { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }

/* Modal */
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(15, 23, 42, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.modal.open { display: flex; }
.modal-card {
  width: 100%;
  max-width: 520px;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.modal-head { padding: 16px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
.modal-body { padding: 16px; overflow-y: auto; }
.modal-foot { padding: 12px 16px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }

/* Account / settings */
.account-card { display: grid; gap: 12px; }
.account-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; gap: 8px; flex-wrap: wrap; }
.account-row .lab { font-size: 13px; color: var(--text-muted); }
.account-row .val { font-size: 14px; font-weight: 500; }

.banner-guest {
  background: var(--accent-yellow);
  color: #92400E;
  padding: 10px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid #FBBF24;
}

/* Empty / state-specific cards */
.state-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  text-align: center;
  box-shadow: var(--shadow-1);
}
.state-card svg { color: var(--brand); margin-bottom: 12px; }
.state-card h2 { margin-bottom: 6px; }
.state-card p { color: var(--text-muted); margin-bottom: 16px; }
.state-card .actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* ===== Guide page ===== */

.guide-shell { max-width: 960px; margin: 0 auto; padding: 24px 16px 60px; }
.guide-hero {
  background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #2563EB 200%);
  color: #fff;
  border-radius: var(--r-lg);
  padding: 36px 24px;
  margin-bottom: 24px;
  position: relative;
  overflow: hidden;
}
.guide-hero::after {
  content: "";
  position: absolute;
  inset: -40% -20% auto auto;
  width: 320px; height: 320px;
  background: radial-gradient(circle, rgba(6,182,212,0.32) 0%, transparent 60%);
  pointer-events: none;
}
.guide-hero h1 { font-size: 32px; color: #fff; margin-bottom: 10px; max-width: 26ch; }
.guide-hero p  { color: var(--text-subtle); max-width: 50ch; font-size: 15px; }
.guide-hero .actions { margin-top: 20px; display: flex; gap: 8px; flex-wrap: wrap; }

.guide-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 24px;
}
.guide-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.guide-tile .num {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--brand-soft);
  color: var(--brand);
  font-family: var(--f-mono);
  font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.guide-tile h3 { font-size: 16px; }
.guide-tile p { font-size: 13px; color: var(--text-muted); line-height: 1.65; }

.guide-types {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 16px 0;
}
.guide-types .type-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
}
.guide-types .type-tile svg { color: var(--brand); }

.guide-section { margin-bottom: 28px; }
.guide-section h2 { font-size: 20px; margin-bottom: 10px; }
.guide-section p { color: var(--text-muted); font-size: 14px; line-height: 1.7; }
.guide-section ul { padding-left: 20px; color: var(--text-muted); font-size: 14px; line-height: 1.8; }

.cta-block {
  background: var(--bg-base);
  color: #fff;
  border-radius: var(--r-lg);
  padding: 28px 24px;
  text-align: center;
}
.cta-block h2 { color: #fff; margin-bottom: 6px; }
.cta-block p { color: var(--text-subtle); margin-bottom: 16px; }
.cta-block .actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* ===== Terms ===== */

.terms-shell {
  max-width: 760px;
  margin: 0 auto;
  padding: 28px 18px 60px;
}
.terms-shell h1 { font-size: 26px; margin-bottom: 6px; }
.terms-shell .meta { color: var(--text-muted); font-size: 13px; margin-bottom: 24px; }
.terms-shell article { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 22px; }
.terms-shell article h2 { font-size: 18px; margin-top: 24px; margin-bottom: 8px; }
.terms-shell article h2:first-child { margin-top: 0; }
.terms-shell article p, .terms-shell article li { font-size: 14px; line-height: 1.75; color: var(--text-strong); }
.terms-shell article ul { padding-left: 20px; }
.terms-shell .callout {
  background: var(--brand-soft);
  border: 1px solid #BFDBFE;
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin: 12px 0;
  font-size: 13px;
  color: #1E3A8A;
  line-height: 1.7;
}

/* ===== Admin ===== */

.admin-shell { max-width: 1280px; margin: 0 auto; padding: 16px; display: grid; gap: 16px; }
.admin-tabs { display: flex; gap: 4px; }
.admin-tab {
  padding: 8px 14px;
  border-radius: var(--r-md);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-strong);
  font-weight: 600;
  font-size: 13px;
}
.admin-tab.active { background: var(--brand); color: #fff; border-color: var(--brand); }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px;
}
.kpi .num { font-family: var(--f-mono); font-size: 22px; font-weight: 700; }
.kpi .lab { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.kpi.brand { background: linear-gradient(135deg, var(--brand) 0%, var(--holo) 200%); color: #fff; border-color: transparent; }
.kpi.brand .lab { color: rgba(255,255,255,0.8); }

/* Stock summary bar */
.stock-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; min-width: 96px; }
.stock-bar span { display: block; height: 100%; }
.stock-bar .ample { background: var(--st-ample); }
.stock-bar .normal { background: var(--st-normal); }
.stock-bar .low { background: var(--st-low); }
.stock-bar .soldout { background: var(--st-soldout); }

.application-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 14px;
  margin-bottom: 8px;
}
.application-card header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.application-card h3 { font-size: 15px; margin-bottom: 2px; }
.application-card .meta { font-size: 12px; color: var(--text-muted); }
.application-card .grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  font-size: 13px;
  margin: 8px 0;
}
.application-card .grid .k { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.application-card .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.application-card .reason { background: var(--danger-soft); padding: 8px 10px; border-radius: var(--r-sm); font-size: 12px; color: #7F1D1D; margin-top: 6px; }

/* ===== Stocks holo border on hover ===== */

.holo-border {
  position: relative;
}
.holo-border::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from 0deg, transparent 0%, var(--holo) 25%, var(--brand) 50%, var(--accent-yellow) 75%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
  animation: spin-slow 4s linear infinite;
}
.holo-border:hover::after { opacity: 1; }
@keyframes spin-slow {
  to { transform: rotate(360deg); }
}

/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===== Responsive Breakpoints ===== */

@media (min-width: 640px) {
  h1 { font-size: 32px; }
  .guide-grid { grid-template-columns: repeat(3, 1fr); }
  .guide-types { grid-template-columns: repeat(3, 1fr); }
  .kpi-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (min-width: 768px) {
  .product-cards { display: none !important; }
  .product-table-wrap { display: block; }
  .field-row { grid-template-columns: 1fr 1fr 1fr; }
}

@media (max-width: 767px) {
  .product-table-wrap { display: none; }
  .product-cards { display: flex; }
}

@media (min-width: 1024px) {
  .map-shell {
    height: 100vh;
    padding-bottom: 0;
  }
  .app-shell { padding-bottom: 0; }
  .bottom-nav { display: none; }
  /* v17: .search-bar deprecated — split into .search-shell-anchor + .chip-row-anchor.
     Top anchor is 16px on desktop (matches FAB right). */
  .search-shell-anchor, .chip-row-anchor { top: 16px; }
  /* Desktop: locate FAB sits ABOVE the scale bar (bottom 16px + ~24px tall +
     ~32px gap = bottom 72px) and BELOW the custom zoom column. */
  .map-shell .map-fab { right: 16px; bottom: 72px; }

  .result-panel, .detail-panel { display: none !important; }
  .sheet-handle { display: none; }

  /* Desktop attribution: stay INSIDE the map area (rail occupies the first
     --rail-w pixels). When the list sidebar is also open, push past it so the
     attribution stays in the actual visible map strip — never under a panel. */
  .map-status { bottom: 12px; left: calc(var(--rail-w, 80px) + 14px); }
  .map-shell[data-layout="rail-list"] .map-status,
  .map-shell[data-layout="rail-list-detail"] .map-status {
    left: calc(var(--rail-w, 80px) + var(--list-w, 380px) + 14px);
  }

  /* desktop header for non-map pages */
  .desktop-only { display: inline-flex; }

  .dash-grid, .admin-shell {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 1440px) {
  .chip-row-anchor { right: 24px; }
  .map-shell .map-fab { right: 24px; }
  /* Keep custom zoom + scale aligned to the same right gutter as the FAB. */
  .map-zoom  { right: 22px; }
  .map-scale { right: 24px; }
  .summary-grid { grid-template-columns: repeat(4, 1fr); }
}

/* ===== Utilities ===== */

.row { display: flex; gap: 8px; align-items: center; }
.col { display: flex; flex-direction: column; gap: 8px; }
.gap-4 { gap: 4px; } .gap-8 { gap: 8px; } .gap-12 { gap: 12px; } .gap-16 { gap: 16px; }
.mb-8 { margin-bottom: 8px; } .mb-12 { margin-bottom: 12px; } .mb-16 { margin-bottom: 16px; }
.mt-8 { margin-top: 8px; } .mt-12 { margin-top: 12px; } .mt-16 { margin-top: 16px; }
.text-center { text-align: center; }
.f-bold { font-weight: 700; }
.hidden { display: none !important; }
.spacer { flex: 1; }

/* Visually hidden */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ===== Diagnostic panel (?diag=1) ===== */
.diag-panel {
  position: fixed;
  top: 12px; right: 12px;
  z-index: 99999;
  background: rgba(15, 23, 42, 0.94);
  color: #F8FAFC;
  border: 1px solid rgba(6, 182, 212, 0.4);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--f-mono);
  font-size: 11px;
  line-height: 1.45;
  max-width: 320px;
  box-shadow: 0 10px 24px rgba(15,23,42,0.45);
  pointer-events: none;
}
.diag-panel .diag-title { font-weight: 700; color: #06B6D4; letter-spacing: 0.06em; margin-bottom: 6px; }
.diag-panel .diag-row { display: flex; justify-content: space-between; gap: 12px; }
.diag-panel .diag-v { font-weight: 600; }
.diag-panel .diag-v.pending { color: #94A3B8; }
.diag-panel .diag-v.ok { color: #22C55E; }
.diag-panel .diag-v.fail { color: #EF4444; }
.diag-panel .diag-v.warn { color: #F97316; }

/* ===== Rail + Wide sidebar ===== */
.map-rail {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  z-index: 25;
  width: var(--rail-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  align-items: stretch;
  padding: 12px 6px;
  gap: 6px;
}

/* Rail-top logo — sits at the very top of the desktop rail above the
   category buttons. Click resets the home state (close detail/sidebar,
   deselect category). The PNG asset is RGB without alpha (white bg) — the
   rail surface is also white, so the two blend without showing a square. */
.rail-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 6px 2px 8px;
  margin: -4px 0 4px;            /* pull tight against the rail's top padding */
  border: 0;
  background: transparent;       /* PNG 가 transparent corners 라 wrapper 도 투명 */
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.rail-logo:hover { background: rgba(15, 23, 42, 0.04); }
.rail-logo img {
  display: block;
  width: 100%;
  max-height: 56px;
  object-fit: contain;            /* preserve 2:1 ratio — no crop/squish */
}
.rail-item {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  padding: 10px 4px;
  border: 0; background: transparent;
  border-radius: var(--r-md);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 11px; font-weight: 600;
  position: relative;
}
.rail-item:hover { background: var(--surface-soft); color: var(--text-strong); }
.rail-item.active { background: var(--brand-soft); color: var(--brand); }
.rail-item.active::before {
  content: ""; position: absolute; left: -6px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 2px 2px 0; background: var(--brand);
}
/* Rail category icons — 투명 배경 PNG (`_t.png` 시리즈) 사용. wrapper 자체는
   배경/테두리/그림자/border-radius 없이 완전 투명 → 사각형 흔적 0. rail 자체가
   --surface(#fff) 위에 놓여 있으므로 PNG 의 anti-alias 가장자리도 자연스럽게 합쳐짐. */
.rail-icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
}
.rail-icon svg { width: 22px; height: 22px; }
/* Asset-based rail icons (card_shop / pokemon_vending_machine) — preserve the
   1:1 source aspect via object-fit:contain. No mask / clip-path / border-radius. */
.rail-icon .rail-icon-img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.rail-count {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-muted);
  background: var(--surface-soft);
  border-radius: 8px;
  padding: 1px 6px;
  margin-top: 2px;
}
/* 카드샵/자판기 numeric 카운트는 rail 표시 안 함 — 단순 라벨만.
   문구점 (stationery_store) 의 '.rail-count--soon' coming-soon pill 은 유지. */
.rail-count[data-count-for="card_shop"],
.rail-count[data-count-for="pokemon_vending_machine"] {
  display: none;
}
.rail-item.active .rail-count { background: var(--brand); color: #fff; }
.rail-item[data-cat="pokemon_vending_machine"].active .rail-count { background: var(--accent-yellow); color: #1F2937; }

/* === Disabled (Coming Soon) rail items ===
   - Gray out icon + label + count.
   - Block all hover/active visual feedback so users see the category is inert.
   - cursor: not-allowed signals "click does nothing". JS onCategoryClick also
     early-returns for disabled cats — both layers, in case one regresses. */
.rail-item[data-disabled="true"] {
  opacity: 0.42;
  cursor: not-allowed;
  filter: grayscale(0.95);
}
.rail-item[data-disabled="true"]:hover,
.rail-item[data-disabled="true"]:active,
.rail-item[data-disabled="true"].active {
  background: transparent;
  color: var(--text-muted);
}
.rail-item[data-disabled="true"]:hover .rail-icon-img,
.rail-item[data-disabled="true"] .rail-icon-img {
  filter: grayscale(1) opacity(0.85);
}
/* Coming-Soon count pill: replaces the numeric count with a small label. */
.rail-count.rail-count--soon {
  background: #1F2937;
  color: #FDE68A;
  font-size: 8.5px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 1px 4px;
  font-family: var(--f-mono);
  font-weight: 700;
}

.map-sidebar {
  position: absolute;
  left: var(--rail-w); top: 0; bottom: 0;
  z-index: 24;
  width: var(--list-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: 6px 0 24px rgba(15,23,42,0.08);
  display: flex; flex-direction: column;
  /* search-shell-anchor (top: 12-16, height ~44) rides on top of this aside.
     Push content down by anchor-bottom + 10px so the head divider sits below it. */
  padding-top: 64px;
  transform: translateX(-100%);
  transition: transform 240ms ease-out;
}
.map-sidebar[data-mode="category"],
.map-sidebar[data-mode="search"],
.map-sidebar[data-mode="detail"] {
  transform: translateX(0);
}
.map-sidebar[aria-hidden="true"] { pointer-events: none; }

.sidebar-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px 8px;
  border-bottom: 1px solid var(--border);
}
.sidebar-title { font-size: 15px; font-weight: 700; color: var(--text-strong); margin: 0; flex: 1 1 auto; min-width: 0; }
.sidebar-close { background: transparent; border: 0; color: var(--text-muted); font-size: 16px; padding: 6px; cursor: pointer; border-radius: 6px; }
.sidebar-close:hover { background: var(--surface-soft); color: var(--text-strong); }
.sidebar-back {
  background: transparent; border: 0;
  color: var(--text-strong);
  font-size: 22px; line-height: 1;
  padding: 0; margin: 0 4px 0 -4px;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  cursor: pointer;
  flex-shrink: 0;
}
.sidebar-back:hover { background: var(--surface-soft); }
.sidebar-back[hidden] { display: none; }

.sidebar-search { padding: 10px 16px; border-bottom: 1px solid var(--border); }
.sidebar-search input {
  width: 100%; padding: 9px 12px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--surface-soft);
  font-size: 14px; color: var(--text-strong); outline: none;
}
.sidebar-search input:focus { border-color: var(--brand); background: var(--surface); }
.sidebar-search input::placeholder { color: var(--text-subtle); }

.sidebar-body { flex: 1; overflow-y: auto; padding: 10px 12px 24px; }
.sidebar-section { display: block; }
.sidebar-section[hidden] { display: none; }
.sidebar-list { display: flex; flex-direction: column; gap: 8px; }
.sidebar-empty { padding: 32px 16px; text-align: center; color: var(--text-muted); font-size: 13px; }

.sidebar-collapse {
  position: absolute;
  right: -16px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-2);
  color: var(--text-muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700;
}
.sidebar-collapse:hover { color: var(--brand); border-color: var(--brand); }
.map-sidebar[data-mode="closed"] .sidebar-collapse { display: none; }

/* ===== Rail-edge sidebar toggle (always available) =====
   Position is driven by .map-shell[data-layout=...]:
     rail               → rail's outer edge
     rail-list          → list panel's outer edge
     rail-list-detail   → detail panel's outer edge
   Sticking to data-layout (single source of truth) keeps the toggle aligned
   with whichever panel is the right-most open one. */
.rail-toggle {
  position: absolute;
  left: var(--rail-w); top: 50%;
  transform: translateY(-50%);
  width: 22px; height: 56px;
  z-index: 27;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 0;
  border-radius: 0 12px 12px 0;
  box-shadow: 4px 0 12px rgba(15,23,42,0.08);
  color: var(--text-muted);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; line-height: 1;
  transition: left 240ms ease-out, color 160ms ease, border-color 160ms ease;
  padding: 0;
}
.map-shell[data-layout="rail-list"] .rail-toggle {
  left: calc(var(--rail-w) + var(--list-w));
}
.map-shell[data-layout="rail-list-detail"] .rail-toggle {
  /* sit flush against the floating detail's right edge (panel left = rail+list+12) */
  left: calc(var(--rail-w) + var(--list-w) + 12px + var(--detail-w));
}
@media (max-width: 600px) {
  .map-shell[data-layout="rail-list"] .rail-toggle,
  .map-shell[data-layout="rail-list-detail"] .rail-toggle {
    left: calc(100vw - 22px);
  }
}
.rail-toggle:hover { color: var(--brand); border-color: var(--brand); }
.rail-toggle .rail-toggle-arrow { display: inline-block; transition: transform 200ms ease; }
.rail-toggle[aria-expanded="true"] .rail-toggle-arrow { transform: rotate(180deg); }
@media (max-width: 600px) {
  .rail-toggle { left: 56px; height: 48px; width: 20px; }
}

/* search-bar / chip-row 위치 보정: rail 폭 만큼 오른쪽으로 */
/* search-bar / FAB never overlap a sidebar — left offset follows data-layout. */
.map-shell .search-bar {
  left: calc(var(--rail-w) + 12px);
  right: 16px;
  transition: left 240ms ease-out, right 240ms ease-out;
}
.map-shell[data-layout="rail-list"] .search-bar {
  left: calc(var(--rail-w) + var(--list-w) + 12px);
}
.map-shell[data-layout="rail-list-detail"] .search-bar {
  left: calc(var(--rail-w) + var(--list-w) + var(--detail-w) + 12px);
}
@media (max-width: 768px) {
  /* Mobile uses bottom nav; the rail logo isn't shown on mobile. */
  .rail-logo { display: none !important; }
}
@media (max-width: 600px) {
  .map-rail { padding: 8px 4px; }
  .rail-item { font-size: 10.5px; padding: 8px 2px; }
  .map-sidebar { width: calc(100vw - var(--rail-w)); }
  .map-shell .search-bar,
  .map-shell[data-layout="rail-list"] .search-bar,
  .map-shell[data-layout="rail-list-detail"] .search-bar {
    left: calc(var(--rail-w) + 8px);
    right: 8px;
  }
}

/* 자판기 카테고리 활성 시 — rail-item 좌측 인디케이터 노란 액센트 */
.rail-item.active[data-cat="pokemon_vending_machine"]::before {
  background: var(--accent-yellow);
}

.sidebar-detail { padding: 0 4px; }
.sidebar-detail .detail-empty { padding: 32px 16px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* Vending machine card / detail */
.badge.type.vending {
  background: #FEF3C7;
  color: #78350F;
  border: 1px solid #FCD34D;
}
.store-card--vending .thumb-vending {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  /* No overflow:hidden — original aspect of the asset must show in full. */
}
.store-card--vending .thumb-vending svg { width: 80%; height: 80%; }
.store-card--vending .thumb-vending .thumb-vending-img {
  /* Keep original 1:1 ratio (asset is 1254×1254). object-fit: contain prevents
     the photo from being cropped to fill the thumb container. */
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.store-card--vending .meta a.link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.store-card--vending .meta a.link:hover { text-decoration: underline; }

/* Card-shop list card — uses the same shell as vending but with the asset
   PNG of the red storefront pin (matches the marker on the map). */
.store-card--cardshop .thumb-cardshop {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  /* No overflow:hidden / mask — pin shape must render uncut. */
}
.store-card--cardshop .thumb-cardshop svg { width: 80%; height: 80%; }
.store-card--cardshop .thumb-cardshop .thumb-cardshop-img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
.store-card--cardshop .meta a.link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.store-card--cardshop .meta a.link:hover { text-decoration: underline; }
.badge.type.cardshop {
  background: #FEE2E2;
  color: #991B1B;
  border: 1px solid #FCA5A5;
}

.detail-vending {
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px;
}
.detail-vending .vending-thumb {
  width: 88px; height: 88px;
  background: var(--surface);
  border-radius: 50%;
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  align-self: center;
}
.detail-vending .vending-thumb svg { width: 64px; height: 64px; }
.detail-vending h3 { font-size: 16px; font-weight: 700; text-align: center; margin: 0; color: var(--text-strong); }
.detail-vending .meta-line { text-align: center; font-size: 13px; color: var(--text-muted); }
.detail-vending .actions { display: flex; gap: 8px; justify-content: center; margin-top: 8px; }
.detail-vending .btn-primary {
  background: var(--brand); color: #fff; padding: 10px 16px; border-radius: var(--r-md);
  font-weight: 600; font-size: 14px; text-decoration: none;
}

/* ===== Vending marker sizing =====
   Mock: keep 44x56 wrapper with flex-center so the SVG visually nests inside
   the larger hit area (mock's translate(-50%,-100%) handles bottom-center).
   Naver: wrapper MUST equal the rendered SVG size (35x45) so the icon.anchor
   we configure (pin tip pixel) actually lines up with the lat/lng. A larger
   wrapper would force the SVG to the wrapper's center, putting the pin tip
   above the anchor and visibly drifting as zoom changes. */
.mock-marker[data-store-type="pokemon_vending_machine"] {
  width: 44px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Map markers — wrapper sizes MUST match the inline SVG render dims so the
   anchor we set in pinAnchorFor (SVG pin-tip pixel) lines up with the actual
   tip and stays fixed across zoom levels.
   IMPORTANT: markers use inline SVG (transparent canvas) — never the asset
   PNGs. The pin-reference PNGs are RGB (no alpha) with a solid white square
   background; using them here would paint a white card over map tiles and
   hide road labels/POIs.
   HIT AREA: every marker's wrapper IS the click target — `pointer-events: auto`
   on the wrapper and `pointer-events: all` on the inner SVG so clicks land on
   transparent areas of the SVG too (default `visiblePainted` ignores them). */
.naver-pack-marker[data-store-type="pokemon_vending_machine"] {
  width: 35px;
  height: 45px;
  display: block;
  background: transparent;
}
.naver-pack-marker[data-store-type="pokemon_vending_machine"] svg {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
}
.naver-pack-marker[data-store-type="card_shop"] {
  width: 40px;
  height: 50px;
  display: block;
  background: transparent;
}
.naver-pack-marker[data-store-type="card_shop"] svg {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
}
/* Defensive: nothing inside any naver marker should ever pick up a wrapper bg.
   And ensure the entire wrapper rect catches pointer events (Naver auto-detect
   for click hit area can come up short). */
.naver-pack-marker {
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
}
.naver-pack-marker svg {
  /* "all" means hit-test fires on every pixel of the SVG box regardless of
     fill/visibility — so clicks on the SVG's transparent corners still bubble
     up to the wrapper's click handler. */
  pointer-events: all;
}

/* ===== v12 — active marker = red halo (shape preserved) ===== */
.mock-marker.is-active svg,
.naver-pack-marker.is-active svg {
  /* shape stays the same; outer glow + tight outline both in red. */
  filter:
    drop-shadow(0 0 0 #EF4444)
    drop-shadow(0 0 1px #EF4444)
    drop-shadow(0 0 2px #EF4444)
    drop-shadow(0 4px 14px rgba(239, 68, 68, 0.55));
  transition: filter 160ms ease;
}
.mock-marker.is-active,
.naver-pack-marker.is-active { z-index: 9999; }

/* ===== Saved shortcut (rail 하단 항목) =====
   다른 rail 항목과 동일한 톤 — 테두리/배경 박스 없음, 아이콘 색 강조 없음.
   active 일 때만 brand 강조 (.rail-item.active 와 같은 패턴). */
.saved-shortcut {
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  padding: 10px 4px;
  cursor: pointer;
  width: 100%;
  line-height: 1.2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.saved-shortcut:hover { background: var(--surface-soft); color: var(--text-strong); }
.saved-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  color: inherit;            /* line stroke 가 라벨과 같은 회색 → active 시 brand */
  line-height: 1;
}
.saved-icon svg { display: block; }
.saved-label { font-size: 11px; font-weight: 600; }
/* 저장 개수 badge — rail 노출하지 않음 (스펙: rail 카운트 제거). 데이터는 그대로
   유지되어 ProfileSheet 의 빠른 메뉴에는 노출됨. */
.saved-count { display: none !important; }

/* ===== v11 — Naver-style 자판기 상세 ===== */
.detail-vending-naver { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
/* Hero image at the top of the floating detail panel — pulled to the panel
   edges (negative margins cancel the parent padding) so it spans full width.
   Asset (vending_main_pic.png) is 1254×1254, so the hero uses a 1:1 aspect
   ratio with `object-fit: contain` to preserve the asset's exact shape — no
   crop, no squish. Capped via max-height to avoid eating the whole panel. */
.dv-hero {
  margin: -14px -16px 4px;
  width: calc(100% + 32px);
  aspect-ratio: 1 / 1;
  max-height: 240px;
  background: #fff;            /* main_pic 자산 흰 배경에 맞춰 wrapper 도 흰색 */
  display: flex;
  align-items: center;
  justify-content: center;
}
.dv-hero img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
}
/* Fallback state if the hero image 404s — class is set by the inline onerror. */
.dv-hero--fallback {
  aspect-ratio: 16 / 6;
  max-height: 120px;
  background:
    radial-gradient(circle at 30% 50%, #FCD34D 0%, transparent 60%),
    linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);
}
.dv-head .dv-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 6px;
  line-height: 1.3;
}
.dv-head .dv-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.dv-head .meta-line.muted.small { font-size: 12px; color: var(--text-muted); }
.dv-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 10px 0 12px;
  border-bottom: 1px solid var(--border);
}
.dv-action {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: transparent; border: 0; padding: 8px 6px;
  font-size: 12.5px; color: var(--text-strong); cursor: pointer;
  border-radius: var(--r-md);
  text-decoration: none;
}
.dv-action:hover { background: var(--surface-soft); }
.dv-action:hover .dv-action-icon { color: #0F172A; }
.dv-action[aria-pressed="true"] { color: var(--brand); }
.dv-action[aria-pressed="true"] .dv-action-icon { color: var(--accent-yellow); }
/* Line-icon container: matches Naver-style stroke icons. */
.dv-action-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; line-height: 1;
  color: #64748B;
}
.dv-action-icon svg { width: 24px; height: 24px; display: block; }
/* Saved state: fill the star with the stroke color so it reads as "active". */
.dv-action[aria-pressed="true"] .dv-action-icon svg { fill: currentColor; }
.dv-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;                /* mobile fallback if 4 tabs overflow */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.dv-tabs::-webkit-scrollbar { display: none; }
.dv-tab {
  background: transparent; border: 0;
  padding: 8px 12px; cursor: pointer;
  font-size: 13px; font-weight: 600;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  flex-shrink: 0;                  /* don't squish tabs to ellipsis */
  white-space: nowrap;
}
.dv-tab.active { color: var(--brand); border-color: var(--brand); }
.dv-tab-count {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 700;
  background: rgba(37,99,235,0.14);
  color: var(--brand);
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 2px;
}
.dv-tab-body { padding: 8px 0 4px; display: flex; flex-direction: column; }
.dv-tab-pane { display: none; flex-direction: column; gap: 10px; padding: 4px 0; }
.dv-tab-pane.is-active { display: flex; }

/* Card-shop home tab — surface card */
.cs-home-desc {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.55;
  margin: 0 0 4px;
}
.cs-home-news {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--surface-soft);
  border-radius: 10px;
  border: 1px solid var(--border);
  font-size: 12.5px;
}
.cs-home-news-tag {
  font-size: 10.5px; font-weight: 700;
  background: #0F172A; color: #fff;
  padding: 2px 8px; border-radius: 999px;
  flex-shrink: 0;
}
.cs-home-news-title {
  color: var(--text-strong);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.cs-home-inv {
  font-size: 12px;
  color: var(--text-muted);
  padding: 8px 0;
}
.cs-home-inv--empty { color: var(--text-muted); }

/* Card-shop inventory tab — read-only product rows */
.cs-inv-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.cs-inv-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 12px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.cs-inv-row.is-sold { background: var(--surface-soft); }
.cs-inv-img {
  width: 56px; height: 56px;
  object-fit: contain;
  background: #fff;            /* 카탈로그/제공 PNG 가 흰 배경 → wrapper 도 흰색 */
  border: 1px solid var(--border);
  border-radius: 8px;
  display: block;
}
.cs-inv-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 24px;
  color: var(--text-muted);
}
.cs-inv-meta { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.cs-inv-name {
  font-size: 13px; font-weight: 700;
  color: var(--text-strong);
  word-break: break-word;
}
.cs-inv-sub { font-size: 11px; color: var(--text-muted); }
.cs-inv-meta-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 2px;
}
.cs-inv-stock {
  font-size: 12px; font-weight: 700;
  color: var(--brand);
  font-family: var(--f-mono);
}
.cs-inv-row.is-sold .cs-inv-stock { color: #B91C1C; }
.cs-inv-price {
  font-size: 12px; font-weight: 700;
  color: var(--text-strong);
  font-family: var(--f-mono);
}
.cs-inv-price.is-muted {
  font-weight: 500;
  color: var(--text-muted);
}

/* Card-shop news tab */
.cs-news-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.cs-news-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cs-news-head { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.cs-news-tag {
  font-size: 10.5px; font-weight: 700;
  background: #0F172A; color: #fff;
  padding: 2px 8px; border-radius: 999px;
}
.cs-news-date { color: var(--text-muted); font-family: var(--f-mono); }
.cs-news-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.cs-news-body { font-size: 12.5px; color: var(--text-strong); line-height: 1.5; }
.cs-news-img {
  width: 100%; max-height: 200px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
}

/* Empty state inside detail tabs */
.cs-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 32px 12px;
  gap: 6px;
  color: var(--text-muted);
}
.cs-empty-icon { font-size: 30px; line-height: 1; }
.cs-empty-title { font-size: 13px; font-weight: 600; color: var(--text-strong); }
.info-row {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 10px;
  align-items: start;
  font-size: 13.5px;
}
.info-row .info-label { color: var(--text-muted); font-size: 12.5px; }
.info-row .info-value { color: var(--text-strong); line-height: 1.5; }
.info-row .info-value a { color: var(--brand); text-decoration: none; }
.info-row .info-value a:hover { text-decoration: underline; }

/* ===== v15 — 2차 detail sidebar (자판기 전용) ===== */
/* Floating detail panel (Naver-style) — sits ON TOP of the map with a gap
   from the list sidebar, rounded corners, vertical viewport margins, and a
   soft drop shadow. Map underneath stays continuous; only the panel area
   covers it. No top padding — header anchors to the panel top. */
.map-detail {
  position: absolute;
  left: calc(var(--rail-w) + var(--list-w) + 12px);
  top: 16px;
  bottom: 16px;
  z-index: 23;
  width: var(--detail-w);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.18);
  padding-top: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  /* fade + tiny lift on enter; visibility flips off after the fade completes
     so a closed panel never paints over a closing list. */
  opacity: 0;
  transform: translateY(6px);
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 200ms ease-out,
    transform 220ms ease-out,
    visibility 0s linear 220ms;
}
.map-detail[data-open="true"] {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity 200ms ease-out,
    transform 220ms ease-out,
    visibility 0s linear 0s;
}
.md-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.md-back, .md-close {
  width: 32px; height: 32px;
  background: transparent; border: 0;
  color: var(--text-strong);
  font-size: 18px; line-height: 1;
  cursor: pointer; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.md-back:hover, .md-close:hover { background: var(--surface-soft); }
.md-eyebrow {
  flex: 1 1 auto;
  text-align: center;
  font-size: 13px; font-weight: 700;
  color: var(--text-muted);
}
.md-body { flex: 1; overflow-y: auto; }

/* ===========================================================================
   MOBILE LAYOUT — single source of truth at 768px breakpoint.

   Strategy: KEEP the same DOM (.map-sidebar / .map-detail) and the same JS
   render functions (paintCategoryList / renderDetailSidebar / openVendingDetail).
   Only swap the CSS positioning so the panels become bottom sheets at mobile.
   This guarantees every desktop fix (rAF recenter, hit-area click, no zoom
   drift, asset image policy, etc.) automatically applies to mobile.

   Hidden on mobile:
     - .map-rail   (left desktop rail — replaced by bottom .mobile-cat-bar)
     - .rail-toggle (desktop edge toggle — sheet handle replaces it)
     - .result-panel, .detail-panel (LEGACY mobile UI — kept in DOM but never
                                     rendered to avoid duplicate-render confusion)

   Visible only on mobile:
     - .mobile-cat-bar (bottom nav)
     - .map-sidebar / .map-detail in bottom-sheet form
   =========================================================================== */

/* Default (desktop / tablet ≥769px): hide the mobile cat bar entirely. */
.mobile-cat-bar { display: none; }

@media (max-width: 768px) {
  /* --- HIDE desktop / legacy mobile UI --- */
  .map-rail        { display: none !important; }
  .rail-toggle     { display: none !important; }
  .result-panel    { display: none !important; }
  .detail-panel    { display: none !important; }

  /* --- map canvas: full width since the rail is gone, leave room for cat bar --- */
  #map-canvas,
  .map-shell[data-layout="rail-list"] #map-canvas,
  .map-shell[data-layout="rail-list-detail"] #map-canvas {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
  }

  /* --- search shell + chips: stretch to full width --- */
  .search-shell-anchor,
  .map-shell[data-layout="rail-list"] .search-shell-anchor,
  .map-shell[data-layout="rail-list-detail"] .search-shell-anchor {
    left: 12px;
    right: 12px;
    width: auto;
    top: calc(12px + env(safe-area-inset-top, 0px));
  }
  .chip-row-anchor,
  .map-shell[data-layout="rail-list"] .chip-row-anchor,
  .map-shell[data-layout="rail-list-detail"] .chip-row-anchor {
    left: 12px;
    right: 12px;
    top: calc(64px + env(safe-area-inset-top, 0px));
  }

  /* --- locate FAB + map-status: dynamic bottom that follows the visible
     map area. JS (updateMobileOverlayBottom) sets --mobile-overlay-bottom
     based on whichever is closer to the viewer:
       - top edge of an open sheet (list/detail), or
       - top edge of the bottom cat bar.
     CSS transition smooths the change so the controls glide along with the
     sheet's slide animation. Fallback uses the cat bar height + safe-area. */
  .map-shell .map-fab {
    right: 16px;
    bottom: var(--mobile-overlay-bottom, calc(72px + env(safe-area-inset-bottom, 0px))) !important;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1);
  }
  .map-status {
    bottom: var(--mobile-overlay-bottom, calc(72px + env(safe-area-inset-bottom, 0px))) !important;
    left: 12px;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1), opacity 200ms ease-out;
  }
  /* Hide the attribution when a sheet is at FULL state — it would otherwise
     float over the (now mostly-covered) map and look like sheet content.
     Sibling combinator works because .map-status is later in DOM than the sheets. */
  .map-detail[data-open="true"][data-sheet-state="full"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="category"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="search"] ~ .map-status,
  .map-sidebar[data-sheet-state="full"][data-mode="detail"] ~ .map-status {
    display: none;
  }

  /* Mobile: hide both custom controls. Pinch-zoom replaces the +/- column,
     and the scale bar would compete with the bottom sheet for vertical room.
     Naver's built-in controls are already disabled at the SDK level (see
     map-adapter.js init), so nothing else needs to be force-hidden here. */
  .map-zoom,
  .map-scale {
    display: none !important;
  }

  /* --- BOTTOM SHEETS (list + detail) — 3 snap states --------------------
     State                CSS variable               Approx. height
     collapsed            120px                      title peek only
     half (default)       50vh                       map visible above
     full                 100vh − safe-area − 24     near full screen

     Drag is wired in JS (setupSheetDrag) — it sets `--sheet-h` inline during
     drag; on release it removes the inline var and snaps to the closest state
     by writing data-sheet-state. CSS .is-dragging disables the height
     transition so finger movement feels 1:1. */
  .map-sidebar,
  .map-detail {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    top: auto;
    width: 100%;
    border-right: 0;
    border-top: 1px solid var(--border);
    border-radius: 16px 16px 0 0;
    padding-top: 28px;     /* room for the grab handle */
    padding-bottom: calc(env(safe-area-inset-bottom, 0px));
    --sheet-h: 50vh;
    height: var(--sheet-h);
    transition: transform 280ms cubic-bezier(.2,.7,.2,1),
                height 220ms cubic-bezier(.2,.7,.2,1);
    overscroll-behavior: contain;
  }
  .map-sidebar.is-dragging,
  .map-detail.is-dragging {
    transition: transform 0s, height 0s;     /* 1:1 finger tracking */
  }
  .map-sidebar[data-sheet-state="collapsed"],
  .map-detail[data-sheet-state="collapsed"] { --sheet-h: 120px; }
  .map-sidebar[data-sheet-state="half"],
  .map-detail[data-sheet-state="half"]      { --sheet-h: 50vh; }
  .map-sidebar[data-sheet-state="full"],
  .map-detail[data-sheet-state="full"]      {
    --sheet-h: calc(100vh - 24px - env(safe-area-inset-top, 0px));
  }

  /* List sheet — driven by data-mode (closed vs open) */
  .map-sidebar {
    box-shadow: 0 -8px 24px rgba(15,23,42,0.15);
    transform: translateY(100%);
    z-index: 30;
  }
  .map-sidebar[data-mode="category"],
  .map-sidebar[data-mode="search"],
  .map-sidebar[data-mode="detail"] {
    transform: translateY(0);
  }

  /* Detail sheet — driven by data-open and sits ABOVE the list */
  .map-detail {
    margin: 0;
    border: 0;
    border-top: 1px solid var(--border);
    box-shadow: 0 -10px 28px rgba(15,23,42,0.22);
    opacity: 1;
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 280ms cubic-bezier(.2,.7,.2,1),
                height 220ms cubic-bezier(.2,.7,.2,1),
                visibility 0s linear 280ms;
    z-index: 31;
  }
  .map-detail[data-open="true"] {
    transform: translateY(0);
    visibility: visible;
    transition: transform 280ms cubic-bezier(.2,.7,.2,1),
                height 220ms cubic-bezier(.2,.7,.2,1),
                visibility 0s linear 0s;
  }

  /* Grab handle — full-width invisible hit zone with a centered visual bar.
     `touch-action: none` on the hit zone prevents native scrolling so JS owns
     the drag gesture. Made tall (40px) and the bar slightly thicker so users
     can easily find/grab it — especially when retracting from "full" state. */
  .sheet-grab {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 40px;
    z-index: 5;
    cursor: grab;
    touch-action: none;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .map-sidebar.is-dragging .sheet-grab,
  .map-detail.is-dragging .sheet-grab { cursor: grabbing; }
  .sheet-grab-bar {
    width: 44px; height: 5px;
    background: #cbd5e1;
    border-radius: 3px;
    pointer-events: none;
    transition: background 120ms ease, width 120ms ease;
  }
  .map-sidebar.is-dragging .sheet-grab-bar,
  .map-detail.is-dragging .sheet-grab-bar {
    background: var(--brand);
    width: 56px;
  }
  /* Sheet header: in addition to the small grab, the header itself is wired
     as a drag zone in JS — give it a subtle "grabbable" cursor so desktop
     pointers also see the affordance. (Buttons inside have their own cursor.) */
  .map-sidebar > .sidebar-head,
  .map-detail > .md-head {
    cursor: grab;
    touch-action: none;
    user-select: none;
  }
  .map-sidebar.is-dragging > .sidebar-head,
  .map-detail.is-dragging > .md-head { cursor: grabbing; }
  .map-sidebar > .sidebar-head button,
  .map-detail > .md-head button {
    cursor: pointer;
    touch-action: auto;
  }
  /* Padding adjustment: grab grew to 40px so head needs a bit more breathing room. */
  .map-sidebar, .map-detail { padding-top: 40px; }

  /* Body content: only the FULL state allows internal scroll; in collapsed/half
     the sheet is small enough that scrolling competes with the drag gesture.
     overscroll-behavior: contain prevents page-level overscroll on iOS. */
  .map-sidebar .sidebar-body,
  .map-detail .md-body {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .map-sidebar:not([data-sheet-state="full"]) .sidebar-body,
  .map-detail:not([data-sheet-state="full"]) .md-body {
    overflow-y: auto;
  }
  .map-sidebar[data-sheet-state="full"] .sidebar-body,
  .map-detail[data-sheet-state="full"] .md-body {
    overflow-y: auto;
  }
  .map-sidebar[data-sheet-state="collapsed"] .sidebar-body,
  .map-detail[data-sheet-state="collapsed"] .md-body {
    /* keep DOM but hide inner scroll while peek */
    overflow: hidden;
  }

  /* shrink the detail hero on half/collapsed so map stays visible above it */
  .map-detail[data-sheet-state="half"] .dv-hero,
  .map-detail[data-sheet-state="collapsed"] .dv-hero {
    max-height: 140px;
  }
  .map-detail[data-sheet-state="full"] .dv-hero {
    max-height: 240px;
  }

  /* --- MOBILE CATEGORY BAR --- */
  .mobile-cat-bar {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    background: var(--surface);
    border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -4px 16px rgba(15,23,42,0.06);
  }
  .mcb-item {
    flex: 1;
    display: flex; flex-direction: column;
    align-items: center; gap: 2px;
    background: transparent; border: 0;
    padding: 6px 4px;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: 8px;
    transition: color 120ms ease, background 120ms ease;
  }
  .mcb-item:hover, .mcb-item.active {
    color: var(--brand);
    background: var(--brand-soft);
  }
  .mcb-item[data-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    filter: grayscale(0.95);
  }
  .mcb-item[data-disabled="true"]:hover,
  .mcb-item[data-disabled="true"].active {
    background: transparent;
    color: var(--text-muted);
  }
  .mcb-icon {
    width: 26px; height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .mcb-icon img {
    width: 100%; height: 100%;
    max-width: 100%; max-height: 100%;
    object-fit: contain;
    object-position: center;
    display: block;
  }
  .mcb-label {
    font-size: 11px;
    font-weight: 600;
    line-height: 1.15;
    text-align: center;
  }
  .mcb-label small {
    display: inline-block;
    font-size: 8px;
    background: #1F2937;
    color: #FDE68A;
    padding: 1px 4px;
    border-radius: 3px;
    margin-left: 4px;
    letter-spacing: 0.04em;
    font-family: var(--f-mono);
    font-weight: 700;
  }
}

/* ===========================================================================
   LOGIN — rail bottom button + modal (desktop) / bottom sheet (mobile)
   ---------------------------------------------------------------------------
   Rail button uses .rail-item shell so visual style matches the categories.
   The mobile cat bar gets a 4th .mcb-item (.mcb-login). Modal sits at z-index
   above all map overlays / sheets so login is reachable from any state.
   =========================================================================== */

/* Rail bottom anchor — pushes the login item to the bottom of the rail flex
   column. Above-the-rail savedShortcut still sits with its own margin-top:10px
   directly under the categories. */
/* siteInfo + login form a bottom-anchored pair. The first item (siteInfo)
   takes the auto-margin; login flows directly under it (no auto-margin so
   they don't separate). */
.rail-info {
  margin-top: auto;
  border-top: 1px dashed var(--border);
  padding-top: 10px;
  color: var(--text-muted);
}
.rail-info:hover { color: var(--text-strong); }
.rail-login {
  padding-top: 4px;
}
.rail-login.is-loggedin { color: var(--brand); }
.rail-avatar {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  border-radius: 50%;
  font-family: var(--f-mono);
}

/* === Modal === */
.login-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;       /* above floating detail (31), cat bar (40), all sheets */
  display: none;
  align-items: center;
  justify-content: center;
}
.login-modal.is-open { display: flex; }
.login-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.login-modal-card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border-radius: 14px;
  width: min(380px, calc(100% - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 24px 24px 20px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
  animation: login-modal-in 200ms cubic-bezier(.2,.7,.2,1);
}
@keyframes login-modal-in {
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.login-modal-close {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  background: transparent; border: 0;
  font-size: 16px; color: var(--text-muted);
  cursor: pointer;
  border-radius: 8px;
}
.login-modal-close:hover { background: var(--surface-soft); color: var(--text-strong); }
.login-title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 6px;
}
.login-sub {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0 0 18px;
  line-height: 1.5;
}
.login-form { display: flex; flex-direction: column; gap: 12px; margin-bottom: 14px; }
.login-field { display: flex; flex-direction: column; gap: 4px; }
.login-field-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.login-field input {
  font: inherit;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
  outline: none;
  transition: border-color 120ms ease, background 120ms ease;
}
.login-field input:focus {
  border-color: var(--brand);
  background: var(--surface);
}
.login-submit {
  font: inherit;
  font-weight: 700;
  padding: 11px 14px;
  border-radius: 10px;
  border: 0;
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  margin-top: 4px;
  transition: filter 120ms ease;
}
.login-submit:hover { filter: brightness(0.95); }
.login-submit--ghost {
  background: transparent;
  color: var(--text-strong);
  border: 1px solid var(--border);
}
.login-submit--ghost:hover { background: var(--surface-soft); }
.login-secondary {
  display: flex; justify-content: space-between; gap: 8px;
  margin-top: 4px;
}
.login-link {
  background: transparent; border: 0;
  color: var(--text-muted);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 2px;
}
.login-link:hover { color: var(--brand); text-decoration: underline; }
.login-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 12px;
  color: var(--text-subtle);
  font-size: 11px;
}
.login-divider::before,
.login-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
.login-social { display: flex; flex-direction: column; gap: 8px; }
.login-social {
  font: inherit;
}
.login-social > .login-social {
  display: none;  /* dummy — keeps the button selector below clean */
}
button.login-social {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-strong);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
button.login-social:hover { background: var(--surface-soft); }
.login-social-mark {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  font-weight: 800;
  font-size: 12px;
}
.login-social--naver  .login-social-mark { background: #03C75A; color: #fff; }
.login-social--kakao  .login-social-mark { background: #FEE500; color: #1F2937; }
.login-social--google .login-social-mark { background: #fff; color: #4285F4; border: 1px solid var(--border); }

/* ===== Tabs (일반 / 사업자) — segmented control ===== */
.login-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin: 4px 0 16px;
}
.login-tab {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  padding: 8px 10px;
  border-radius: 7px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.login-tab:hover { color: var(--text-strong); }
.login-tab.is-active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
}
.login-pane { display: block; }

/* Helper text & 사업자-only sub copy */
.login-sub--biz { color: var(--text-strong); font-weight: 500; }
.login-helper-text {
  font-size: 11.5px;
  color: var(--text-muted);
  margin: 6px 0 0;
}
.login-mode-toggle {
  justify-content: center;
  align-items: center;
  margin-top: 14px;
}
.login-link-prefix {
  font-size: 12px;
  color: var(--text-muted);
}

/* 사업자 form: 2열 row + 사업자번호 row */
.login-form--biz { gap: 14px; }
.login-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.login-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
}
.login-row input { min-width: 0; }
.login-verify-btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--brand);
  background: var(--surface);
  color: var(--brand);
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms ease, color 120ms ease;
}
.login-verify-btn:hover:not(:disabled)  { background: var(--brand); color: #fff; }
.login-verify-btn:disabled { opacity: 0.55; cursor: progress; }

/* Verify status pill (idle / pending / verified / failed) */
.verify-status {
  margin-top: 6px;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 11.5px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 1.3;
}
.verify-status--idle    { background: rgba(100,116,139,0.10); color: #475569; }
.verify-status--pending { background: rgba(234,179,8,0.14);   color: #854D0E; }
.verify-status--ok      { background: rgba(34,197,94,0.14);   color: #166534; }
.verify-status--err     { background: rgba(239,68,68,0.12);   color: #991B1B; }
.verify-spinner {
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: verify-spin 700ms linear infinite;
  display: inline-block;
}
@keyframes verify-spin { to { transform: rotate(360deg); } }

/* Radio group (매장 종류) */
.login-radio-group {
  border: 0;
  padding: 0;
  margin: 0;
}
.login-radio-group .login-field-label { padding: 0; margin-bottom: 6px; display: block; }
.login-radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-strong);
  cursor: pointer;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-right: 8px;
  background: var(--surface);
  transition: background 120ms ease, border-color 120ms ease;
}
.login-radio:hover { background: var(--surface-soft); }
.login-radio input[type="radio"] {
  accent-color: var(--brand);
  margin: 0;
}
.login-radio:has(input[type="radio"]:checked) {
  background: rgba(37,99,235,0.08);
  border-color: var(--brand);
}

/* Email-verify code row appears below the email row when a code has been
   sent. Spacing matches the biz-num row above. */
.login-row--code { margin-top: 8px; }

/* 약관 동의 체크박스 — 회원가입 form 하단 */
.login-terms {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-strong);
  line-height: 1.5;
  padding: 4px 2px;
  cursor: pointer;
}
.login-terms input[type="checkbox"] {
  accent-color: var(--brand);
  margin-top: 2px;
  flex-shrink: 0;
}
.login-terms-link {
  color: var(--brand);
  text-decoration: underline;
  cursor: pointer;
}
.login-terms-link:hover { filter: brightness(0.9); }
.login-terms-required {
  color: #B91C1C;
  font-weight: 600;
  font-size: 11.5px;
  white-space: nowrap;
}

/* Dev-only test login button — visually distinct from real submit (dashed
   outline + monospace meta) so testers immediately recognize it as a shortcut. */
.login-test-btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1.5px dashed #94A3B8;
  background: var(--surface-soft);
  color: var(--text-strong);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.login-test-btn:hover { background: #FEF3C7; border-color: #F59E0B; }
.login-test-meta {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 500;
  color: var(--text-muted);
}

/* 사업자 submit variant — slightly different tone so the role is obvious */
.login-submit--biz { background: #0F172A; }
.login-submit--biz:hover:not(:disabled) { background: #1E293B; filter: none; }
.login-submit:disabled { opacity: 0.5; cursor: not-allowed; }

/* Logged-in business meta block */
.login-user-role {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 600;
  margin-top: 1px;
  letter-spacing: 0.02em;
}
.login-biz-meta {
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  margin: 0 0 14px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  font-size: 12px;
}
.login-biz-meta > div {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px;
}
.login-biz-meta dt {
  margin: 0;
  color: var(--text-muted);
  font-weight: 600;
}
.login-biz-meta dd {
  margin: 0;
  color: var(--text-strong);
  word-break: break-word;
}

/* Business avatar tinted differently from user avatar */
.rail-avatar--biz { background: #0F172A; }

/* Application status pill in the logged-in business view */
.biz-app-status {
  margin: 4px 0 12px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
}
.biz-app-status--pending { background: rgba(234,179,8,0.14); color: #854D0E; }
.biz-app-status--ok      { background: rgba(34,197,94,0.14); color: #166534; }
.biz-app-status--err     { background: rgba(239,68,68,0.12); color: #991B1B; }

/* ===== Admin panel (mock — ?admin=1 or pokemapAdmin.open()) ===== */
.admin-panel {
  position: fixed;
  bottom: 16px;
  left: 16px;
  width: min(380px, calc(100% - 32px));
  max-height: calc(100vh - 32px);
  z-index: 50;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: 13px;
}
.admin-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: #0F172A;
  color: #fff;
}
.admin-panel-head h3 { margin: 0; font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.admin-close {
  background: transparent; border: 0;
  color: rgba(255,255,255,0.7); cursor: pointer;
  font-size: 14px; padding: 4px 8px; border-radius: 6px;
}
.admin-close:hover { background: rgba(255,255,255,0.1); color: #fff; }

.admin-panel-body { overflow-y: auto; padding: 8px 12px 12px; }

.admin-section { margin-top: 10px; }
.admin-section-title {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 6px;
  font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted);
}
.admin-count {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--text-muted);
}
.admin-status-badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.02em;
}
.admin-status-badge--pending { background: rgba(234,179,8,0.18);  color: #854D0E; }
.admin-status-badge--ok      { background: rgba(34,197,94,0.18);  color: #166534; }
.admin-status-badge--err     { background: rgba(239,68,68,0.16);  color: #991B1B; }

/* Admin sheet status badges (Supabase-driven) — match the legacy palette
   above but keyed by the application_status enum value names. */
.badge.admin-status-badge--pending_review { background: rgba(234,179,8,0.18);  color: #854D0E; }
.badge.admin-status-badge--approved       { background: rgba(34,197,94,0.18);  color: #166534; }
.badge.admin-status-badge--rejected       { background: rgba(239,68,68,0.16);  color: #991B1B; }

.admin-app {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 6px;
  background: var(--surface-soft);
}
.admin-app-meta { min-width: 0; }
.admin-app-name {
  font-size: 13px; font-weight: 700; color: var(--text-strong);
  word-break: break-word;
}
.admin-app-type {
  font-size: 10.5px; font-weight: 600;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 1px 6px; border-radius: 4px;
  margin-left: 4px;
}
.admin-app-sub {
  font-size: 11.5px; color: var(--text-muted);
  margin-top: 2px;
  word-break: break-word;
}
.admin-app-reason {
  font-size: 11px; color: #991B1B;
  margin-top: 4px;
}
.admin-app-actions {
  display: flex; flex-direction: column; gap: 4px;
}
.admin-btn {
  font: inherit;
  font-size: 11.5px; font-weight: 700;
  padding: 6px 12px;
  border-radius: 6px;
  border: 0; cursor: pointer;
  white-space: nowrap;
  transition: filter 120ms ease;
}
.admin-btn:hover { filter: brightness(0.95); }
.admin-btn--approve { background: #16A34A; color: #fff; }
.admin-btn--reject  { background: #DC2626; color: #fff; }
.admin-btn--ghost   { background: var(--surface); color: var(--text-strong); border: 1px solid var(--border); }
.admin-empty {
  font-size: 12px;
  color: var(--text-muted);
  padding: 6px 0 4px;
}

@media (max-width: 768px) {
  /* Mobile: anchor to top so it doesn't fight the bottom sheet stack. */
  .admin-panel {
    top: calc(env(safe-area-inset-top, 0px) + 8px);
    left: 8px; right: 8px; bottom: auto;
    width: auto;
    max-height: 60vh;
  }
}

/* Logged-in user card */
.login-user {
  display: flex; align-items: center; gap: 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  margin-bottom: 14px;
}
.login-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700;
  font-family: var(--f-mono);
}
.login-user-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.login-user-name { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.login-user-email { font-size: 12px; color: var(--text-muted); }

/* Mobile: present as a bottom sheet instead of a centered modal. */
@media (max-width: 768px) {
  .login-modal { align-items: flex-end; }
  .login-modal-card {
    width: 100%;
    max-width: 100%;
    max-height: 84vh;
    border-radius: 16px 16px 0 0;
    padding-top: 28px;
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    animation: login-sheet-in 240ms cubic-bezier(.2,.7,.2,1);
  }
  /* tiny grab indicator at the top of the mobile sheet */
  .login-modal-card::before {
    content: '';
    position: absolute;
    top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 44px; height: 5px;
    border-radius: 3px;
    background: #cbd5e1;
  }
  .login-modal-close { top: 18px; right: 14px; }
}
@keyframes login-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* =====================================================================
   Profile sheet (내정보) — naver-style account/settings panel.
   Desktop: centered modal-like card (~440px wide).
   Mobile : full-height bottom-anchored sheet.
===================================================================== */
.profile-sheet {
  position: fixed;
  inset: 0;
  z-index: 1100;             /* above login-modal (1000) */
  display: none;
  align-items: center;
  justify-content: center;
}
.profile-sheet.is-open { display: flex; }
.ps-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.ps-card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border-radius: 16px;
  width: min(440px, calc(100% - 32px));
  max-height: calc(100vh - 64px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
  animation: ps-card-in 220ms cubic-bezier(.2,.7,.2,1);
}
@keyframes ps-card-in {
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.ps-body { overflow-y: auto; padding: 0 0 16px; }

/* Top bar */
.ps-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 6px;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 2;
}
.ps-topbar-left, .ps-topbar-right { display: flex; align-items: center; gap: 4px; }
.ps-title {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  color: var(--text-strong);
}
.ps-icon-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--text-strong);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  transition: background 120ms ease;
}
.ps-icon-btn:hover { background: var(--surface-soft); }

/* Sub-view top bar (with back arrow). Same layout, different left content. */
.ps-topbar--sub .ps-topbar-left .ps-icon-btn {
  font-size: 22px;
  font-weight: 700;
  margin-right: 4px;
}

/* Profile area */
.ps-profile {
  padding: 4px 24px 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  border-bottom: 1px solid var(--border);
}
.ps-avatar-wrap {
  position: relative;
  margin-bottom: 12px;
}
.ps-avatar {
  width: 88px; height: 88px;
  border-radius: 50%;
  background: linear-gradient(135deg, #DBEAFE, #BFDBFE);
  display: flex; align-items: center; justify-content: center;
  border: 3px solid var(--surface);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.10);
}
.ps-avatar-emoji   { font-size: 44px; line-height: 1; }
.ps-avatar-initial {
  font-family: var(--f-mono);
  font-size: 38px; font-weight: 700;
  color: var(--brand);
}
.ps-avatar-edit {
  position: absolute;
  right: -2px; bottom: -2px;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 2px solid var(--surface);
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
.ps-avatar-edit:hover { filter: brightness(0.95); }
.ps-name {
  font-size: 17px;
  font-weight: 700;
  color: var(--text-strong);
  margin-bottom: 2px;
}
.ps-sub {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-bottom: 8px;
  word-break: break-all;
}
.ps-bio {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.5;
  max-width: 320px;
}
.ps-bio-empty { color: var(--text-muted); font-style: normal; font-size: 12.5px; }

/* Quick menu (2x2 grid) */
.ps-quick {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 16px;
  border-bottom: 1px solid var(--border);
}
.ps-quick-item {
  position: relative;
  background: var(--surface-soft);
  border: 0;
  border-radius: 12px;
  padding: 12px 6px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font: inherit;
  color: var(--text-strong);
  transition: background 120ms ease, transform 120ms ease;
}
.ps-quick-item:hover { background: rgba(37,99,235,0.08); }
.ps-quick-item:active { transform: scale(0.97); }
.ps-quick-icon  {
  font-size: 22px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #2563EB;                    /* primary brand for quick menu icons */
}
.ps-quick-icon svg { display: block; }
.ps-quick-label { font-size: 11.5px; font-weight: 600; }
.ps-quick-badge {
  position: absolute;
  top: 6px; right: 6px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  font-family: var(--f-mono);
  line-height: 16px;
  text-align: center;
}

/* Settings list */
.ps-list {
  display: flex;
  flex-direction: column;
  padding: 8px 8px;
}
.ps-list-item {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 13.5px;
  color: var(--text-strong);
  text-align: left;
  border-radius: 10px;
  transition: background 120ms ease;
}
.ps-list-item:hover { background: var(--surface-soft); }
.ps-list-icon  {
  font-size: 16px;
  text-align: center;
  line-height: 1;
  color: #64748B;                    /* default neutral grey for line icons */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ps-list-icon svg { display: block; }
.ps-list-label { min-width: 0; }
.ps-list-arrow { color: var(--text-muted); font-size: 16px; line-height: 1; }
.ps-list-tag {
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface-soft);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.ps-list-item--brand .ps-list-icon  { color: var(--brand); }
.ps-list-item--brand .ps-list-label { color: var(--brand); font-weight: 700; }
.ps-list-item--danger { color: #B91C1C; }
.ps-list-item--danger .ps-list-icon { color: #B91C1C; }
.ps-list-item--danger-strong { color: #fff; background: #DC2626; margin-top: 6px; }
.ps-list-item--danger-strong:hover { background: #B91C1C; }
.ps-list-item--danger-strong .ps-list-icon { color: #FCA5A5; }

/* ---- Sub-view forms (edit / password / notif / social / location / reviews) ---- */
.ps-form {
  padding: 16px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ps-form-section { display: flex; flex-direction: column; gap: 8px; }
.ps-section-label {
  font-size: 11.5px; font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ps-form-field { display: flex; flex-direction: column; gap: 4px; }
.ps-form-label {
  font-size: 11.5px; font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.ps-form-field input,
.ps-form-field textarea {
  font: inherit;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text-strong);
  outline: none;
  transition: border-color 120ms ease, background 120ms ease;
  resize: vertical;
}
.ps-form-field input:focus,
.ps-form-field textarea:focus { border-color: var(--brand); background: var(--surface); }
.ps-form-readonly {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 0;
  border-top: 1px dashed var(--border);
}
.ps-form-readvalue {
  font-size: 13px;
  color: var(--text-strong);
  font-family: var(--f-mono);
  word-break: break-all;
}
.ps-form-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 8px;
}
.ps-btn {
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  padding: 9px 18px;
  border-radius: 8px;
  border: 0;
  cursor: pointer;
  transition: filter 120ms ease, background 120ms ease;
}
.ps-btn--primary { background: var(--brand); color: #fff; }
.ps-btn--primary:hover { filter: brightness(0.95); }
.ps-btn--ghost {
  background: transparent;
  color: var(--text-strong);
  border: 1px solid var(--border);
}
.ps-btn--ghost:hover { background: var(--surface-soft); }

/* Avatar picker grid */
.ps-avatar-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
}
.ps-avatar-pick {
  aspect-ratio: 1 / 1;
  background: var(--surface-soft);
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  line-height: 1;
  font: inherit;
  color: var(--text-strong);
  transition: background 120ms ease, border-color 120ms ease;
  padding: 0;
}
.ps-avatar-pick:hover { background: rgba(37,99,235,0.10); }
.ps-avatar-pick.is-selected {
  border-color: var(--brand);
  background: rgba(37,99,235,0.12);
}
.ps-avatar-pick .ps-avatar-initial {
  font-size: 16px;
  color: var(--brand);
}

/* Toggle rows for notification settings */
.ps-toggle-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.ps-toggle-row:last-of-type { border-bottom: 0; }
.ps-toggle-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-strong);
}
.ps-toggle-sub {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-muted);
}
.ps-toggle-row input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 40px; height: 22px;
  background: #CBD5E1;
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background 140ms ease;
  flex-shrink: 0;
}
.ps-toggle-row input[type="checkbox"]::before {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  transition: left 140ms ease;
}
.ps-toggle-row input[type="checkbox"]:checked { background: var(--brand); }
.ps-toggle-row input[type="checkbox"]:checked::before { left: 20px; }

/* Social list rows */
.ps-helper {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.5;
}
.ps-social-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.ps-social-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
  font-size: 13px;
}
.ps-social-mark {
  width: 24px; height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center; justify-content: center;
  font-weight: 800;
  font-size: 12px;
}
.ps-social-name { font-weight: 600; color: var(--text-strong); }
.ps-social-status {
  font-size: 11.5px;
  color: var(--text-muted);
  background: var(--surface);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.ps-social-status.is-connected {
  background: rgba(34,197,94,0.14);
  color: #166534;
  border-color: rgba(34,197,94,0.4);
}

/* Bullet list (location info) */
.ps-bullet-list {
  font-size: 12.5px;
  color: var(--text-strong);
  line-height: 1.6;
  padding-left: 18px;
  margin: 4px 0 0;
}

/* Empty state (no reviews etc.) */
.ps-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 40px 16px;
  gap: 8px;
}
.ps-empty-icon {
  font-size: 36px;
  line-height: 1;
  color: #94A3B8;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ps-empty-icon svg { display: block; }
.ps-empty-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.ps-empty-sub  { font-size: 12px; color: var(--text-muted); line-height: 1.5; max-width: 280px; }

/* ---- Mobile: full-height sheet anchored to bottom ---- */
@media (max-width: 768px) {
  .profile-sheet { align-items: flex-end; }
  .ps-card {
    width: 100%;
    max-width: 100%;
    height: 100vh;
    max-height: 100vh;
    border-radius: 16px 16px 0 0;
    padding-top: 28px;             /* room for the grab handle (above) */
    animation: ps-sheet-in 240ms cubic-bezier(.2,.7,.2,1);
    will-change: transform;
  }
  .ps-body {
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  }
  .ps-topbar {
    padding-top: calc(env(safe-area-inset-top, 0px) + 4px);
  }
  .login-modal-card {
    padding-top: 28px;             /* room for the grab handle */
    will-change: transform;
  }
  /* The login-modal-card already had a ::before grab indicator — hide it now
     that we inject a real grab element with pointer events. */
  .login-modal-card::before { display: none; }
}

/* ===== Site info sheet (사이트 정보 / 약관) =====
   Reuses .profile-sheet shell so mobile dismiss-drag, full-height layout,
   and grab handle are all inherited. Only content-specific rules below. */
.si-section {
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
}
.si-section:last-of-type { border-bottom: 0; }
.si-section-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 0 0 8px;
}
.si-section-en {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.si-desc {
  font-size: 13px;
  color: var(--text-strong);
  line-height: 1.6;
  margin: 0;
}
.si-keywords {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.si-keywords li {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--brand);
  background: rgba(37,99,235,0.08);
  padding: 4px 10px;
  border-radius: 999px;
}
.si-meta {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  font-size: 13px;
}
.si-meta > div {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px;
  align-items: start;
}
.si-meta dt { font-weight: 600; color: var(--text-muted); margin: 0; }
.si-meta dd { margin: 0; color: var(--text-strong); }
.si-en { font-size: 12px; color: var(--text-muted); }

/* Terms link list — blue text per spec (참고: dubaicookiemap 약관 톤). */
.si-terms-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.si-terms-list li {
  border-bottom: 1px solid var(--border);
}
.si-terms-list li:last-child { border-bottom: 0; }
.si-link {
  display: block;
  padding: 11px 2px;
  color: #2563EB;            /* 파란색 텍스트 — 약관 링크 표준 */
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  transition: color 120ms ease, text-decoration 120ms ease;
}
.si-link:hover {
  color: #1D4ED8;
  text-decoration: underline;
}
.si-link::after {
  content: '›';
  float: right;
  color: var(--text-muted);
  font-weight: 400;
  font-size: 14px;
}
.si-trademark .si-desc {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.7;
}
.si-footer {
  padding: 14px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border);
  background: var(--surface-soft);
}
.si-copyright {
  margin: 0;
  font-size: 11.5px;
  color: var(--text-muted);
  text-align: center;
}

/* Terms body — long-form prose with scrollable container (parent .ps-body
   already has overflow-y:auto, so we just style the typography). */
.si-terms-body {
  padding: 16px 20px 24px;
  font-size: 13.5px;
  line-height: 1.75;
  color: var(--text-strong);
}
.si-terms-body h4 {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-strong);
  margin: 20px 0 8px;
}
.si-terms-body h4:first-child { margin-top: 0; }
.si-terms-body p { margin: 0 0 10px; }
.si-terms-body ul {
  margin: 0 0 10px;
  padding-left: 20px;
}
.si-terms-body ul li { margin: 0 0 4px; }

/* Dismiss-grab — a real DOM element (not pseudo) so it can own pointer events
   with touch-action: none. Visible only on mobile; auto-injected by JS into
   .ps-card and .login-modal-card. The bar inside is the visual indicator. */
.sheet-dismiss-grab {
  display: none;
}
@media (max-width: 768px) {
  .sheet-dismiss-grab {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 28px;
    z-index: 6;
    cursor: grab;
    touch-action: none;             /* JS owns vertical gesture */
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .sheet-dismiss-grab:active { cursor: grabbing; }
  .sheet-dismiss-grab-bar {
    width: 44px;
    height: 5px;
    border-radius: 3px;
    background: #cbd5e1;
    pointer-events: none;
    transition: background 120ms ease, width 120ms ease;
  }
  .sheet-dismiss-grab:active .sheet-dismiss-grab-bar {
    background: var(--brand);
    width: 56px;
  }
}
@keyframes ps-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* =====================================================================
   Shop management sheet (.shop-sheet) — card-shop owner panel.
   Reuses .profile-sheet shell + adds content-specific styling.
===================================================================== */

/* Top store card (above menu) */
.shop-storecard {
  margin: 8px 16px 0;
  padding: 14px 16px;
  background: linear-gradient(135deg, #DBEAFE, #EFF6FF);
  border: 1px solid #BFDBFE;
  border-radius: 12px;
}
.shop-storecard-name { font-size: 15px; font-weight: 700; color: var(--text-strong); }
.shop-storecard-addr { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.shop-storecard-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(37,99,235,0.20);
}
.shop-storecard-stats > div { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.shop-stat-num   { font-family: var(--f-mono); font-size: 18px; font-weight: 700; color: var(--brand); }
.shop-stat-label { font-size: 11px; color: var(--text-muted); }

/* Inventory toolbar */
.shop-inv-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px 16px 4px;
}
.shop-inv-toolbar input[type="search"] {
  flex: 1; min-width: 0;
  font: inherit;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  outline: none;
}
.shop-inv-toolbar input:focus { border-color: var(--brand); background: var(--surface); }
.shop-inv-instock { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-muted); cursor: pointer; }
.shop-inv-instock input { accent-color: var(--brand); }

/* Inventory list */
.shop-inv-list { list-style: none; padding: 8px 16px 4px; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.shop-inv-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.shop-inv-img {
  width: 64px; height: 64px;
  object-fit: contain;
  border-radius: 8px;
  background: #fff;
  border: 1px solid var(--border);
  display: block;
}
.shop-inv-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  color: var(--text-muted);
}
.shop-inv-meta { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.shop-inv-name {
  font-size: 13.5px; font-weight: 700;
  color: var(--text-strong);
  word-break: break-word;
}
.shop-inv-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.shop-tag {
  display: inline-flex; align-items: center;
  font-size: 10.5px; font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  letter-spacing: 0.02em;
}
.shop-tag--ghost {
  background: var(--surface-soft);
  color: var(--text-strong);
  border: 1px solid var(--border);
  font-weight: 500;
}
.shop-tag--news { background: #0F172A; color: #fff; }
.shop-tag--status        { background: rgba(100,116,139,0.18); color: #475569; }
.shop-tag--ample         { background: rgba(34,197,94,0.18);   color: #166534; }
.shop-tag--normal        { background: rgba(37,99,235,0.16);   color: #1E40AF; }
.shop-tag--low           { background: rgba(234,179,8,0.18);   color: #854D0E; }
.shop-tag--sold_out      { background: rgba(239,68,68,0.16);   color: #991B1B; }
.shop-tag--incoming      { background: rgba(6,182,212,0.18);   color: #155E75; }
.shop-tag--preorder      { background: rgba(250,204,21,0.20);  color: #854D0E; }

.shop-inv-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin-top: 4px;
}
.shop-step {
  font: inherit;
  font-weight: 700;
  font-size: 11.5px;
  padding: 5px 8px;
  min-width: 30px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  color: var(--text-strong);
  font-family: var(--f-mono);
}
.shop-step:hover { background: var(--surface-soft); }
.shop-stock {
  font: inherit;
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: 13px;
  width: 56px;
  text-align: center;
  padding: 5px 4px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-soft);
  outline: none;
  -moz-appearance: textfield;
}
.shop-stock::-webkit-outer-spin-button,
.shop-stock::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.shop-stock:focus { border-color: var(--brand); background: var(--surface); }
.shop-soldout {
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  color: var(--text-strong);
  margin-left: auto;
}
.shop-soldout.is-on { background: #DC2626; color: #fff; border-color: #DC2626; }
.shop-soldout:hover:not(.is-on) { background: var(--surface-soft); }
.shop-delete {
  font: inherit;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
}
.shop-delete:hover { color: #DC2626; background: rgba(239,68,68,0.08); }

/* Price row under quantity controls */
.shop-inv-price-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
}
.shop-inv-price-label {
  font-size: 11px; font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.shop-price {
  font: inherit;
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 700;
  width: 110px;
  text-align: right;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-soft);
  outline: none;
  -moz-appearance: textfield;
}
.shop-price::-webkit-outer-spin-button,
.shop-price::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.shop-price:focus { border-color: var(--brand); background: var(--surface); }
.shop-inv-price-unit {
  font-size: 11px;
  color: var(--text-muted);
}

/* Custom-add 2-column row (qty + price) */
.ps-form-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* Catalog */
.shop-cat-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px 4px;
}
.shop-cat-toolbar input[type="search"] {
  flex: 1; min-width: 0;
  font: inherit;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  outline: none;
}
.shop-cat-toolbar input:focus { border-color: var(--brand); background: var(--surface); }
.shop-cat-count { font-size: 11px; color: var(--text-muted); white-space: nowrap; }

.shop-cat-grid {
  list-style: none; padding: 8px 16px 4px; margin: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.shop-cat-card {
  position: relative;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.shop-cat-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: #fff;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.shop-cat-img--placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 32px;
  color: var(--text-muted);
}
.shop-cat-name {
  font-size: 12px; font-weight: 700;
  color: var(--text-strong);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.shop-cat-series { font-size: 10.5px; color: var(--text-muted); }
.shop-cat-actions { display: flex; gap: 4px; flex-wrap: wrap; margin-top: auto; }
.shop-cat-add {
  font-size: 11px !important;
  padding: 5px 10px !important;
}
.shop-cat-added {
  font-size: 10.5px;
  color: #166534;
  background: rgba(34,197,94,0.14);
  padding: 4px 8px;
  border-radius: 6px;
  text-align: center;
  font-weight: 700;
}

/* News */
.shop-news-toolbar { padding: 12px 16px 4px; }
.shop-news-list { list-style: none; padding: 8px 16px 4px; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.shop-news-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.shop-news-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 11px;
}
.shop-news-date { color: var(--text-muted); font-family: var(--f-mono); }
.shop-news-public {
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--surface-soft);
  color: var(--text-muted);
  border: 1px solid var(--border);
  margin-left: auto;
}
.shop-news-public.is-public { background: rgba(34,197,94,0.16); color: #166534; border-color: rgba(34,197,94,0.4); }
.shop-news-title { font-size: 14px; font-weight: 700; color: var(--text-strong); }
.shop-news-body { font-size: 12.5px; color: var(--text-strong); line-height: 1.5; }
.shop-news-img {
  width: 100%; max-height: 180px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
}
.shop-news-actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 4px;
}
.shop-news-actions .ps-btn {
  font-size: 11.5px !important;
  padding: 6px 12px !important;
}
.shop-news-actions .shop-news-del { color: #B91C1C !important; }

/* Mobile-specific tweaks */
@media (max-width: 768px) {
  .shop-cat-grid { grid-template-columns: repeat(2, 1fr); }
  .shop-inv-controls { gap: 3px; }
  .shop-step { min-width: 28px; padding: 4px 6px; font-size: 11px; }
  .shop-stock { width: 48px; font-size: 12px; }
  .shop-soldout { font-size: 11px; padding: 4px 8px; }
}

/* =====================================================================
   Google AdSense slot scaffold.
   - Production default: ALL ad slots hidden (display:none, no UI space taken).
   - Visibility opt-in via body[data-ads]:
       data-ads="real"        — real AdSense markup rendered (window.POKAMAP_AD_CONFIG)
       data-ads="on"          — dev placeholder boxes (POKAMAP_SHOW_AD_PLACEHOLDERS / ?ads=1)
   - Per-device gating: desktop variants only on >768px, mobile only on ≤768px.
   - z-index stays below mobile bottom-nav (40) and FAB (30) so ads never
     block map interactions; pointer-events:none on map-bottom slots.
===================================================================== */

.ad-slot {
  /* Production default: collapsed completely — no flash, no reserved space. */
  display: none;
  align-items: center;
  justify-content: center;
  background: #F3F4F6;
  border: 1px dashed #CBD5E1;
  color: #94A3B8;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 6px;
  user-select: none;
  pointer-events: auto;
  font-family: var(--f-sans);
}
.ad-slot-label { font-size: 10.5px; font-weight: 700; }

/* ----- Variants (sizing only — visibility gated by body[data-ads] below) ----- */
.ad-slot--desktop-horizontal {
  width: 728px; height: 90px; max-width: calc(100% - 32px);
  margin: 8px auto;
}
.ad-slot--desktop-detail {
  width: 100%; min-height: 90px; max-height: 96px;
  margin: 8px 0 0;
}
.ad-slot--desktop-rect {
  width: 300px; height: 250px; max-width: 100%;
  margin: 12px auto 16px;
}
.ad-slot--mobile-banner {
  width: 320px; height: 50px; max-width: calc(100vw - 32px);
  margin: 0 auto;
}
.ad-slot--mobile-rect {
  width: 100%; max-width: 320px; aspect-ratio: 6 / 5;
  margin: 12px auto 16px;
}

/* ----- Visibility gate ----- */
/* Desktop (>768px): show desktop variants only when body[data-ads] is set. */
body[data-ads] .ad-slot--desktop-horizontal,
body[data-ads] .ad-slot--desktop-detail,
body[data-ads] .ad-slot--desktop-rect { display: flex; }

/* Mobile (≤768px): show mobile variants only when body[data-ads] is set;
   desktop variants stay hidden. */
@media (max-width: 768px) {
  body[data-ads] .ad-slot--desktop-horizontal,
  body[data-ads] .ad-slot--desktop-detail,
  body[data-ads] .ad-slot--desktop-rect { display: none; }
  body[data-ads] .ad-slot--mobile-banner,
  body[data-ads] .ad-slot--mobile-rect { display: flex; }
}

/* ----- Map-bottom slots (positioned over the map viewport) ----- */
.ad-slot--map-bottom {
  position: absolute;
  z-index: 11;                          /* above attribution (10), below FAB (30) */
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;                 /* ad placeholder doesn't block map clicks */
}
.ad-slot--map-bottom .ad-slot-label { pointer-events: auto; }
/* Desktop: center within the visible map strip. Sidebar / detail open layouts
   shift the strip's left edge — use left+right anchors so margin:auto centers
   the fixed-width 728px banner correctly. */
@media (min-width: 1024px) {
  .ad-slot--desktop-horizontal.ad-slot--map-bottom {
    bottom: 20px;
    left: var(--rail-w, 80px);
    right: 0;
    transform: none;
    margin: 0 auto;
  }
  .map-shell[data-layout="rail-list"] .ad-slot--desktop-horizontal.ad-slot--map-bottom,
  .map-shell[data-layout="rail-list-detail"] .ad-slot--desktop-horizontal.ad-slot--map-bottom {
    left: calc(var(--rail-w, 80px) + var(--list-w, 380px));
  }
}

/* Mobile map-bottom: sit above the bottom nav, with FAB pushed up by
   --mobile-ad-h ONLY when ads are actually rendered. Default 0px → no shift
   in production. Hidden when a sheet is at FULL state (over opaque sheet). */
@media (max-width: 768px) {
  .ad-slot--mobile-banner.ad-slot--map-bottom {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + 8px);
    z-index: 11;
    transition: bottom 220ms cubic-bezier(.2,.7,.2,1);
  }
  /* Sheet-full hide (only matters when ad is showing). */
  body[data-ads] .map-detail[data-open="true"][data-sheet-state="full"] ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="category"] ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="search"]   ~ .ad-slot--mobile-banner.ad-slot--map-bottom,
  body[data-ads] .map-sidebar[data-sheet-state="full"][data-mode="detail"]   ~ .ad-slot--mobile-banner.ad-slot--map-bottom {
    display: none;
  }

  /* Default: 0px (no FAB shift in production). Opt-in to 66px only when ads
     are actually showing. 66px = 50px banner + 16px gap. */
  .map-shell { --mobile-ad-h: 0px; }
  body[data-ads] .map-shell { --mobile-ad-h: 66px; }
  .map-shell .map-fab {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + var(--mobile-ad-h, 0px)) !important;
  }
  .map-status {
    bottom: calc(var(--mobile-overlay-bottom, 72px) + var(--mobile-ad-h, 0px)) !important;
  }
}
