/* EOR Floor Plans — palette taken from the official Eye of Riyadh logo
   artwork: #F9A71D amber, #00BDF2 cyan, #231F20 charcoal. */

:root {
  --eor-amber: #F9A71D;
  --eor-amber-light: #FCB116;
  --eor-amber-dark: #C97F04;
  --eor-cyan: #00BDF2;
  --eor-cyan-dark: #0C7FA8;
  --eor-charcoal: #231F20;

  --bg: #EFEFF1;
  --card: #FFFFFF;
  --border: #E3E3E6;
  --border-strong: #D2D2D6;
  --text: #231F20;
  --muted: #78787E;

  --radius: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 1px 2px rgba(35, 31, 32, 0.06);
  --shadow: 0 2px 12px rgba(35, 31, 32, 0.09);
  --shadow-lg: 0 12px 34px rgba(35, 31, 32, 0.20);
  --topbar-h: 62px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
body { display: flex; flex-direction: column; overflow: hidden; }

button, input, select, textarea { font-family: inherit; }
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--eor-cyan);
  outline-offset: 1px;
}

/* ================= Topbar ================= */

.topbar {
  flex: none;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 0 20px;
  background: var(--card);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(249, 167, 29, 0.9), var(--shadow-sm);
  position: relative;
  z-index: 60;
}

.brand {
  display: flex; align-items: center; gap: 14px; flex: none;
  border: none; background: none; padding: 4px 6px; margin: -4px -6px;
  border-radius: var(--radius-sm); cursor: pointer; text-align: left;
  font: inherit; color: inherit;
  transition: background .13s ease, transform .1s ease;
}
.brand:hover { background: rgba(249, 167, 29, 0.1); }
.brand:active { transform: scale(0.98); }
.brand-logo { height: 30px; width: auto; flex: none; }
.brand-rule { width: 1px; height: 26px; background: var(--border-strong); flex: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1.25; white-space: nowrap; }
.brand-text strong { font-size: 14.5px; letter-spacing: -0.015em; }
.brand-text span { font-size: 10.5px; color: var(--muted); letter-spacing: 0.01em; }

.plan-picker { display: flex; align-items: center; gap: 9px; }
.plan-picker > span {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--muted); font-weight: 700;
}
.plan-picker select {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 8px 30px 8px 12px;
  font-size: 13px; font-weight: 600;
  background: var(--card);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='7'><path d='M1 1l4 4 4-4' stroke='%2378787E' stroke-width='1.6' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 11px center;
  color: var(--text);
  min-width: 232px;
  appearance: none;
  cursor: pointer;
}
.plan-picker select:hover { border-color: var(--eor-amber); }

.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 7px; }

