/* <scraptable-table> wraps OpenSeadragon and any number of overlay children
   that Lustre renders as light-DOM siblings of the injected .scraptable-osd-host
   and .scraptable-loader. CSS positions everything against the element itself. */

scraptable-table {
  display: block;
  position: fixed;
  inset: 0;
  background: oklch(98.4% 0.003 247.858);
  overflow: hidden;
}

.scraptable-osd-host {
  position: absolute;
  inset: 0;
  /* Suppress browser-level pan/zoom so OSD owns all touch gestures. */
  touch-action: none;
}

.scraptable-loader {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.7);
  z-index: 9999;
  /* Hidden by default — JS toggles via element.hidden. */
}

.scraptable-loader[hidden] {
  display: none;
}

/* An <img> — the art is /static/images/spinner.png (drop in a square image;
   the rotation comes from CSS, so the art itself should be a still frame). */
.scraptable-spinner {
  width: 3rem;
  height: 3rem;
  animation: scraptable-spin 0.9s linear infinite;
}

@keyframes scraptable-spin {
  to { transform: rotate(360deg); }
}

/* Overlays — anything Lustre puts inside <scraptable-table> that isn't our
   injected host/loader. The overlay component sets transform + z-index. */
.scraptable-overlay {
  position: absolute;
  top: 0;
  left: 0;
  /* Click on the overlay content itself, not the surrounding rect. */
  pointer-events: auto;
}

/* Chrome — corner/edge-anchored floating UI (toolbars, a FAB). Content-sized so
   the canvas stays draggable in the gaps; sits above user overlays (z ≤ 999),
   below the loader (9999). env(safe-area-inset-*) clears notches (the page is
   viewport-fit=cover). Note the navigator/minimap lives top-left — the
   settings gear owns top-right, the upload FAB bottom-right. */
.scraptable-chrome {
  position: absolute;
  z-index: 1000;
  margin: 0.75rem;
  pointer-events: auto;
}
.scraptable-chrome.top-left { top: env(safe-area-inset-top); left: env(safe-area-inset-left); }
.scraptable-chrome.top-right { top: env(safe-area-inset-top); right: env(safe-area-inset-right); }
.scraptable-chrome.bottom-left { bottom: env(safe-area-inset-bottom); left: env(safe-area-inset-left); }
.scraptable-chrome.bottom-right { bottom: env(safe-area-inset-bottom); right: env(safe-area-inset-right); }
.scraptable-chrome.top-center,
.scraptable-chrome.bottom-center { left: 50%; transform: translateX(-50%); }
.scraptable-chrome.top-center { top: env(safe-area-inset-top); }
.scraptable-chrome.bottom-center { bottom: env(safe-area-inset-bottom); }

/* While the image drawer (css/room.css) is up, the bottom chrome rides up
   with it, keeping a constant distance from the drawer's top edge. The
   drawer panel reads the same variable for its height. Set on :root for the
   document-level link and on :host for the copy adopted into the server
   component's shadow root. */
:root,
:host {
  --st-drawer-height: 25dvh;
}
.scraptable-chrome.bottom-left,
.scraptable-chrome.bottom-right,
.scraptable-chrome.bottom-center {
  transition: transform 0.25s ease;
}
scraptable-table.st-drawer-open .scraptable-chrome.bottom-left,
scraptable-table.st-drawer-open .scraptable-chrome.bottom-right {
  transform: translateY(calc(-1 * var(--st-drawer-height)));
}
scraptable-table.st-drawer-open .scraptable-chrome.bottom-center {
  transform: translate(-50%, calc(-1 * var(--st-drawer-height)));
}

/* The "+" FAB reads as an X while the drawer is open. Rotate the whole
   button so its hover/pressed box turns with the art. */
#add-scrap .st-img-button {
  transition: transform 0.25s ease;
}
scraptable-table.st-drawer-open #add-scrap .st-img-button {
  transform: rotate(45deg);
}

/* Other clients' viewport rects — OSD overlays in viewport coordinates,
   colored per user. The name label hangs off the top-left corner. */
.st-presence {
  border: 2px solid #d3d3d3;
  box-sizing: border-box;
  pointer-events: none;
}
.st-presence-name {
  position: absolute;
  bottom: 100%;
  left: -2px;
  font-size: 11px;
  line-height: 1.5;
  color: white;
  background: #d3d3d3;
  padding: 0 5px;
  border-radius: 3px 3px 3px 0;
  white-space: nowrap;
}

/* Selection bounding box — one per selecting user, in their color. */
.st-selection {
  border: 2px solid #d3d3d3;
  box-sizing: border-box;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

/* Own-selection chrome (delete X, link button, scale handle). The controls re-enable
   pointer events inside the pointer-events:none box, and are sized in px so
   they stay constant on screen while OSD scales the box itself. */
.st-selection-mine {
  overflow: visible;
}

/* Plain image controls (art from /static/images/buttons/): gray tint +
   border on hover, darker while pressed — same treatment as .st-img-button
   in room.css, sized down for the selection chrome. */
.st-sel-delete,
.st-sel-scale {
  pointer-events: auto;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  cursor: pointer;
}

.st-sel-delete img,
.st-sel-scale img {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.st-sel-delete:hover,
.st-sel-scale:hover {
  background: rgb(128 128 128 / 0.18);
  border-color: gray;
}

.st-sel-delete:active,
.st-sel-scale:active {
  background: rgb(128 128 128 / 0.35);
}

.st-sel-delete:active img,
.st-sel-scale:active img {
  filter: brightness(0.75);
}

.st-sel-delete {
  position: absolute;
  top: -11px;
  right: -11px;
}

/* The drag-to-scale handle in the bottom-right corner — a diagonal
   double-ended arrow, visible whenever the delete X is. */
.st-sel-scale {
  position: absolute;
  bottom: -11px;
  right: -11px;
  cursor: nwse-resize;
  /* The handle owns its touch gestures — no browser pan/zoom mid-scale. */
  touch-action: none;
}
