/* ===========================================
   SEND-TO MENU  (specs/send-menu-premium.md)

   The single stylesheet for the per-item "Send to…" menu. It used to be split
   three ways — css/components.css, an inline <style> in index.html, and a more
   specific library-only override in css/library.css — which is why the same
   menu looked different on a library card than on a generate card. All three
   are gone; this file is the only place these classes are styled, and it is
   linked AFTER css/main.css so it wins the cascade without !important.

   Feel: macOS / Notion context menu. Thin monochrome line icons in a fixed
   slot, quiet hairline dividers between groups, soft rounded panel with a
   hairline border and a neutral (not pink) hover.
   =========================================== */

/* Anchor for the trigger button; the panel itself is a body-level portal. */
.send-to-container {
  position: relative;
}

/* ---------- Panel ---------------------------------------------------- */

.send-to-menu {
  position: fixed;
  display: none;
  flex-direction: column;
  gap: 1px;
  box-sizing: border-box;
  min-width: min(220px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  padding: 6px;
  background: rgba(30, 30, 32, 0.94);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  overscroll-behavior: contain;
  scrollbar-width: thin;
  /* How far a row sits inside the panel edge (6px padding + 1px border). The
     folder flyout adds it back so the visible gap is between the two PANELS,
     not between the flyout and the row that opened it. */
  --send-panel-inset: 7px;
  /* Scale-in grows from the corner the menu actually opened towards. */
  transform-origin: bottom right;
  z-index: 10000;
}

.send-to-menu.active {
  display: flex;
}

.send-to-menu.opens-down {
  transform-origin: top right;
}

.send-to-menu[data-align="center"] {
  transform-origin: bottom center;
}

.send-to-menu.opens-down[data-align="center"] {
  transform-origin: top center;
}

.send-to-menu.viewport-constrained {
  overflow-y: auto;
}

/* Frosted glass is progressive: paint an opaque panel where it is unsupported
   so the menu never renders as a translucent smear over the grid. */
@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))) {
  .send-to-menu,
  .send-folder-menu {
    background: var(--bg-elevated);
  }
}

/* ---------- Rows ------------------------------------------------------ */

.send-to-option,
.send-folder-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* The panel is a flex column with a max-height; without this the rows shrink
     below their min-height the moment the menu has to scroll — which is exactly
     the case on a phone, where the rows need to stay touch-sized. */
  flex: 0 0 auto;
  min-height: 32px;
  padding: 0 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.send-to-option:hover,
.send-to-option:focus-visible,
.send-folder-item:hover,
.send-folder-item:focus-visible {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-primary);
  outline: none;
}

/* Keyboard focus is driven by .focus() from the controller, so the plain
   :focus state has to read as selected too — not just :focus-visible. */
.send-to-option:focus,
.send-folder-item:focus {
  background: rgba(255, 255, 255, 0.08);
  outline: none;
}

.send-to-option:disabled,
.send-folder-item:disabled {
  opacity: 0.4;
  cursor: default;
}

.send-to-option:disabled:hover,
.send-folder-item:disabled:hover {
  background: transparent;
}

/* ---------- Icons ----------------------------------------------------- */

.send-to-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  color: var(--text-secondary);
  transition: color 0.12s ease;
}

.send-to-icon svg {
  width: 16px;
  height: 16px;
  display: block;
}

.send-to-option:hover .send-to-icon,
.send-to-option:focus .send-to-icon,
.send-folder-item:hover .send-to-icon,
.send-folder-item:focus .send-to-icon {
  color: var(--text-primary);
}

.send-to-label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- Character label slot --------------------------------------- */

/* ProductModelCatalog.characterLabelHtml() renders every character name in the
   app: the generation picker's combobox trigger and option rows, the inpaint
   picker, and the Library's character filter. Same 16px-in-20px currentColor
   slot as .send-to-icon above, but INLINE rather than a flex child, because
   the two places it lands — .lora-combobox-label and .lora-combobox-option —
   are block boxes that ellipsise their own overflow. Making them flex would
   take that ellipsis away from every non-character label they also carry (the
   anatomy LoRA filenames are long). `flex: 0 0 20px` is harmless where the
   parent happens to be a flex row and keeps the slot from being squeezed. */
.char-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  margin-right: 4px;
  vertical-align: middle;
  color: var(--text-secondary, #999);
}

.char-icon svg {
  width: 16px;
  height: 16px;
  display: block;
}

/* The name sits at full strength beside a muted glyph — the same two-tone
   reading as a Send-to row. `vertical-align` keeps the pair on one optical
   line whatever the row's font-size is. */
.char-name {
  vertical-align: middle;
}

