/*
 * Plain CSS that must load even if the Tailwind build is missing —
 * floorplan transforms, GPU compositing hints, kiosk tap-target floor,
 * the kiosk app shell (.floorplan-screen) and modal scaffolding.
 * Brand colors and typography live in app/assets/tailwind/application.css.
 */

html, body {
  margin: 0;
  background-color: #0e3046;
  -webkit-font-smoothing: antialiased;
}

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

/* ===========================================================
 * Kiosk app shell
 *
 * .floorplan-screen fills the viewport, stacked as:
 *   header (logo) -> floorplan (flex:1) -> bottom bar
 * --background comes from inline style, sourced from bg.svg in
 * the screen template.
 * =========================================================== */

.floorplan-screen {
  min-height: 100vh;
  min-height: 100dvh;
  max-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: clamp(0.75rem, 4vw, 2.5rem);
  background: var(--background) center / cover no-repeat #0e3046;
  color: #f8fafc;
  gap: clamp(0.5rem, 2vw, 1rem);
  position: relative;
}

/* Fullscreen mode: the floorplan controller toggles .is-fullscreen on the
   screen container via the toolbar's expand button. The header is hidden
   so the floor plan gets the full vertical space, and the bottom bar
   becomes an overlay so it floats over the map. Tap-throughs in the
   gaps work because pointer-events: none on the bar with auto restored
   on the actual control clusters. */
.floorplan-screen.is-fullscreen {
  padding: 0;
  gap: 0;
}
.floorplan-screen.is-fullscreen .floorplan-screen__header {
  display: none;
}
.floorplan-screen.is-fullscreen .floorplan-screen__bar {
  position: absolute;
  inset: auto 0 clamp(0.75rem, 3vw, 1.5rem) 0;
  padding-inline: clamp(0.75rem, 3vw, 1.5rem);
  pointer-events: none;
  z-index: 40;
}
.floorplan-screen.is-fullscreen .floorplan-screen__actions,
.floorplan-screen.is-fullscreen .floorplan-controls {
  pointer-events: auto;
}

/* Fullscreen toggle icon swap — the button stamps both icons; CSS hides
   the inactive one. */
.floorplan-controls__btn--fullscreen [data-fullscreen-icon="exit"] { display: none; }
.floorplan-screen.is-fullscreen .floorplan-controls__btn--fullscreen [data-fullscreen-icon="enter"] { display: none; }
.floorplan-screen.is-fullscreen .floorplan-controls__btn--fullscreen [data-fullscreen-icon="exit"]  { display: block; }

/* Ghost FABs read fine against the bg-coloured panel in normal mode,
   but overlaid on the floorplan in fullscreen they need a backing
   surface or the Key button vanishes against light areas of the map. */
.floorplan-screen.is-fullscreen .floorplan-fab--ghost {
  background: rgba(15, 60, 85, 0.85);
  border-color: rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.6);
}
.floorplan-screen.is-fullscreen .floorplan-fab--ghost:hover {
  background: rgba(20, 70, 104, 0.95);
}

.floorplan-screen__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.25rem;
  padding-inline: clamp(0.5rem, 2vw, 1.5rem);
  flex: 0 0 auto;
}
.floorplan-screen__logo {
  height: clamp(3.5rem, 8vw, 7rem);
  width: auto;
}
.floorplan-screen__qr {
  display: block;
  flex: 0 0 auto;
  width: clamp(3.5rem, 7vw, 6rem);
  height: clamp(3.5rem, 7vw, 6rem);
}
.floorplan-screen__qr svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* On mobile, drop the header QR and re-centre the logo. */
@media (max-width: 640px) {
  .floorplan-screen__header {
    justify-content: center;
  }
  .floorplan-screen__qr {
    display: none;
  }
}

/* The .floorplan container fills the vertical space left over by the
   header + bottom bar. The SVG inside is absolutely positioned and
   stretched to fill the container box — Safari doesn't reliably honour
   `height: 100%` on a flex-child SVG without explicit dimensions, but
   `position: absolute; inset: 0` is unambiguous. The viewBox content
   is centred inside that box by the SVG's intrinsic
   preserveAspectRatio="xMidYMid meet", so on a portrait kiosk the map
   sits at full width with breathing room above and below. Sizing the
   SVG to the full container (rather than to the natural aspect) lets
   zoom-in transforms expand into that breathing room instead of being
   clipped by the SVG element box. */