/* --- save status --- */
.save-status {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 700;
  padding: 0 10px 0 4px;
  white-space: nowrap;
}
.save-status::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; flex: none;
  transition: background .15s ease;
}
.save-status.ok { color: #4C8C3A; }
.save-status.ok::before { background: #4C8C3A; }
/* Settles to a quiet dot a moment after saving, so it isn't shouting
   "Saved" after every keystroke — the dot alone is the reassurance. */
.save-status.ok.quiet { color: var(--muted); }
.save-status.ok.quiet::before { background: #9AC98A; }
.save-status.error { color: #C0392B; cursor: help; }
.save-status.error::before { background: #C0392B; }

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

.btn {
  border: none; border-radius: var(--radius-sm);
  padding: 8px 13px; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: background .14s ease, border-color .14s ease, transform .1s ease;
}
.btn:active { transform: scale(0.96); }
.btn-block { width: 100%; }
.btn-icon { display: inline-flex; flex: none; }

/* Shared tactile press feedback for every icon-only control (remove, move,
   clear, close, add) — one rule instead of repeating :active on each. */
.g-move, .g-remove, .find-clear, .pop-close, .tier-add-btn, .sponsor-tab {
  transition-property: color, background, opacity, transform;
  transition-duration: .13s;
  transition-timing-function: ease;
}
.g-move:active, .g-remove:active, .find-clear:active,
.pop-close:active, .tier-add-btn:active, .sponsor-tab:active { transform: scale(0.88); }
.btn-secondary { background: #EAF7FC; color: var(--eor-cyan-dark); border: 1px solid #C9ECF8; }
.btn-secondary:hover { background: #D8F0FA; }
.btn-ghost { background: var(--card); color: var(--text); border: 1px solid var(--border-strong); }
.btn-ghost:hover { background: #F6F6F7; border-color: var(--muted); }
.btn-danger { background: #FDECEB; color: #C0392B; border: 1px solid #F6C8C3; }
.btn-danger:hover { background: #FBDBD8; }
.btn-danger-ghost { background: var(--card); color: #C0392B; border: 1px solid #F0C9C5; }
.btn-danger-ghost:hover { background: #FDECEB; }

#undo-btn { padding: 8px; }
#undo-btn:disabled { opacity: 0.35; cursor: not-allowed; }
#undo-btn:disabled:hover { background: var(--card); border-color: var(--border-strong); }

/* Official Saudi Riyal sign (U+20C1, Unicode 17 / Sept 2025). Embedded as a
   single-glyph webfont so it renders correctly regardless of whether the
   viewer's OS has caught up yet — font: emran-alhaddad/Saudi-Riyal-Font
   (open source), scoped to just this character via .sar-symbol so normal
   text and digits are unaffected. */
@font-face {
  font-family: 'SaudiRiyal';
  src: url(data:font/woff2;base64,d09GMgABAAAAAAT0AA0AAAAAC2QAAASeAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGhgGYACCZhEICocEhXcLGgABNgIkAzAEIAWHLgeBBRvVCSCOwnEvSojJ5ORhKiWep9/bPPc32mdnUaW+wXeJKlVIJCg8CIfcQWViVHSETJeZqNqErgZPp/28VaAy13pTkXvNQZv4IHCbHD9In+dyevP5Cfy7K+slmC3ybGwuLx2T18L1PKA2pnPbFCvQCdbLLSJq0N0AB31thACv29f9APD1k6ZUJ0tAD4aoQDO8bhmyFC1UI+oCuAO15AO2Q8G5MwSqDefwClCi9Be6wX9nQPsMEKAeA1AQUIMaLCGACzQCljAqQE+OwoCjcu0D6kv8/x/sl6sfkIpP/3/9/WpgdgoEQAeYoIR0QACkAlSghuJ31w3LAXyr/P+vAvSAOTCAzAK5B6CBQzRNhcGgGoYLL+dYrlnFKgu9iOcEj646uXaI2W3sJ9lTI4EetCRQAgulmH6SYMZBziQb1xBipCaQaS6l0vWRWr1q1aFDnTA52r1fr8fUTpXKWvLQ4KnSwb0+PppFHxtVC1at2uXrO9JOSIUWTzV+QWdXLT0K2uhG0jpJEiZs6WjSR9KuG9Zv1u+P2q1UujpcsT1L3dNzqhQszNevVtPHSYnHKlXoGEWtDpi6yX/duUgVJGGvzwIypcpt/Ni4Jly1atcq32n6zc+V4+ld7k6gz53h7vgOHLKN10L3KkUS7kouYUcPhGVony1zOi//ctkTdm/3kAqubk+P0MptoSFlXH1d5ZyIwuAyWX7+z+picypWzAjs1xCbVaGJLgqt5qqbqg/Y6ntEjm76aneF9Yjvano5HXrdrjSkllfHmVOk+o/IY8O89mBNc9Lbwcoe28z7DRmFzSmN4wbrT5X+B/E2SdMQn2S1PFaUu1OkJfIXKxVt+w1pFa2xjdll47yrvsvczl7/4ETotcmj56Zkzxs3b+7w0ZMNx9wX7srQ8rIsghhH+yj839cG7rwS/FVUQnWXgYUdjUP+HL5C8fybvBJ6ZQRWMKOhfsi7ZqHZEz4e3TZxMtEqXR8kGN0n/5/a9jk9IKKiFlmPtlWvYKy8rF34efCtxR9snP0uNWnu7Jj8kj9HHV1INdJDNT2jhozoFXwqYPLE+VjfWDBpsq7FUrJmU3brXPVwppI6gm8PCAjcX9RU3FdX8KtcJcczkIBc+4K9C8ZdxNPL/LtD9KcF19fLgOpBtODVPMNO+5d0/C2p2BEBPefddskgYA8Aa9mMABgKQwChUg9RkbGjprcJDW9v0SJ+QccrQRhDkk6Os7mYoEtPTCIZQk6xo9ALyCFMI3lIDtjnGFLlm9EzZJUcNNIoAAUACL10ULSMoCUYAkaUk2BRfgAnwm+QoZJMytlMKIQkH0pUBpAqdhjUMjIGGlTuklr2MTzoI92UJ23+wONVGmQ40WC8UgM5iCwsRBYopXLQcHEwXzrQIVosogW4IRrFwqmv4ZzGEQ2Em8tRFmff4c5x4kDgmpXdKAOJhsMnRWOAIg8/SVZ+YGXZ5ee18vMkZYbYopod2PHxMh22lbggxy4aiTp8UzunkRxGMUliNsQgyayTKk8k+l05RzpGmT7YjNb5FSWKKTxHRVTCPj0ISoRIUaJDEZowhCWctufXnHPwkJG/e0pZDQA=) format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
.sar-symbol {
  font-family: 'SaudiRiyal', "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* ================= App shell ================= */

.app-body {
  flex: 1;
  min-height: 0;
  display: flex;
}
/* Same [hidden]-vs-explicit-display fix as .under-construction below — this
   is the element that actually gets hidden when a plan is underConstruction. */
.app-body[hidden] { display: none; }

/* ================= Site-wide navigation ================= */

.site-nav {
  width: 250px;
  flex: none;
  background: var(--card);
  border-right: 1px solid var(--border);
  padding: 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  overflow-y: auto;
}

/* --- always-visible event summary, top of the sidebar --- */

.nav-event {
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.nav-event .event-logo { height: 40px; width: auto; max-width: 100%; margin-bottom: 10px; }
.nav-event .event-logo[hidden] { display: none; }
.nav-event h1 { margin: 0; font-size: 15.5px; font-weight: 700; line-height: 1.3; letter-spacing: -0.01em; }
.event-countdown {
  display: inline-block; margin-top: 8px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--eor-amber-dark); background: rgba(249, 167, 29, 0.15);
  border-radius: 20px; padding: 4px 10px;
}
.event-countdown[hidden] { display: none; }
.event-countdown.event-countdown-past { color: var(--muted); background: #F0F0F2; }
.nav-event .detail-list { margin: 12px 0 0; }

/* --- collapsible "Event Info" section --- */
/* The grid-rows 0fr/1fr trick animates height without JS measuring the
   content's scrollHeight — .collapsible-body-inner supplies the intrinsic
   height, the outer grid row just tweens between 0fr and 1fr, and the
   inner's own overflow:hidden clips it mid-transition. */
.collapsible { margin-top: 14px; }
.collapsible-toggle {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  border: none; background: none; cursor: pointer; padding: 0;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--eor-amber-dark); font-weight: 700;
}
.collapsible-toggle .chevron { transition: transform .2s ease; flex: none; }
.collapsible-toggle[aria-expanded="false"] .chevron { transform: rotate(-90deg); }
.collapsible-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows .22s ease;
}
.collapsible-body.collapsed { grid-template-rows: 0fr; }
.collapsible-body-inner { overflow: hidden; min-height: 0; }
.collapsible-body.collapsed .detail-list { margin-top: 0; }
.nav-event .detail-list div { padding: 6px 0; border-bottom: 1px solid #F0F0F2; }
.nav-event .detail-list dt { font-size: 8.5px; margin-bottom: 2px; }
.nav-event .detail-list dd { font-size: 12px; line-height: 1.4; }
.nav-event .price-block { margin-top: 12px; gap: 8px; }
.nav-event .price { padding: 10px 8px 11px; }
.nav-event .price-label { font-size: 9px; margin-bottom: 4px; }
.nav-event .price b { font-size: 20px; }

/* ================= Main content ================= */

/* --- the three top-level destinations, a horizontal strip above the
   mode toggle/search bar --- */
.nav-zones { flex: none; display: flex; gap: 4px; position: relative; }
.nav-indicator {
  position: absolute; top: 0; bottom: 0; left: 0;
  background: var(--eor-charcoal); border-radius: 8px;
  transition: transform .24s cubic-bezier(.34, 1.3, .64, 1), width .24s cubic-bezier(.34, 1.3, .64, 1);
  z-index: 0;
}
.nav-item {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 7px;
  border: none; background: none;
  padding: 9px 16px; border-radius: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--text);
  cursor: pointer;
  transition: color .13s ease, transform .12s ease;
}
.nav-item svg { flex: none; }
.nav-item:hover { color: var(--eor-amber-dark); }
.nav-item:active { transform: scale(0.96); }
.nav-item.active { color: #fff; }
.nav-item.active:hover { color: #fff; }

.app-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
}

.content-toolbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 9px 12px;
  flex-wrap: wrap;
}
.content-toolbar[hidden] { display: none; }

/* --- mode toggle: the Seating Chart/Guest List (or Booth Map/Sponsors)
   switch within whichever zone is active, sat left of Find --- */
.mode-toggle {
  display: flex; gap: 2px; flex: none; position: relative;
  background: #F0F0F2; border-radius: var(--radius-sm); padding: 3px;
}
.mode-toggle[hidden] { display: none; }
.mode-indicator {
  position: absolute; top: 3px; bottom: 3px; left: 0;
  background: var(--card); border-radius: 6px; box-shadow: var(--shadow-sm);
  transition: transform .22s cubic-bezier(.34, 1.3, .64, 1), width .22s cubic-bezier(.34, 1.3, .64, 1);
  z-index: 0;
}
.mode-btn {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  border: none; background: none; cursor: pointer;
  padding: 6px 13px; border-radius: 6px;
  font-size: 12px; font-weight: 700; color: var(--muted);
  white-space: nowrap;
  transition: color .13s ease, transform .12s ease;
}
.mode-btn svg { flex: none; }
.mode-btn:active { transform: scale(0.96); }
.mode-btn.active { color: var(--eor-charcoal); }

.find-guest { position: relative; flex: 1; min-width: 200px; max-width: 340px; }
.find-guest input {
  width: 100%;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 8px 74px 8px 32px;
  font-size: 12.5px;
  background: var(--card);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><circle cx='5.5' cy='5.5' r='4' stroke='%2378787E' stroke-width='1.5' fill='none'/><path d='M8.7 8.7L12 12' stroke='%2378787E' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: left 10px center;
  appearance: none;
}
/* The native clear button is unreliable to hit and doesn't restyle, so it is
   replaced with .find-clear below. */
.find-guest input::-webkit-search-cancel-button,
.find-guest input::-webkit-search-decoration { -webkit-appearance: none; display: none; }

.find-count {
  position: absolute; right: 30px; top: 50%; transform: translateY(-50%);
  font-size: 10.5px; font-weight: 700; color: var(--eor-amber-dark);
  pointer-events: none; white-space: nowrap;
}
.find-clear {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 20px; height: 20px; padding: 0;
  border: none; border-radius: 50%;
  background: #E6E6E9; color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.find-clear:hover { background: var(--eor-charcoal); color: #fff; }
.find-clear[hidden] { display: none; }

/* --- stat tiles with inline bars --- */

.stats { display: flex; gap: 8px; margin-left: auto; flex: none; }
.stat {
  background: #F7F7F8;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 12px 8px;
  min-width: 126px;
}
.stat.stat-simple { min-width: 84px; }
.stat-label {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px;
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--muted); font-weight: 700;
  margin-bottom: 2px;
}
.stat-pct { color: var(--eor-amber-dark); }
.stat b { display: block; font-size: 15px; line-height: 1.2; color: var(--eor-charcoal); font-weight: 700; }
.stat b i { font-style: normal; font-size: 11px; font-weight: 600; color: var(--muted); }
.stat-bar {
  margin-top: 5px; height: 4px; border-radius: 2px;
  background: #E2E2E6; overflow: hidden;
}
.stat-bar span {
  display: block; height: 100%; border-radius: 2px;
  background: var(--eor-amber);
  transition: width .2s ease;
}
.stat-bar.cyan span { background: var(--eor-cyan); }

/* ================= Section panels (Guest List / Sponsors / Conference) === */

.section-panel { display: none; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }
.section-panel.active { display: flex; animation: fade-in-up .2s ease; }

@keyframes fade-in-up {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- Conference: not built yet, same visual language as the whole-event
   Under Construction page, just scoped to this one panel --- */
.zone-placeholder {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
  padding: 40px;
  text-align: center;
  color: var(--muted);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.zone-placeholder h2 { margin: 0; font-size: 18px; color: var(--eor-charcoal); letter-spacing: -0.01em; }
.zone-placeholder p { margin: 0; font-size: 13px; max-width: 340px; }

/* ================= Timeline (run of show) ================= */

.timeline-current {
  flex: none;
  background: var(--eor-charcoal);
  color: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px;
}
.timeline-current-empty { font-size: 13px; color: rgba(255,255,255,0.75); }
.timeline-current-empty strong { color: var(--eor-amber); }
.timeline-current-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--eor-amber); font-weight: 700; margin-bottom: 3px;
}
.timeline-current-title { font-size: 17px; font-weight: 700; margin-bottom: 4px; }
.timeline-current-meta { font-size: 12px; color: rgba(255,255,255,0.7); margin-bottom: 12px; }
.timeline-current .btn { width: auto; }

.timeline-toolbar { flex: none; display: flex; justify-content: flex-end; }

.timeline-list {
  flex: 1; min-height: 0; overflow-y: auto;
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.timeline-empty { padding: 18px 12px; font-size: 12px; color: var(--muted); font-style: italic; }

.timeline-row {
  display: grid;
  grid-template-columns: 16px 52px 1fr 40px 72px auto;
  align-items: center; gap: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  padding: 9px 12px;
  cursor: pointer;
}
.timeline-row.dragging { opacity: 0.4; }
.timeline-row.drag-over { border-color: var(--eor-amber); box-shadow: 0 0 0 3px rgba(249, 167, 29, 0.35); }
.timeline-row.status-current { border-color: var(--eor-amber-dark); background: rgba(249, 167, 29, 0.08); }
.timeline-row.status-done { opacity: 0.55; }
.timeline-grip { color: var(--muted); cursor: grab; display: flex; }
.timeline-time { font-weight: 700; font-size: 12.5px; color: var(--eor-charcoal); white-space: nowrap; }
.timeline-body strong { display: block; font-size: 13px; }
.timeline-body small { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }
.timeline-duration { font-size: 11px; color: var(--muted); white-space: nowrap; }
.timeline-status {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
  color: var(--muted); white-space: nowrap; text-align: right;
}
.timeline-row.status-current .timeline-status { color: var(--eor-amber-dark); }
.timeline-row .g-move {
  border: none; background: none; color: var(--muted);
  cursor: pointer; padding: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; flex: none;
}
.timeline-row .g-move:hover { color: var(--eor-cyan-dark); background: #EAF7FC; }

/* ================= Screens (venue signage inventory) ================= */
/* Reuses .timeline-list/.timeline-toolbar/.timeline-empty/.timeline-grip
   directly (same "add + drag-reorderable list + popover" shape as the
   Agenda) — only the row's own columns differ. */

.screen-row {
  display: grid;
  grid-template-columns: 16px 1fr 1fr 90px;
  align-items: center; gap: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  padding: 9px 12px;
  cursor: pointer;
}
.screen-row.dragging { opacity: 0.4; }
.screen-row.drag-over { border-color: var(--eor-amber); box-shadow: 0 0 0 3px rgba(249, 167, 29, 0.35); }
.screen-body strong { display: block; font-size: 13px; }
.screen-body small { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }
.screen-content-type {
  display: inline-block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 700; color: var(--eor-cyan-dark); background: #EAF7FC;
  border-radius: 20px; padding: 2px 8px;
}
.screen-content small { display: block; color: var(--muted); font-size: 11px; margin-top: 3px; }
.screen-instance-badge {
  display: inline-block; margin-left: 5px; font-size: 10px; font-weight: 700;
  color: var(--eor-amber-dark); background: rgba(249, 167, 29, 0.15);
  border-radius: 20px; padding: 2px 7px;
}
.screen-status {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
  white-space: nowrap; text-align: right;
  color: var(--muted);
}
.screen-row.status-active .screen-status { color: #4C8C3A; }
.screen-row.status-needs-update .screen-status { color: var(--eor-amber-dark); }
.screen-row.status-offline .screen-status { color: #C0392B; }

.screen-video-link {
  font-size: 11px; font-weight: 700; color: var(--eor-cyan-dark);
  text-decoration: none; white-space: nowrap;
}
.screen-video-link:hover { text-decoration: underline; }
.screen-video-link.muted { color: var(--muted); font-weight: 400; cursor: default; pointer-events: none; }

/* Content library — a catalog, not a sequence, so no grip/drag column
   (contrast with .screen-row, which is reorderable). */
.content-row {
  display: grid;
  grid-template-columns: 1fr 140px 100px;
  align-items: center; gap: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  padding: 9px 12px;
  cursor: pointer;
}
.content-body strong { display: block; font-size: 13px; }
.content-body small { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }

/* Screens List, grouped by screen type (Stage/Display/Mobile) — each group
   is its own header + "Add" button + sub-list, rather than one flat list
   with a type column. */
.screens-group { margin-bottom: 18px; }
.screens-group:last-child { margin-bottom: 0; }
.screens-group-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.screens-group-head h4 {
  margin: 0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--eor-amber-dark); font-weight: 700;
}
.btn-small { padding: 5px 10px; font-size: 12px; width: auto; }

/* Embedded Agenda editor inside the Screen popover — same shape as
   .pop-guests (the table popover's guest list), just with a video-link
   column and a remove button instead of move/company. */
.agenda-item-row {
  display: grid;
  grid-template-columns: 16px 1fr 50px 24px;
  align-items: center; gap: 8px;
  padding: 7px 4px;
  border-bottom: 1px solid var(--border);
}
.agenda-item-row:last-child { border-bottom: none; }
.agenda-item-row.dragging { opacity: 0.4; }
.agenda-item-row.drag-over { outline: 1.5px dashed var(--eor-amber); outline-offset: -1px; }
.agenda-item-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.agenda-item-body strong { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pop-subhead {
  margin: 4px 12px 6px; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); font-weight: 700;
}
.screens-pop-agenda[hidden] { display: none; }
.screens-pop-agenda { border-top: 1px dashed var(--border); padding-top: 8px; }
.screens-pop-agenda .pop-guests { max-height: 160px; overflow-y: auto; margin: 0 12px; }
.screens-pop-duplicate[hidden] { display: none; }
.screens-pop-duplicate { padding: 0 12px 10px; }
.screens-pop-agenda-add { padding: 0 12px 10px; }
/* "+ Add content" reveals this picker rather than the popover always
   showing a select — keeps the resting state down to just the list and
   the one button. */
.screens-pop-agenda-picker[hidden] { display: none; }
.screens-pop-agenda-picker { display: flex; gap: 6px; margin-top: 8px; }
.screens-pop-agenda-picker select { flex: 1; min-width: 0; }
.screens-pop-agenda-picker .btn { flex: none; width: auto; padding: 7px 10px; }

/* Branding's artwork preview — just an <img> pointed at whatever URL is
   currently typed; a broken/non-image link hides the <img> (see the
   `error` listener in app.js) but the "View artwork" link stays, since a
   PDF/.ai file still opens fine even though it can't preview inline. */
.branding-pop-artwork-preview[hidden] { display: none; }
.branding-pop-artwork-preview {
  margin: 0 12px 12px;
  padding: 10px;
  background: #F6F6F7;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.branding-pop-artwork-preview img {
  max-width: 100%; max-height: 160px;
  border-radius: 4px;
  object-fit: contain;
}
.branding-pop-artwork-preview a {
  font-size: 12px; font-weight: 700; color: var(--eor-cyan-dark); text-decoration: none;
}
.branding-pop-artwork-preview a:hover { text-decoration: underline; }

.event-logo {
  height: 52px; width: auto; max-width: 100%;
  margin-bottom: 16px;
}
.event-logo[hidden] { display: none; }

.detail-list { margin: 18px 0 0; }
.detail-list div { padding: 10px 0; border-bottom: 1px solid #F0F0F2; }
.detail-list div:last-child { border-bottom: none; }
.detail-list dt {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--muted); font-weight: 700; margin-bottom: 3px;
}
.detail-list dd { margin: 0; font-size: 13.5px; line-height: 1.5; }

/* --- click-to-edit affordance, shared by every Event Details field --- */

.editable-field {
  cursor: text;
  border-radius: 5px;
  margin: -3px -5px;
  padding: 3px 5px;
  transition: background .12s ease;
}
.editable-field:hover {
  background: rgba(0, 189, 242, 0.08);
  box-shadow: inset 0 0 0 1px rgba(0, 189, 242, 0.25);
}
.editable-field:hover::after {
  content: '';
  display: inline-block;
  width: 11px; height: 11px;
  margin-left: 6px;
  vertical-align: -1.5px;
  opacity: 0.8;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230C7FA8' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><path d='M12 20h9'/><path d='M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z'/></svg>") no-repeat center / contain;
}
.editable-field:empty::before { content: '—'; color: var(--muted); }
.editable-field input.inline-edit {
  all: unset;
  display: block;
  width: 100%;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  border-bottom: 1.5px solid var(--eor-cyan);
  background: rgba(0, 189, 242, 0.06);
  padding: 1px 2px;
}

.price-block {
  margin-top: 20px;
  display: grid; grid-template-columns: 1fr; grid-auto-rows: max-content; gap: 12px;
}
.price {
  background: var(--eor-charcoal);
  border-radius: var(--radius-sm);
  padding: 16px 12px 17px;
  text-align: center;
}
/* The label is the eyebrow now — amber, bold, a bit of "pop" — and the
   number itself is what a price actually looks like in a real UI: large,
   heavy, high-contrast, not a 14px afterthought. */
.price-label {
  display: block;
  font-size: 11.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--eor-amber);
  margin-bottom: 6px;
}
.price b {
  display: block; color: #fff;
  font-size: 32px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.1;
}
/* Price tiles sit on the dark charcoal fill, so the edit affordance needs
   its own, lighter contrast rather than the sidebar's default cyan-on-white. */
.price .editable-field:hover {
  background: rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 0 0 1px rgba(0, 189, 242, 0.5);
}
.price .editable-field:hover::after { color: var(--eor-cyan); }
.price .editable-field input.inline-edit {
  background: rgba(255, 255, 255, 0.12);
  border-bottom-color: var(--eor-cyan);
  font-size: inherit;
}

/* --- floor plan properties --- */

.tool-group h3, .tool-group h4 {
  margin: 0 0 10px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--eor-amber-dark); font-weight: 700;
}

/* Sits above the whole widget (both tool-groups in Floor Plan settings, or
   the single one in Booth Types) — one step up in the hierarchy from the
   .tool-group headings above, so it's larger/darker rather than the same
   amber-uppercase style, or the two levels would read as equal weight. */
.widget-title {
  margin: 0; font-size: 13px; font-weight: 700; color: var(--eor-charcoal);
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.hint { font-size: 11.5px; color: var(--muted); margin: 12px 0; line-height: 1.5; }

.slider { display: block; margin-bottom: 12px; font-size: 11.5px; color: var(--muted); }
.slider > span { display: flex; justify-content: space-between; margin-bottom: 4px; }
.slider b { color: var(--text); font-weight: 700; }
.slider input[type="range"] { width: 100%; accent-color: var(--eor-amber); }

.check {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--muted);
  margin-top: 14px; cursor: pointer;
}
.check input { accent-color: var(--eor-cyan); }
.seat-reserve { margin: 0 0 6px; font-size: 11.5px; }

.overflow-warn {
  margin: 10px 0 0;
  background: #FFF6E6;
  border: 1px solid #F5D9A0;
  border-left: 3px solid var(--eor-amber);
  border-radius: 7px;
  padding: 8px 10px;
  font-size: 11px; line-height: 1.5; color: #8A6100;
}
.overflow-warn[hidden] { display: none; }

/* --- Floor Plan / Booth Types widgets: sidebar cards, shown only while
   viewing the matching zone/mode (Award Gala's Seating Chart, or the
   Booth Map) — sit in the sidebar's normal flow, not floating over the
   chart, so both live under .site-nav in index.html. --- */
.nav-widget {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 15px;
  display: flex; flex-direction: column; gap: 16px;
}
.nav-widget[hidden] { display: none; }
.nav-widget .detail-list { margin: 0; }
.nav-widget .detail-list div { padding: 6px 0; }
.nav-widget .detail-list dt { font-size: 8.5px; margin-bottom: 2px; }
.nav-widget .detail-list dd { font-size: 11.5px; line-height: 1.4; }

/* --- booth type legend: colour swatch + tier name/size/height + a large
   count, the number organisers actually scan for --- */
.booth-type-list { display: flex; flex-direction: column; gap: 12px; }
.booth-type-row { display: flex; align-items: center; gap: 10px; }
.booth-type-swatch {
  width: 13px; height: 13px; border-radius: 3px; flex: none;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.booth-type-info { flex: 1; min-width: 0; }
.booth-type-row strong { display: block; font-size: 11.5px; line-height: 1.4; }
.booth-type-row small { display: block; font-size: 10px; color: var(--muted); line-height: 1.4; }
.booth-type-count {
  flex: none;
  font-size: 11.5px; font-weight: 700; color: var(--eor-charcoal);
  line-height: 1.4;
  min-width: 16px; text-align: right;
}

/* ================= Shared floor-plan viewport (Seating Chart + Booth Map) === */

.chart-viewport {
  position: relative;
  flex: 1;
  min-height: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 12px;
}
.chart-viewport[hidden] { display: none; }
.chart-viewport:not([hidden]) { animation: fade-in-up .2s ease; }

.chart-canvas { position: relative; flex: none; }

#plan-image {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  user-select: none; pointer-events: none;
}
#plan-image[hidden] { display: none; }

.image-missing {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 40px;
  color: var(--muted); font-size: 13px; line-height: 1.6;
  background: repeating-linear-gradient(45deg, #fafafa, #fafafa 10px, #f2f2f2 10px, #f2f2f2 20px);
}
.image-missing[hidden] { display: none; }

/* Which overlay layer is visible depends on the active zone/mode — all live
   permanently in the DOM so there's only one viewport/zoom-fit to manage. */
#aisle-layer, #tables-layer, #booths-layer, #conference-layer, #screens-layer, #screen-zones-layer, #branding-layer { display: none; }
.app-content[data-zone="gala"][data-mode="chart"] #aisle-layer,
.app-content[data-zone="gala"][data-mode="chart"] #tables-layer { display: block; }
.app-content[data-zone="booths"][data-mode="map"] #booths-layer { display: block; }
.app-content[data-zone="conference"][data-mode="chart"] #conference-layer { display: block; }
.app-content[data-zone="screens"][data-mode="map"] #screens-layer,
.app-content[data-zone="screens"][data-mode="map"] #screen-zones-layer,
.app-content[data-zone="branding"][data-mode="map"] #branding-layer,
.app-content[data-zone="branding"][data-mode="map"] #screen-zones-layer { display: block; }

/* On the Seating Chart, the booths are just spatial context for where the
   sponsor hall sits relative to the tables — a faint, read-only backdrop,
   not a second interactive layer. Booth tier colour/border are normally set
   inline per-node in renderBooths(), so overriding them here needs
   `!important`; a single flat gray replaces "which tier" with "there are
   booths here" as the only signal, and pointer-events:none drops
   hover/click/the popover outright rather than requiring a separate render
   path. (Table nodes still stack above: they carry an explicit z-index,
   booth nodes don't, and a positive z-index always wins over the
   auto/DOM-order stack regardless of which layer comes later in the
   markup.) */
.app-content[data-zone="gala"][data-mode="chart"] #booths-layer {
  display: block;
  opacity: 0.2;
  pointer-events: none;
}
.app-content[data-zone="gala"][data-mode="chart"] #booths-layer .booth-node {
  background: #9A9A9E !important;
  border-color: transparent !important;
  cursor: default;
}

/* Same faint-backdrop idiom, the other two directions: booths show as
   spatial context on the Conference chart, and conference seats show as
   spatial context on the Booth Map — same reasoning either way (where does
   this other area sit relative to what I'm actually editing), same
   read-only treatment (gray, low opacity, no hover/click/popover). */
.app-content[data-zone="conference"][data-mode="chart"] #booths-layer {
  display: block;
  opacity: 0.2;
  pointer-events: none;
}
.app-content[data-zone="conference"][data-mode="chart"] #booths-layer .booth-node {
  background: #9A9A9E !important;
  border-color: transparent !important;
  cursor: default;
}
.app-content[data-zone="booths"][data-mode="map"] #conference-layer {
  display: block;
  opacity: 0.3;
  pointer-events: none;
}
.app-content[data-zone="booths"][data-mode="map"] #conference-layer .seat-node {
  background: #9A9A9E !important;
  border-color: transparent !important;
  cursor: default;
}

/* Screens/Branding Floor Plan both need both other layers as spatial
   context at once — same faint read-only backdrop idiom, just two layers
   together instead of one, since a marker's placement is meaningless
   without knowing where the booths and the seating both sit. */
.app-content[data-zone="screens"][data-mode="map"] #booths-layer,
.app-content[data-zone="branding"][data-mode="map"] #booths-layer {
  display: block;
  opacity: 0.2;
  pointer-events: none;
}
.app-content[data-zone="screens"][data-mode="map"] #booths-layer .booth-node,
.app-content[data-zone="branding"][data-mode="map"] #booths-layer .booth-node {
  background: #9A9A9E !important;
  border-color: transparent !important;
  cursor: default;
}
.app-content[data-zone="screens"][data-mode="map"] #conference-layer,
.app-content[data-zone="branding"][data-mode="map"] #conference-layer {
  display: block;
  opacity: 0.3;
  pointer-events: none;
}
.app-content[data-zone="screens"][data-mode="map"] #conference-layer .seat-node,
.app-content[data-zone="branding"][data-mode="map"] #conference-layer .seat-node {
  background: #9A9A9E !important;
  border-color: transparent !important;
  cursor: default;
}

/* Clicking anywhere on the plan in this mode drops a new item right
   there (see the canvas click listeners in app.js) — crosshair signals
   "click to place", overridden back to grab/grabbing (Screens) or the
   resize cursor (Branding) on the markers themselves so an existing item
   still reads as draggable, not placeable. */
.app-content[data-zone="screens"][data-mode="map"] #chart-canvas,
.app-content[data-zone="branding"][data-mode="map"] #chart-canvas { cursor: crosshair; }

/* The wrap carries the position/drag-anchor; the marker circle itself
   stays a plain flexbox with no positioning of its own, so the duplicate
   badge below can sit outside the circle's own overflow:hidden (needed to
   clip the label's width transition) without being clipped along with it. */
.screen-marker-wrap {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 5;
}

/* Icon-only by default — a floor plan with a dozen screens on it reads as
   clutter if every one carries its full name permanently; the label only
   needs to be there for the one you're actually looking at, so it expands
   on hover/focus instead (same "reveal detail on demand" idea as the
   read-only hover tooltips on tables/booths/seats, just inline on the
   marker itself rather than a separate floating card). */
.screen-marker {
  display: flex; align-items: center; justify-content: center; gap: 0;
  background: var(--card);
  border: 1.5px solid var(--eor-amber);
  border-radius: 20px;
  width: 26px; height: 26px;
  padding: 0;
  box-shadow: var(--shadow-sm);
  font-size: 11px; font-weight: 700; color: var(--eor-charcoal);
  white-space: nowrap;
  user-select: none;
  cursor: grab;
  overflow: hidden;
  box-sizing: border-box;
  transition: width .16s ease, padding .16s ease, gap .16s ease;
}
.screen-marker svg { flex: none; color: var(--eor-amber); }
.screen-marker-label {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-width .16s ease, opacity .12s ease;
}
.screen-marker:hover, .screen-marker:focus-visible {
  justify-content: flex-start;
  width: auto;
  padding: 4px 10px 4px 6px;
  gap: 5px;
}
.screen-marker:hover .screen-marker-label,
.screen-marker:focus-visible .screen-marker-label {
  max-width: 220px;
  opacity: 1;
}
.screen-marker:active { cursor: grabbing; }
.screen-marker.status-needs-update { border-color: var(--eor-amber-dark); }
.screen-marker.status-needs-update svg { color: var(--eor-amber-dark); }
.screen-marker.status-offline { border-color: #C0392B; opacity: 0.65; }
.screen-marker.status-offline svg { color: #C0392B; }

/* Flags "this screen has more than one instance on the floor plan" — shown
   on every one of that screen's markers (not just one of them), same
   count each time, so noticing it on whichever marker you're looking at
   is enough. */
.screen-marker-badge {
  position: absolute;
  top: -5px; right: -5px;
  min-width: 15px; height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: var(--eor-charcoal);
  color: #fff;
  font-size: 9px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 1.5px var(--card);
  pointer-events: none;
}

/* Branding's Floor Plan marker — the one structural difference from
   Screens: a resizable rectangle (its own width/height per placement,
   see app.js) rather than a fixed-size circle, since a banner's footprint
   varies item to item. Position is its own top-left corner (not a centred
   transform the way the circle marker uses), set inline alongside
   width/height on every render. */
.branding-marker {
  position: absolute;
  box-sizing: border-box;
  background: rgba(255, 255, 255, 0.85);
  border: 1.5px solid var(--eor-amber);
  border-radius: 4px;
  box-shadow: var(--shadow-sm);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  cursor: grab;
  z-index: 5;
}
.branding-marker:active { cursor: grabbing; }
.branding-marker.status-needs-update { border-color: var(--eor-amber-dark); }
.branding-marker.status-offline { border-color: #C0392B; opacity: 0.65; }
.branding-marker-badge { position: absolute; top: -6px; right: -6px; }

/* Bottom-right resize handle — its own mousedown stops propagation (see
   startBrandingResize() in app.js) so dragging it resizes the rectangle
   instead of also triggering the marker's own move-drag for the same
   gesture. */
.branding-resize-handle {
  position: absolute;
  right: -4px; bottom: -4px;
  width: 10px; height: 10px;
  background: var(--eor-amber);
  border: 1.5px solid var(--card);
  border-radius: 2px;
  cursor: nwse-resize;
}

/* Venue zones — a faint, always-visible outline + label in the Screens
   Floor Plan, with a stronger highlight while a marker is being dragged
   over that zone specifically (see highlightScreenZoneAt() in app.js). */
.screen-zone {
  position: absolute;
  border: 1.5px dashed rgba(35, 31, 32, 0.18);
  border-radius: 4px;
  pointer-events: none;
  transition: background .12s ease, border-color .12s ease;
}
.screen-zone-label {
  position: absolute;
  top: 6px; left: 8px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: rgba(35, 31, 32, 0.35);
}
.screen-zone.drag-over {
  background: rgba(249, 167, 29, 0.14);
  border-color: var(--eor-amber);
  border-style: solid;
}
.screen-zone.drag-over .screen-zone-label { color: var(--eor-amber-dark); }

/* The guest/sponsor search box in the shared toolbar doesn't apply to
   Screens (nothing to search by name) — only the Floor Plan/List/Content
   mode toggle and the stats tiles do, so just this one child hides. */
.app-content[data-zone="screens"] .find-guest,
.app-content[data-zone="branding"] .find-guest { display: none; }

/* Guides fade in while an aisle slider is being dragged, then fade out. */
.aisle-guide {
  position: absolute;
  background: rgba(0, 189, 242, 0.13);
  border-top: 1px dashed rgba(0, 189, 242, 0.55);
  border-bottom: 1px dashed rgba(0, 189, 242, 0.55);
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease;
}
#aisle-layer.showing .aisle-guide { opacity: 1; }

.aisle-tag {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  background: var(--eor-cyan); color: #fff;
  font-size: 9px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px; border-radius: 10px;
  white-space: nowrap;
}

/* --- tables --- */

.table-node { position: absolute; cursor: grab; z-index: 3; transition: filter .12s ease, opacity .15s ease; }
.table-node.vacant { opacity: 0.3; }          /* nobody seated yet */
.table-node:hover { z-index: 20; filter: drop-shadow(0 2px 5px rgba(35, 31, 32, 0.3)); }
.table-node:hover .table-body { border-color: var(--eor-cyan); }
.table-node.dragging { opacity: 0.35; cursor: grabbing; z-index: 22; }
.table-node.drag-over .table-body {
  border-color: var(--eor-amber-dark);
  box-shadow: 0 0 0 4px rgba(249, 167, 29, 0.35);
}
.table-node.open { z-index: 21; }
.table-node.open .table-body {
  border-color: var(--eor-cyan);
  box-shadow: 0 0 0 3px rgba(0, 189, 242, 0.4);
}
.table-node.search-hit { opacity: 1; z-index: 19; }
.table-node.search-hit .table-body {
  border-color: var(--eor-amber);
  box-shadow: 0 0 0 4px rgba(249, 167, 29, 0.55);
}

.table-body {
  position: absolute;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid var(--eor-charcoal);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--eor-charcoal); line-height: 1;
}

.seat {
  position: absolute;
  background: var(--eor-amber);
  border: 1px solid var(--eor-charcoal);
  border-radius: 2px;
}
.seat.open { background: #DDD; opacity: 0.55; }
/* Held by a reserved table but not yet matched to a named guest. */
.seat.held { background: var(--eor-cyan); }

.table-node.reserved .table-body {
  background: #E8F8FE;
  border-color: var(--eor-cyan-dark);
  color: var(--eor-cyan-dark);
}

/* --- booths --- */
/* The tier colour is set inline per-node in renderBooths() (from
   BOOTH_TYPES in plans.js) — the floor plan background is now a plain
   architectural outline with no colour of its own. Fill strength itself
   carries status: a light tint while open, full strength once assigned
   (also set inline, since it's a color-mix against the tier colour).
   Border colour is per-side inline too (see boothBorderSides() in app.js)
   — a shared edge between two touching booths must be drawn by only one
   of them or it doubles into a visibly thicker seam. Border *style*
   (dashed vs solid) stays here in CSS since it only depends on the
   .assigned class, not on any neighbour. */
.booth-node {
  position: absolute;
  cursor: pointer;
  border-width: 1.5px;
  border-style: dashed;
  border-color: transparent;
  box-sizing: border-box;
  transition: filter .12s ease;
}
.booth-node.assigned { border-style: solid; }
/* A drop-shadow rather than a transform: scale — this node's own geometry
   is what positionBoothPopover() measures on click, so nothing should move
   it, only make it visually pop. */
.booth-node:hover { filter: drop-shadow(0 2px 5px rgba(35, 31, 32, 0.35)); }
.booth-node:hover { border-color: var(--eor-cyan); z-index: 20; }
.booth-node.open { border-color: var(--eor-cyan); box-shadow: 0 0 0 3px rgba(0, 189, 242, 0.4); z-index: 21; }
.booth-node.search-hit { z-index: 19; }

.booth-badge {
  position: absolute; top: 2px; left: 3px;
  font-family: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", Menlo, monospace;
  font-weight: 700; line-height: 1;
  /* Plain text on the tier fill, not a solid chip — colour is set inline
     per-node in renderBooths() (readableTextOn()) so it stays legible on
     both a pale 20%-tint fill and a full-strength dark one. */
  color: var(--booth-text, var(--eor-charcoal));
  z-index: 1;
  pointer-events: none;
}

/* Occupied indicator — bottom-right mirror of the number badge (top-left),
   same size, same contrast-aware colour, shown only once a sponsor is
   actually assigned (see the `sponsor` check in renderBooths()). */
.booth-tick {
  position: absolute; bottom: 2px; right: 3px;
  display: flex;
  color: var(--booth-text, var(--eor-charcoal));
  z-index: 1;
  pointer-events: none;
}
.booth-tick svg { width: 100%; height: 100%; }

/* --- conference (theatre-style single seating) --- */
/* Featured (numbered, assignable) seats vs. static decoration are the same
   shape — only .static drops the pointer/hover/assigned treatment, since it
   has no click handler behind it at all (not just visually suppressed). */
.seat-node {
  position: absolute;
  box-sizing: border-box;
  border-radius: 3px;
  background: #E7E7EA;
  border: 1px solid var(--border-strong);
}
.seat-node.static { background: #EFEFF1; border-color: #E2E2E5; cursor: default; }
.seat-node:not(.static) {
  cursor: grab;
  transition: filter .12s ease;
}
.seat-node:not(.static):hover { filter: drop-shadow(0 2px 4px rgba(35, 31, 32, 0.3)); z-index: 5; }
.seat-node.assigned { background: var(--eor-amber); border-color: var(--eor-amber-dark); }
/* Held for someone before a name is entered — same cyan "reserved, not yet
   named" idiom as a gala table — distinct from the amber "actually named"
   fill so the two states stay visually distinguishable in the chart. */
.seat-node.reserved { background: #E8F8FE; border-color: var(--eor-cyan-dark); }
.seat-node.reserved::after { background: rgba(12, 127, 168, 0.45); }
.seat-node.dragging { opacity: 0.35; }
.seat-node.drag-over { box-shadow: 0 0 0 3px rgba(249, 167, 29, 0.45); }
.seat-node.open {
  border-color: var(--eor-cyan); box-shadow: 0 0 0 3px rgba(0, 189, 242, 0.4); z-index: 6;
}
.seat-node.search-hit {
  border-color: var(--eor-amber); box-shadow: 0 0 0 3px rgba(249, 167, 29, 0.55); z-index: 6;
}
.seat-node-badge {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; line-height: 1;
  color: var(--eor-charcoal);
  pointer-events: none;
  z-index: 1;
}
.seat-node.assigned .seat-node-badge { color: #fff; }

/* A plain rounded square reads as a floor tile, not a chair — this strip is
   the backrest, giving every chair (featured or static) a visible front/back
   the way the reference image's chairs have. It sits on whichever edge
   faces away from the stage — renderConference() sets the back-* class from
   plan().stage, the same "which way do chairs face" convention seatAngles()
   already uses for the gala tables' own seats. */
.seat-node::after {
  content: '';
  position: absolute;
  background: rgba(35, 31, 32, 0.4);
  border-radius: 1px;
  pointer-events: none;
}
.seat-node.assigned::after { background: rgba(255, 255, 255, 0.55); }
.seat-node.back-right::after { top: 10%; bottom: 10%; right: 6%; width: 22%; }
.seat-node.back-left::after { top: 10%; bottom: 10%; left: 6%; width: 22%; }
.seat-node.back-top::after { left: 10%; right: 10%; top: 6%; height: 22%; }
.seat-node.back-bottom::after { left: 10%; right: 10%; bottom: 6%; height: 22%; }

/* ================= Hover card + editable popover ================= */

.tooltip {
  position: fixed;
  background: var(--eor-charcoal);
  color: #fff;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  z-index: 200;
  pointer-events: none;
  box-shadow: var(--shadow-lg);
  max-width: 230px;
  /* Faded out and very slightly lower at rest — .visible (below) fades and
     lifts it into place. A *transition*, not a restarting keyframe
     animation, on purpose: hovering a dense grid of small booths/seats
     toggles this state many times a second, and a transition interpolates
     smoothly from wherever it currently is (including mid-fade) instead of
     snapping back to a fixed starting point on every single retrigger —
     that snap-back was what read as stuttering/flickering before. Opacity
     + a 4px translate only, no scale — a size change is a much more
     jarring thing to have interrupted mid-flight than a fade.
     `visibility` is delayed on the way out so it's not still keyboard/
     screen-reader reachable while invisible, but flips instantly on the
     way in. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity .18s cubic-bezier(.22, .61, .36, 1),
              transform .18s cubic-bezier(.22, .61, .36, 1),
              visibility 0s linear .18s;
}
.tooltip.visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity .16s cubic-bezier(.22, .61, .36, 1),
              transform .16s cubic-bezier(.22, .61, .36, 1),
              visibility 0s linear;
}
.tooltip strong { color: var(--eor-amber); display: block; margin-bottom: 5px; }
.tooltip .t-open { color: #8E8E93; font-style: italic; }

/* A dimmed, blurred scrim behind whichever popover is open — turns the
   click-anchored card into a proper centred modal: the background is still
   visible (so there's context for what you're editing) but neither visible
   clearly nor interactive while a popover is up. Sits just under the
   popover's own z-index (210) and above everything else. */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(35, 31, 32, 0.4);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 205;
}
.modal-backdrop[hidden] { display: none; }

.popover {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 252px;
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 210;
  overflow: hidden;
  max-height: 85vh;
}
.popover[hidden] { display: none; }
/* Entrance-only — starting the animation the instant `hidden` is removed
   reads as a purposeful "open", not just content appearing; no matching
   exit animation since that needs JS-timed removal of `hidden` and isn't
   worth the complexity for a card that's gone in one click anyway. */
.popover:not([hidden]) { animation: pop-in .16s cubic-bezier(.2, .8, .2, 1); }

@keyframes pop-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.94); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.pop-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px;
  padding: 11px 12px;
  background: var(--eor-charcoal);
  color: #fff;
}
.pop-head strong { display: block; font-size: 13.5px; color: var(--eor-amber); }
.pop-head span { font-size: 11px; color: rgba(255,255,255,0.65); }
.pop-close {
  border: none; background: none; color: rgba(255,255,255,0.7);
  cursor: pointer; padding: 2px;
  display: inline-flex; align-items: center; justify-content: center;
}
.pop-close svg { width: 16px; height: 16px; }
.pop-close:hover { color: #fff; }

.pop-reserve {
  padding: 9px 10px;
  background: #F7F7F8;
  border-bottom: 1px solid var(--border);
}
.pop-reserve .check { margin: 0 0 7px; font-size: 11.5px; color: var(--text); font-weight: 600; }
.pop-reserve input[type="text"] {
  width: 100%;
  border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 6px 8px; font-size: 12px;
}
.pop-reserve input[type="text"]:disabled { background: #EDEDEF; color: var(--muted); }

.pop-guests {
  list-style: none;
  margin: 0; padding: 8px 8px 4px;
  max-height: 210px; overflow-y: auto;
}
.pop-guests li {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 6px; border-radius: 6px;
  font-size: 12.5px;
}
.pop-guests li:hover { background: #F6F6F7; }
.pop-guests .seat-no {
  width: 17px; height: 17px; flex: none;
  border-radius: 50%;
  background: var(--eor-amber);
  color: #fff; font-size: 9.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.pop-guests .g-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  line-height: 1.3;
}
.pop-guests .g-name small { display: block; color: var(--muted); font-size: 10.5px; }
.pop-guests .g-move,
.pop-guests .g-remove {
  border: none; background: none; color: var(--muted);
  cursor: pointer; padding: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .12s ease;
}
.pop-guests li:hover .g-move,
.pop-guests li:hover .g-remove { opacity: 1; }
.pop-guests .g-move:hover { color: var(--eor-cyan-dark); }
.pop-guests .g-remove:hover { color: #C0392B; }
.pop-guests .move-input {
  flex: 1; min-width: 0;
  border: 1px solid var(--eor-cyan); border-radius: 5px;
  padding: 3px 6px; font-size: 12px; text-align: center;
}
.pop-guests .move-input.move-error { border-color: #C0392B; }
.pop-empty { padding: 10px 8px; font-size: 12px; color: var(--muted); font-style: italic; }

/* Same Name/Company field pair as the booth/conference-seat popovers
   (.booth-pop-fields), rather than the single "Name, Company" combined
   input this replaced — an explicit Add button since a table (unlike a
   booth or a conference seat) holds several guests, so there's no single
   always-live pair of fields to bind to. */
.pop-add-fields {
  padding: 4px 12px 10px;
  display: flex; flex-direction: column; gap: 8px;
  border-top: 1px dashed var(--border);
}
.pop-add-fields .field { display: flex; flex-direction: column; gap: 4px; }
.pop-add-fields .field span {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); font-weight: 700;
}
.pop-add-fields .field input {
  border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 7px 9px; font-size: 12.5px; color: var(--text);
}
.pop-add-fields .field input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }
.pop-add-fields .field input:disabled { background: #F6F6F7; color: var(--muted); }
/* Icon-only Confirm + Clear, side by side rather than one full-width
   labelled button — Confirm just closes (fields already save live on
   input, same as everywhere else in the app), Clear is destructive. */
.pop-foot { display: flex; gap: 8px; padding: 0 8px 9px; }
.pop-foot .btn { flex: 1; padding: 9px; }

/* --- booth popover: two plain labeled fields instead of a guest list --- */

.booth-pop-fields { padding: 11px 12px; display: flex; flex-direction: column; gap: 10px; }
.booth-pop-fields .field { display: flex; flex-direction: column; gap: 4px; }
.booth-pop-fields .field span {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); font-weight: 700;
}
.booth-pop-fields .field input {
  border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 7px 9px; font-size: 12.5px; color: var(--text);
}
.booth-pop-fields .field input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }

/* Dropdowns styled to match the text inputs right next to them (same
   border/radius/padding/font) rather than the browser's own default select
   chrome — a custom chevron replaces the native arrow since `appearance:
   none` drops it entirely. Shared by every popover select (Content type,
   the Agenda picker) rather than restated per popover. */
.booth-pop-fields .field select,
.screens-pop-agenda-picker select {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 7px 26px 7px 9px; font-size: 12.5px; color: var(--text);
  font-family: inherit;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238E8E93' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
}
.booth-pop-fields .field select:focus,
.screens-pop-agenda-picker select:focus {
  outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent;
}

/* ================= Guest list & Sponsors ================= */

/* --- unassigned guests --- */

.unassigned-panel {
  flex: none;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 12px 14px;
}
.unassigned-head {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 10px;
}
.unassigned-head h3 {
  margin: 0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--eor-amber-dark); font-weight: 700; white-space: nowrap;
}
.unassigned-head input {
  flex: 1; max-width: 340px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 7px 10px; font-size: 12.5px;
}
.unassigned-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px;
}
/* Deliberately a different colour from a seated table slot (amber-tinted)
   — cyan says "not at a table yet" at a glance, across dozens of rows. */
.unassigned-chip {
  display: grid; grid-template-columns: 1fr 1fr auto auto; gap: 6px; align-items: center;
  background: rgba(0, 189, 242, 0.09);
  border: 1px solid rgba(0, 189, 242, 0.35);
  border-radius: 8px; padding: 6px 7px;
}
.unassigned-chip input {
  min-width: 0; width: 100%;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 7px; font-size: 12px;
  background: var(--card);
}
.unassigned-chip input.u-co { color: var(--muted); }
.unassigned-chip input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }
.unassigned-chip .g-move,
.unassigned-chip .g-remove {
  border: none; background: none; color: var(--muted);
  cursor: pointer; padding: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; flex: none;
}
.unassigned-chip .g-move:hover { color: var(--eor-cyan-dark); background: #EAF7FC; }
.unassigned-chip .g-remove:hover { color: #C0392B; background: #FDECEB; }
.unassigned-chip .g-move[hidden],
.unassigned-chip .g-remove[hidden] { display: none; }
.unassigned-chip .move-input {
  width: 56px; border: 1px solid var(--eor-cyan); border-radius: 6px;
  padding: 3px 6px; font-size: 11.5px; text-align: center;
}
.unassigned-chip .move-input.move-error { border-color: #C0392B; }
.unassigned-empty { grid-column: 1 / -1; font-size: 12px; color: var(--muted); font-style: italic; padding: 4px 0; }

.table-list-wrap {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.table-list { width: 100%; border-collapse: separate; border-spacing: 0; }
.table-list th, .table-list td {
  border-bottom: 1px solid var(--border);
  padding: 7px 12px; font-size: 12.5px; text-align: left;
  vertical-align: middle;
}
.table-list tr:last-child td { border-bottom: none; }
.table-list th {
  background: #F7F7F8; color: var(--muted);
  font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
  position: sticky; top: 0; z-index: 5;
}
.table-list .col-num { width: 74px; }
.table-list .col-seated { width: 96px; }
.table-list td.tnum { font-weight: 800; color: var(--eor-amber-dark); font-size: 14px; }
.table-list td.seated { color: var(--muted); white-space: nowrap; }
.table-list tr.is-full td.seated { color: var(--eor-amber-dark); font-weight: 700; }
.table-list tr.row-hit { background: rgba(249, 167, 29, 0.09); }
.empty-row { color: var(--muted); font-style: italic; padding: 18px 12px; }

/* --- reserve strip + 8 seat slots per table --- */

.reserve-strip {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 9px; padding-bottom: 9px;
  border-bottom: 1px dashed var(--border);
  flex-wrap: wrap;
}
.reserve-strip .check { margin: 0; font-size: 11.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.reserve-strip .res-company {
  flex: 1; min-width: 150px; max-width: 300px;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 8px; font-size: 12px;
}
.reserve-strip .res-company:disabled { background: #F4F4F5; color: var(--muted); }

tr.is-reserved { background: rgba(0, 189, 242, 0.06); }
tr.is-reserved td.seated { color: var(--eor-cyan-dark); font-weight: 700; }

.slot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; }
/* One container per seat — a visible boxed unit (name + company + move),
   not just three loose form fields side by side. */
.slot {
  display: grid; grid-template-columns: 17px 1fr 1fr auto; gap: 6px; align-items: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 7px;
}
.slot.filled { background: rgba(249, 167, 29, 0.07); border-color: rgba(249, 167, 29, 0.35); }
.slot-no {
  width: 17px; height: 17px; border-radius: 50%;
  background: #E6E6E9; color: var(--muted);
  font-size: 9.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.slot.filled .slot-no { background: var(--eor-amber); color: #fff; }
.slot input {
  min-width: 0; width: 100%;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 7px; font-size: 12px;
  background: var(--card);
}
.slot input.slot-co { color: var(--muted); }
.slot input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }
.slot .g-move, .slot .g-remove,
.sponsor-fields .g-move, .sponsor-fields .g-remove,
.seat-fields .g-move, .seat-fields .g-remove {
  border: none; background: none; color: var(--muted);
  cursor: pointer; padding: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; flex: none;
}
.slot .g-move:hover, .sponsor-fields .g-move:hover, .seat-fields .g-move:hover {
  color: var(--eor-cyan-dark); background: #EAF7FC;
}
.slot .g-remove:hover, .sponsor-fields .g-remove:hover, .seat-fields .g-remove:hover {
  color: #C0392B; background: #FDECEB;
}
.slot .g-move[hidden], .slot .g-remove[hidden],
.sponsor-fields .g-move[hidden], .sponsor-fields .g-remove[hidden],
.seat-fields .g-move[hidden], .seat-fields .g-remove[hidden] { display: none; }
.slot .move-input,
.sponsor-fields .move-input,
.seat-fields .move-input {
  width: 46px; border: 1px solid var(--eor-cyan); border-radius: 6px;
  padding: 3px 5px; font-size: 11.5px; text-align: center;
}
.slot .move-input.move-error,
.sponsor-fields .move-input.move-error,
.seat-fields .move-input.move-error { border-color: #C0392B; }

/* --- sponsor row (Sponsors section) — same container language as a seat
   slot, just one occupant per booth instead of eight. No separate "type"
   field — the tier tabs already say what tier a sponsor is in. --- */
.sponsor-fields {
  display: grid; grid-template-columns: 1fr auto auto; gap: 6px; align-items: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 8px;
  max-width: 360px;
}
.sponsor-fields.filled { background: rgba(249, 167, 29, 0.07); border-color: rgba(249, 167, 29, 0.35); }
.sponsor-fields input {
  min-width: 0; width: 100%;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 8px; font-size: 12.5px;
  background: var(--card);
}
.sponsor-fields input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }

/* --- conference seat row (Conference Guest List) — same container
   language as a sponsor row, but Name + Company like a table guest, since
   a conference seat holds a person, not a sponsor. --- */
.seat-fields {
  display: grid; grid-template-columns: 1fr 1fr auto auto; gap: 6px; align-items: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 8px;
  max-width: 420px;
}
.seat-fields.filled { background: rgba(249, 167, 29, 0.07); border-color: rgba(249, 167, 29, 0.35); }
.seat-fields input {
  min-width: 0; width: 100%;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 8px; font-size: 12.5px;
  background: var(--card);
}
.seat-fields input:focus { outline: 2px solid var(--eor-cyan); outline-offset: -1px; border-color: transparent; }
.table-list td.bstatus { white-space: nowrap; }
.table-list td.bstatus .b-open { color: var(--muted); font-style: italic; }
.table-list td.bstatus .b-taken { color: var(--eor-amber-dark); font-weight: 700; }

/* --- Sponsors: one tier at a time via tabs, not all five stacked. --- */
.sponsor-tabs {
  flex: none;
  display: flex; gap: 4px; flex-wrap: wrap;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 8px;
}
.sponsor-tab {
  display: flex; align-items: center; gap: 7px;
  border: none; background: none; cursor: pointer;
  padding: 7px 12px; border-radius: 8px;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
  transition: background .13s ease, color .13s ease;
}
.sponsor-tab:hover { background: rgba(249, 167, 29, 0.1); }
.sponsor-tab.active { background: var(--tab-color, var(--eor-charcoal)); color: var(--tab-text, #fff); }
.sponsor-tab-count {
  font-size: 10.5px; font-weight: 700;
  background: rgba(0, 0, 0, 0.08); color: inherit;
  border-radius: 10px; padding: 1px 7px;
}
.sponsor-tab.active .sponsor-tab-count { background: rgba(255, 255, 255, 0.2); }

/* The active tab's own detail bar: colour swatch, spec, assigned/total,
   and a "+" to add a sponsor before a specific booth's picked. */
.tier-header-row td {
  padding: 10px 12px 8px;
  background: #F7F7F8;
  border-bottom: 1px solid var(--border);
}
.tier-header-row:not(:first-child) td { border-top: 1px solid var(--border); }
.tier-head { display: flex; align-items: center; gap: 8px; }
.tier-swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; box-shadow: inset 0 0 0 1px rgba(35,31,32,0.15); }
.tier-spec { font-size: 13px; color: var(--muted); }
.tier-count { font-size: 11px; font-weight: 700; color: var(--eor-amber-dark); margin-left: auto; }
.tier-add-btn {
  flex: none;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--border-strong); background: var(--card);
  color: var(--eor-charcoal); font-size: 14px; line-height: 1; font-weight: 700;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.tier-add-btn:hover { background: var(--eor-charcoal); color: #fff; border-color: var(--eor-charcoal); }

.tier-add-row td { padding: 8px 12px; background: #FBFBFC; border-bottom: 1px solid var(--border); }
.tier-add-fields { max-width: 480px; }

/* Distinct cyan tint (same idiom as an unassigned guest chip) so a sponsor
   noted ahead of a booth reads as clearly not-yet-placed, not just "empty". */
.unassigned-sponsor-row td { padding: 7px 12px; }
.unassigned-sponsor-row .sponsor-fields {
  grid-template-columns: 1fr auto auto;
  background: rgba(0, 189, 242, 0.09);
  border-color: rgba(0, 189, 242, 0.35);
  max-width: 520px;
}
.unassigned-sponsor-row .g-remove {
  border: none; background: none; color: var(--muted);
  cursor: pointer; padding: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; flex: none;
}
.unassigned-sponsor-row .g-remove:hover { color: #C0392B; background: #FDECEB; }

/* ================= Under construction ================= */

.under-construction {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
  padding: 40px;
  text-align: center;
  color: var(--muted);
}
/* The explicit display:flex above beats the [hidden] attribute's UA
   display:none on specificity ties (author styles win) — without this,
   toggling `hidden` does nothing and the page never actually hides. */
.under-construction[hidden] { display: none; }
.under-construction h2 {
  margin: 0; font-size: 20px; color: var(--eor-charcoal); letter-spacing: -0.01em;
}
.under-construction p { margin: 0; font-size: 13.5px; max-width: 360px; }

/* ================= Welcome screen ================= */
/* A full-page takeover — position:fixed over literally everything,
   including the topbar, rather than layered under it, so there's exactly
   one "home" state to reason about instead of every render function
   needing to know whether it's showing. */
.welcome-screen {
  position: fixed; inset: 0; z-index: 300;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  overflow-y: auto;
  padding: 40px 20px;
}
.welcome-screen[hidden] { display: none; }
.welcome-inner { width: 100%; max-width: 900px; text-align: center; }
.welcome-logo { height: 48px; width: auto; margin-bottom: 20px; }
.welcome-inner h1 { margin: 0 0 6px; font-size: 26px; color: var(--eor-charcoal); letter-spacing: -0.01em; }
.welcome-inner > p { margin: 0 0 28px; color: var(--muted); font-size: 14px; }

.welcome-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px; text-align: left;
}
.welcome-card {
  position: relative;
  border: 1px solid var(--border-strong); background: var(--card);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 20px; cursor: pointer;
  display: flex; flex-direction: column; gap: 8px;
  transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.welcome-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--eor-amber); }
.welcome-card:active { transform: translateY(-1px) scale(0.99); }
.welcome-card-logo { height: 32px; width: auto; max-width: 100%; object-fit: contain; align-self: flex-start; }
.welcome-card h3 { margin: 0; font-size: 15px; color: var(--eor-charcoal); letter-spacing: -0.01em; }
.welcome-card-occasion {
  display: inline-block; align-self: flex-start;
  background: rgba(249, 167, 29, 0.15); color: var(--eor-amber-dark);
  border-radius: 20px; padding: 3px 10px;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
}
.welcome-card-date { font-size: 12px; color: var(--muted); }
.welcome-card-badge {
  position: absolute; top: 14px; right: 14px;
  background: #F0F0F2; color: var(--muted);
  border-radius: 20px; padding: 3px 9px;
  font-size: 9px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
}

.uc-spinner { display: flex; gap: 10px; }
.uc-spinner span {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--eor-amber);
  animation: uc-bounce 1.1s ease-in-out infinite;
}
.uc-spinner span:nth-child(2) { background: var(--eor-cyan); animation-delay: .15s; }
.uc-spinner span:nth-child(3) { background: var(--eor-charcoal); animation-delay: .3s; }

@keyframes uc-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
  40% { transform: translateY(-14px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .uc-spinner span { animation: none; opacity: 0.85; }
  .popover:not([hidden]),
  .section-panel.active, .chart-viewport:not([hidden]) { animation: none; }
  .nav-indicator, .mode-indicator,
  .btn, .nav-item, .mode-btn, .g-move, .g-remove, .find-clear,
  .pop-close, .tier-add-btn, .sponsor-tab, .table-node, .booth-node,
  .tooltip, .tooltip.visible {
    transition: none;
  }
}

/* ================= Print ================= */

@media print {
  body { overflow: visible; height: auto; }
  .topbar, .content-toolbar, .tooltip, .popover, .nav-zones, .nav-widget { display: none !important; }
  .app-body { display: block; }
  .app-content { padding: 0; }
  .site-nav { width: 100%; border-right: none; }
  .chart-viewport { border: none; box-shadow: none; overflow: visible; }
  .section-panel { display: flex !important; }
}

/* Tight desktop widths: shed the least important chrome before wrapping. */
@media (max-width: 1320px) {
  .topbar { gap: 16px; padding: 0 14px; }
  .brand-text span, .plan-picker > span { display: none; }
  .plan-picker select { min-width: 190px; }
  .stats .stat { min-width: 58px; padding: 6px 9px; }
}

@media (max-width: 1080px) {
  body { overflow: auto; height: auto; }
  .app-body { flex-direction: column; height: auto; }
  .site-nav { width: 100%; border-right: none; border-bottom: 1px solid var(--border); }
  .nav-zones { flex-wrap: wrap; }
  .section-panel.active { min-height: 60vh; }
  .chart-viewport { min-height: 60vh; }
  .content-toolbar .stats { margin-left: 0; width: 100%; }
}

/* Phone widths: below this a click-anchored popover can't find a sane
   "beside the table" spot, inputs need a 16px floor (iOS auto-zooms any
   focused input under that), and every icon-only tap target needs to grow
   toward the ~40px comfortable-touch minimum. */
@media (max-width: 640px) {
  html { -webkit-text-size-adjust: 100%; }
  input, select, textarea { font-size: 16px; }

  .topbar { gap: 10px; padding: 0 10px; height: auto; min-height: 52px; flex-wrap: wrap; }
  .brand { gap: 8px; }
  .brand-logo { height: 24px; }
  .brand-text { display: none; }
  .plan-picker { gap: 5px; }
  .plan-picker select { min-width: 0; max-width: 40vw; font-size: 12px; padding: 6px 8px; }
  .topbar-actions { gap: 5px; }
  .save-status { font-size: 0; padding: 0; }
  .save-status::before { margin: 0; }
  #export-pdf-label { display: none; }
  #export-pdf { padding: 9px; }

  .app-content { padding: 10px; gap: 8px; }
  .nav-zones { width: 100%; }
  .nav-item { flex: 1; justify-content: center; padding: 10px 6px; }
  .nav-label { display: none; }
  .nav-item svg { width: 18px; height: 18px; }

  .content-toolbar { padding: 8px; gap: 8px; }
  .mode-toggle { width: 100%; }
  .mode-btn { flex: 1; justify-content: center; padding: 9px 6px; }
  .find-guest { min-width: 0; max-width: none; flex-basis: 100%; order: 3; }
  .stats { width: 100%; }
  .stat { flex: 1; }

  /* A bottom sheet, not a floating card anchored near a fingertip-sized
     table dot — see MOBILE_BREAKPOINT/isMobileViewport() in app.js, which
     stops setting inline left/top below this same width so this owns
     position outright. */
  .popover, .booth-popover {
    left: 0 !important; right: 0; top: auto !important; bottom: 0;
    transform: none !important;
    width: 100%; max-width: 100%; max-height: 78vh; overflow-y: auto;
    border-radius: 16px 16px 0 0;
    animation: sheet-up .2s cubic-bezier(.2, .8, .2, 1) !important;
  }
  .tooltip { display: none; }   /* hover state has no meaning on touch */

  .slot-grid { grid-template-columns: 1fr; }
  .unassigned-chip { grid-template-columns: 1fr auto auto; }
  .unassigned-chip .u-co { grid-column: 1 / -1; }

  .g-move, .g-remove, .find-clear, .pop-close, .tier-add-btn { min-width: 34px; min-height: 34px; }
}

@keyframes sheet-up {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: translateY(0); }
}