/* css/theme-light.css paints every <span> #1d1d1f (`.light-theme span`, 0-1-1),
   which outranks both rules above at 0-1-0 — the same trap css/library.css
   documents for .library-detail-icon.
   Wrapping the name in a <span> — which is what carrying a glyph beside it
   requires — handed the blanket rule a target it never had while the name was
   a bare text node.
   (It used to bite hardest of all inside .lora-combobox, whose dropdown kept a
   hard-coded dark panel in BOTH themes. css/lora-combobox.css gives that
   component a real light theme now, so the row underneath is white — but the
   rules below are still what keeps the glyph and the name on the same colour.)
   So: colour the ROW and let both halves follow it, exactly as css/library.css
   concluded for .library-sidebar-item. `inherit`/`currentColor` resolve to
   .lora-combobox-option's own --text-primary, which is what the plain
   non-character rows beside them already use. */
.light-theme .char-icon {
  color: currentColor;
}

.light-theme .char-name {
  color: inherit;
}

/* ---------- Group dividers -------------------------------------------- */

.send-to-divider {
  flex: 0 0 auto;
  height: 1px;
  margin: 4px 0;
  background: rgba(255, 255, 255, 0.08);
}

/* ---------- Folder submenu -------------------------------------------- */

.send-folder-submenu {
  position: relative;
  flex: 0 0 auto;
}

.send-folder-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--text-secondary);
  transition: color 0.12s ease;
}

.send-folder-chevron svg {
  width: 14px;
  height: 14px;
  display: block;
}

.send-folder-trigger:hover .send-folder-chevron,
.send-folder-trigger:focus .send-folder-chevron {
  color: var(--text-primary);
}

.send-folder-menu {
  position: absolute;
  top: 0;
  /* 8px gap from the parent panel, on whichever side it opens. */
  right: calc(100% + 8px + var(--send-panel-inset, 0px));
  display: none;
  flex-direction: column;
  gap: 1px;
  min-width: 190px;
  max-width: min(280px, calc(100vw - 24px));
  max-height: min(280px, calc(100vh - 24px));
  overflow-y: auto;
  padding: 6px;
  background: rgba(30, 30, 32, 0.94);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  z-index: 10001;
}

.send-folder-submenu:hover .send-folder-menu,
/* :not([data-keyboard-closed]) — ArrowLeft/Escape returns focus to the trigger,
   which is inside this container; without the guard :focus-within would
   immediately reopen the flyout the user just closed. */
.send-folder-submenu:focus-within:not([data-keyboard-closed]) .send-folder-menu,
.send-folder-submenu.open .send-folder-menu {
  display: flex;
}

.send-folder-submenu.opens-right .send-folder-menu {
  right: auto;
  left: calc(100% + 8px + var(--send-panel-inset, 0px));
}

/* When the panel had to scroll to fit the viewport, the submenu folds inline
   instead of flying out — an absolutely positioned flyout inside a scroll
   container gets clipped. */
.send-to-menu.viewport-constrained .send-folder-menu {
  position: static;
  min-width: 0;
  max-width: 100%;
  width: 100%;
  margin: 2px 0 4px;
  padding: 2px;
  border: 0;
  border-radius: 6px;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: rgba(255, 255, 255, 0.04);
}

.send-to-menu.viewport-constrained .send-folder-submenu.opens-right .send-folder-menu {
  left: auto;
  right: auto;
}

.send-folder-empty {
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  text-align: left;
  white-space: normal;
  cursor: default;
}

/* ---------- Motion ---------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .send-to-menu.active {
    animation: sendToMenuIn 120ms ease-out;
  }
}

@keyframes sendToMenuIn {
  from {
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* ---------- Light theme ----------------------------------------------- */

.light-theme .send-to-menu,
.light-theme .send-folder-menu {
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(0, 0, 0, 0.1);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16);
}

@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))) {
  .light-theme .send-to-menu,
  .light-theme .send-folder-menu {
    background: #ffffff;
  }
}

.light-theme .send-to-option:hover,
.light-theme .send-to-option:focus,
.light-theme .send-to-option:focus-visible,
.light-theme .send-folder-item:hover,
.light-theme .send-folder-item:focus,
.light-theme .send-folder-item:focus-visible {
  background: rgba(0, 0, 0, 0.06);
}

.light-theme .send-to-divider {
  background: rgba(0, 0, 0, 0.08);
}

.light-theme .send-to-menu.viewport-constrained .send-folder-menu {
  background: rgba(0, 0, 0, 0.04);
}

/* ---------- Touch ----------------------------------------------------- */

@media (max-width: 480px) {
  .send-to-option,
  .send-folder-item {
    min-height: 40px;
  }
}