.floorplan-screen > .floorplan {
  flex: 1 1 0;
  position: relative;
  width: 100%;
  min-height: 0;
  background: none;
  overflow: hidden;
}
.floorplan-screen > .floorplan svg {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  touch-action: none;
}

/* Stand number labels paint on top of their stand rects. Taps on the
   number should still resolve to the underlying rect, so make text
   transparent to pointer events. The dev-mode show_paths overlay sets
   pointer-events:none on its own label group, so this doesn't conflict. */
.floorplan-screen > .floorplan svg text {
  pointer-events: none;
}

/* Cursor hints — grab when the user can drag (zoomed in), grabbing while
   actively panning, pointer over interactive stands. Mouse-only signals;
   irrelevant on touch but harmless. */
.floorplan-screen > .floorplan svg.is-zoomed { cursor: grab; }
.floorplan-screen > .floorplan svg.is-grabbing { cursor: grabbing; }
.floorplan-screen > .floorplan svg [data-stand-interactive="true"] { cursor: pointer; }
.floorplan-screen > .floorplan svg.is-grabbing [data-stand-interactive="true"] { cursor: grabbing; }

/* Hover tooltip — appended to document.body by the floorplan controller
   on first mouse-hover over a stand. position: fixed + transform anchors
   it above the cursor; pointer-events: none so it can't intercept clicks.
   Visibility is toggled via data-visible to enable the opacity transition. */
.floorplan-tooltip {
  position: fixed;
  pointer-events: none;
  background: rgba(14, 48, 70, 0.95);
  color: #f8fafc;
  padding: 0.375rem 0.625rem;
  border-radius: 0.5rem;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.2;
  max-width: 18rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 50;
  opacity: 0;
  transform: translate(-50%, calc(-100% - 0.75rem));
  transition: opacity 90ms ease;
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.55);
}
.floorplan-tooltip[data-visible="true"] { opacity: 1; }

/* Focus highlight: the floorplan controller drops a <circle class="floorplan-focus-ring">
   on the targeted stand whenever focusStand() runs (e.g. exhibitor search
   "Show on floorplan"). It pulses twice then removes itself on animationend.
   Stroke uses non-scaling-stroke so the ring stays a consistent thickness
   regardless of zoom level. */
.floorplan-focus-ring {
  fill: none;
  stroke: #ec4899;
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  transform-box: fill-box;
  transform-origin: center;
  animation: floorplan-focus-ring-pulse 1.1s ease-out;
  animation-iteration-count: 2;
}
@keyframes floorplan-focus-ring-pulse {
  0%   { opacity: 0;   transform: scale(0.55); }
  20%  { opacity: 1;                            }
  100% { opacity: 0;   transform: scale(1.45); }
}

/* Bottom action bar:
   [Key] [Search]              [+] [−] [↺]
   Left group lives in .floorplan-screen__actions, right group is
   the .floorplan-controls FloorplanControlsComponent renders. */
.floorplan-screen__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  /* Sit above the open exhibitor dialog (z:30) — otherwise the dialog's
     bottom-sheet positioning covers the FABs and zoom controls in
     landscape, so the user can't toggle/close it. */
  position: relative;
  z-index: 40;
}

.floorplan-screen__actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.floorplan-fab {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.875rem 1.25rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(15, 60, 85, 0.85);
  color: #f8fafc;
  font-family: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  cursor: pointer;
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.6);
  transition: background-color 120ms ease, transform 120ms ease;
}
.floorplan-fab:hover  { background: rgba(20, 70, 104, 0.95); }
.floorplan-fab:active { transform: translateY(1px); }

.floorplan-fab--primary {
  background: #c99a23;
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.35);
}
.floorplan-fab--primary:hover { background: #e2b53f; }

.floorplan-fab--ghost {
  background: transparent;
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.85);
  backdrop-filter: none;
  box-shadow: none;
}
.floorplan-fab--ghost:hover { background: rgba(255, 255, 255, 0.12); }

.floorplan-fab__label { line-height: 1; }

/* On phones the action bar gets crowded, so collapse the search + key
   FABs to circular icon buttons. Touch target stays at 44×44 minimum. */
@media (max-width: 640px) {
  .floorplan-fab { padding: 0.75rem; gap: 0; min-width: 2.75rem; min-height: 2.75rem; justify-content: center; }
  .floorplan-fab__label { display: none; }
}

/* ===========================================================
 * Floorplan SVG container
 * =========================================================== */

.floorplan {
  overflow: hidden;
  transform: translateZ(0);
}

#floorplan-viewport {
  will-change: transform;
}

/* Floorplan zoom/reset controls — rendered into the right side of the
   bottom bar (.floorplan-screen__bar) rather than overlaid on the SVG. */
.floorplan-controls {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: rgba(15, 60, 85, 0.85);
  padding: 0.375rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.6);
}

.floorplan-controls__btn {
  width: 2.75rem;
  height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background-color: rgba(255, 255, 255, 0.08);
  color: #f8fafc;
  border-radius: 999px;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 120ms ease;
}
.floorplan-controls__btn:hover  { background-color: rgba(255, 255, 255, 0.18); }
.floorplan-controls__btn:active { background-color: rgba(255, 255, 255, 0.28); }

.mode-kiosk .floorplan-controls__btn {
  width: 4rem;
  height: 4rem;
  font-size: 1.75rem;
}
.mode-kiosk [data-kiosk-tap="true"] {
  min-height: 4rem;
  padding-inline: 1.5rem;
  font-size: 1.0625rem;
}

/* ===========================================================
 * Native <dialog> modals
 *
 * .floorplan-dialog--corner: small top-right card (the key).
 * .floorplan-dialog--sheet:  full-width bottom sheet (search + detail).
 * =========================================================== */

.floorplan-dialog {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #0e3046;
}
.floorplan-dialog::backdrop {
  background: rgba(14, 48, 70, 0.55);
  backdrop-filter: blur(2px);
}

.floorplan-dialog__card {
  background: #ffffff;
  border-radius: 1rem;
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.45);
  overflow: hidden;
  max-width: 100%;
  max-height: 90vh;
  max-height: 90dvh;
  display: flex;
  flex-direction: column;
}

.floorplan-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid #d4e6f1;
}
.floorplan-dialog__header--sheet {
  border-bottom: 0;
  padding: 0.5rem 1rem 0.25rem;
  justify-content: flex-end;
  position: relative;
}

.floorplan-dialog__title {
  margin: 0;
  font-family: var(--font-display, "Inter", sans-serif);
  font-size: 1.0625rem;
  font-weight: 600;
}

.floorplan-dialog__close {
  width: 2.25rem;
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  border-radius: 0.5rem;
  color: #155680;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.floorplan-dialog__close:hover { background: #eef5fa; }
.mode-kiosk .floorplan-dialog__close { width: 3.25rem; height: 3.25rem; font-size: 1.75rem; }

.floorplan-dialog__handle {
  position: absolute;
  top: 0.5rem;
  left: 50%;
  transform: translateX(-50%);
  width: 2.5rem;
  height: 0.25rem;
  border-radius: 999px;
  background: #d4e6f1;
}

.floorplan-dialog__footnote {
  padding: 0 1.25rem 1rem;
  margin: 0;
  font-size: 0.75rem;
  color: #4488b5;
}

/* Key dialog — small floating card top-right. */
.floorplan-dialog--corner {
  position: fixed;
  inset: auto;
  top: max(env(safe-area-inset-top, 0px), 1rem);
  right: max(env(safe-area-inset-right, 0px), 1rem);
  width: min(20rem, calc(100vw - 2rem));
}
.floorplan-dialog--corner .floorplan-dialog__card { border-radius: 0.875rem; }

.floorplan-key-list {
  list-style: none;
  margin: 0;
  padding: 0.75rem 1.25rem;
  display: grid;
  gap: 0.5rem;
  font-size: 0.875rem;
}
.floorplan-key-list li { display: flex; align-items: center; gap: 0.75rem; }
.floorplan-key-swatch {
  flex: none;
  display: inline-block;
  width: 1rem;
  height: 1rem;
  border-radius: 0.25rem;
  border: 1px solid rgba(0, 0, 0, 0.08);
}
.floorplan-key-dim { color: #4488b5; }

/* Search / detail dialog — bottom sheet pinned to the bottom of the
   screen, full width on mobile + portrait kiosk, centred & inset
   in landscape. Translates by --drag-x set by draggable_dialog so the
   user can park the dialog at either side. */
.floorplan-dialog--sheet {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  max-width: 100%;
  /* Stay above the floorplan bar (z:5 in fullscreen) and the
     transform-stacking-context'd floorplan SVG. Without this, the
     non-modal dialog can render under the toolbar in fullscreen mode
     or under sibling stacking contexts elsewhere. */
  z-index: 30;
  transform: translateX(var(--drag-x, 0px));
  transition: transform 220ms ease-out;
}
.floorplan-dialog--sheet[data-dragging="true"] { transition: none; }
.floorplan-dialog--sheet .floorplan-dialog__card {
  border-radius: 1.25rem 1.25rem 0 0;
  max-height: 88vh;
  max-height: 88dvh;
}
.floorplan-dialog__card--sheet > turbo-frame { display: block; overflow-y: auto; }

@media (orientation: landscape) and (min-width: 1000px) {
  .floorplan-dialog--sheet {
    inset: auto;
    left: 50%;
    /* Sit above the bottom bar instead of overlapping it — the bar (z:40)
       still paints over the dialog when they collide, but pushing the
       dialog up to ~6rem leaves the bar with its own breathing room. */
    bottom: 5.5rem;
    width: min(46rem, 90vw);
    transform: translateX(calc(-50% + var(--drag-x, 0px)));
  }
  .floorplan-dialog--sheet .floorplan-dialog__card { border-radius: 1.25rem; }
}

/* When parked at a side only the peek strip stays on-screen — make it
   read as a grabbable tab and hide the × so clicks on the strip restore
   the dialog rather than closing it. */
.floorplan-dialog--sheet[data-snapped] .floorplan-dialog__card { cursor: grab; }
.floorplan-dialog--sheet[data-snapped] .floorplan-dialog__close { display: none; }

/* ===========================================================
 * Exhibitor modal content
 * =========================================================== */

.exhibitor-search > label {
  position: sticky;
  top: 0;
  background: #ffffff;
  padding-block: 0.5rem;
  margin-block-start: -0.5rem;
  z-index: 1;
}

.exhibitor-modal-back {
  position: sticky;
  top: 0;
  background: #ffffff;
  padding: 0.5rem 1rem 0.5rem 1rem;
  border-bottom: 1px solid #eef5fa;
  z-index: 1;
}
.exhibitor-modal-back__link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  color: #155680;
  font-weight: 500;
  font-size: 0.875rem;
  text-decoration: none;
}
.exhibitor-modal-back__link:hover { background: #eef5fa; color: #124668; }
.mode-kiosk .exhibitor-modal-back__link { min-height: 3.5rem; padding-inline: 1rem; font-size: 1rem; }

/* ===========================================================
 * Exhibitor row + detail action buttons
 *
 * Pill-shaped buttons that echo the .floorplan-fab visual language
 * (rounded, chunky padding) but tuned for white card backgrounds
 * inside the search list and detail dialog. Kiosk min-tap sizing
 * is provided separately via the .mode-kiosk [data-kiosk-tap]
 * rule earlier in this file.
 * =========================================================== */

.exhibitor-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.625rem 1.125rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, transform 120ms ease;
}
.exhibitor-action:active { transform: translateY(1px); }

.exhibitor-action--view {
  background: transparent;
  color: #111827;
  border-color: #111827;
}
.exhibitor-action--view:hover { background: rgba(17, 24, 39, 0.06); }

.exhibitor-action--show {
  background: #c99a23;
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.25);
}
.exhibitor-action--show:hover { background: #e2b53f; }

/* Detail panel: two-column layout — Website / Categories / button on
   the left, QR on the right, both top-aligned. Collapses to a single
   column on narrow screens. */
.exhibitor-detail__columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  align-items: start;
}
.exhibitor-detail__main { min-width: 0; }
@media (min-width: 600px) {
  .exhibitor-detail__columns { grid-template-columns: minmax(0, 1fr) auto; gap: 1.5rem; }
}

.exhibitor-detail__qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem;
  background: #ffffff;
  border: 1px solid #d4e6f1;
  border-radius: 0.75rem;
}
.exhibitor-detail__qr-code {
  width: 9rem;
  height: 9rem;
  display: block;
}
.exhibitor-detail__qr-code svg {
  display: block;
  width: 100%;
  height: 100%;
}
.exhibitor-detail__qr-caption {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 500;
  color: #4488b5;
  text-align: center;
}

/* Hide the exhibitor website QR on mobile — the layout has already
   collapsed to a single column and the link is still available above. */
@media (max-width: 599px) {
  .exhibitor-detail__qr {
    display: none;
  }
}

/* Dev-only path-id overlay hint. */
.floorplan-dev-hint {
  position: fixed;
  bottom: 0.75rem;
  left: 0.75rem;
  margin: 0;
  padding: 0.5rem 0.75rem;
  font-size: 0.75rem;
  color: #fde68a;
  background: rgba(14, 48, 70, 0.85);
  border-radius: 0.5rem;
  z-index: 6;
}
.floorplan-dev-hint code { font-family: ui-monospace, SFMono-Regular, monospace; }
