/* ===================================================================
   Shared library card grid
   ===================================================================
   ONE definition of the "library card" look, used by every library page
   that presents its items as art cards (Characters, Monsters, …). Pages
   own their data, actions and popup copy; this file owns the
   presentation, so the libraries cannot drift apart visually — restyle
   here and every card library follows.

   Expected markup:
     .lib-toolbar > .lib-create-btn + .lib-search + .lib-tool-btn* + .lib-count
     .lib-grid    > .lib-card*
     .lib-card    > .lib-art  ( .lib-fallback, .lib-img-btn, .lib-actions )
                  + .lib-meta ( .lib-name, .lib-sub )

   Colours come from the page's theme variables (--bark, --crimson, …)
   with the dark palette as a fallback, so a page that forgets to define
   them still renders correctly.
   =================================================================== */

/* ── Toolbar ─────────────────────────────────────────────────────── */
.lib-toolbar{display:flex;align-items:center;gap:12px;margin-bottom:20px;flex-wrap:wrap;}
.lib-search{flex:1;min-width:220px;padding:10px 14px;background:var(--bark);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-family:"Crimson Text",Georgia,serif;font-size:15px;}
.lib-search:focus{border-color:var(--crimson);outline:none;}
.lib-count{color:var(--gold-dim);font-size:13px;font-style:italic;white-space:nowrap;}
.lib-create-btn{display:inline-flex;align-items:center;gap:6px;padding:10px 20px;border:2px dashed var(--border);border-radius:8px;background:transparent;color:var(--gold-dim);font-family:'Cinzel',serif;font-size:12px;font-weight:600;letter-spacing:1px;text-decoration:none;cursor:pointer;transition:all .2s;}
.lib-create-btn:hover{border-color:var(--crimson);color:var(--crimson-hover);background:rgba(var(--accent-rgb),.05);}
.lib-create-btn span{font-size:16px;line-height:1;}
/* Secondary toolbar actions (Multi Select, Import JSON, …). Matches the
   accordion libraries' toolbar buttons so the two families stay familiar. */
.lib-tool-btn{padding:7px 14px;border-radius:5px;border:1px solid var(--border);background:transparent;color:var(--ink-mid);font-family:'Cinzel',serif;font-size:10px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;cursor:pointer;transition:all .2s;white-space:nowrap;}
.lib-tool-btn:hover{border-color:var(--crimson);color:var(--text-strong);background:rgba(var(--accent-rgb),.08);}
.lib-tool-btn.active{background:var(--crimson);color:var(--text-on-crimson);border-color:var(--crimson);}

/* ── Card grid ───────────────────────────────────────────────────── */
.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:20px;}
.lib-card{position:relative;aspect-ratio:3/4;border:1px solid var(--border);border-radius:12px;overflow:hidden;background:var(--bark);cursor:pointer;transition:border-color .2s,box-shadow .25s,transform .15s;box-shadow:0 2px 10px rgba(var(--shade-rgb),.35);}
/* Grows toward you on hover. The two curves are deliberately different: it
   eases OUT on the way in so it arrives softly, and eases IN on the way back so
   it lets go gently instead of snapping flat. Opacity rides the same timing so
   a dimmed card brightens as it lifts. */
.lib-card:hover{border-color:var(--crimson);box-shadow:0 14px 34px rgba(var(--accent-rgb),.26);transform:translateY(-6px) scale(1.035);z-index:1;}
/* "New …" tile — the first card in the grid. Matches a real card's footprint
   so the grid stays even, but reads as an empty slot waiting to be filled. */
.lib-create-card{display:flex;align-items:center;justify-content:center;text-align:center;aspect-ratio:3/4;border:2px dashed var(--border);border-radius:12px;background:transparent;box-shadow:none;color:var(--gold-dim);font-family:'Cinzel',serif;font-size:13px;font-weight:600;letter-spacing:1px;text-decoration:none;cursor:pointer;transition:all .2s;min-height:100%;padding:20px;}
.lib-create-card:hover{border-color:var(--crimson);color:var(--crimson-hover);background:rgba(var(--accent-rgb),.05);transform:translateY(-6px) scale(1.035);box-shadow:none;}
/* Fills the card rather than setting its height: the name bar overlays the
   bottom of this, so the art has to run the whole way down or the bar simply
   eats part of the picture instead of sitting over it. */
.lib-art{position:absolute;inset:0;width:100%;height:100%;background:linear-gradient(160deg,var(--bark-light) 0%,var(--bark-deep) 100%);background-size:cover;background-position:center 20%;}
.lib-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--gold-dim);opacity:.5;}
.lib-art.has-img .lib-fallback{display:none;}
.lib-art.has-img::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,var(--media-veil),transparent 45%);pointer-events:none;}
.lib-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:var(--media-scrim);color:var(--text-on-media);cursor:pointer;transition:background .15s,color .15s,transform .12s;backdrop-filter:blur(2px);}
.lib-icon:hover{background:var(--media-scrim-strong);transform:scale(1.08);}
.lib-icon svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
.lib-icon.lib-danger:hover{background:var(--accent-strong);color: var(--text-on-accent);}
.lib-img-btn{position:absolute;top:8px;left:8px;z-index:2;opacity:0;transition:opacity .15s;}
.lib-actions{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:2;opacity:0;transition:opacity .15s;}
.lib-card:hover .lib-img-btn,.lib-card:hover .lib-actions{opacity:1;}
/* Touch devices have no hover — keep the controls visible there. */
@media (hover:none){.lib-img-btn,.lib-actions{opacity:1;}}
/* The name bar sits OVER the artwork rather than under it, so the picture
   fills the whole card and you can still see it behind the text. 75% of the
   panel colour, blurred a little, so the name stays readable over whatever is
   underneath. color-mix rather than an rgba() token because no theme defines
   --bark as channels; the flat colour above it is the fallback. */
.lib-meta{position:absolute;left:0;right:0;bottom:0;padding:11px 13px 13px;background:var(--bark);background:color-mix(in srgb, var(--bark) 75%, transparent);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);}
.lib-name{font-family:"Cinzel",serif;font-size:16px;font-weight:700;color:var(--ink);letter-spacing:.3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.lib-sub{margin-top:3px;font-size:13px;color:var(--gold-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.lib-empty{text-align:center;color:var(--gold-dim);font-style:italic;padding:60px 0;}
.lib-empty .ico{font-size:42px;margin-bottom:10px;opacity:.6;}

/* ── Kind / source filter row ─────────────────────────────────────
   A centred segmented control under the search bar, used by every library
   that splits its contents (Creatures vs NPCs, SRD vs Custom). Larger than
   the toolbar buttons because it's the main way you move between views. */
.lib-kind-filter{display:flex;gap:0;justify-content:center;margin:0 0 20px;}
.lib-kind-filter .lib-tool-btn{border-radius:0;margin-left:-1px;font-size:14px;letter-spacing:1px;padding:11px 26px;}
.lib-kind-filter .lib-tool-btn:first-child{border-radius:6px 0 0 6px;margin-left:0;}
.lib-kind-filter .lib-tool-btn:last-child{border-radius:0 6px 6px 0;}
/* Corner tag on a card — marks an NPC, an SRD entry, GM-shared content, … */
/* Lifted clear of the name bar, which now overlays the bottom of the art. */
.lib-kind-badge{position:absolute;left:8px;bottom:66px;z-index:2;background:var(--crimson);color:var(--text-on-crimson);font-family:'Cinzel',serif;font-size:9px;font-weight:700;letter-spacing:.8px;padding:2px 7px;border-radius:999px;box-shadow:0 2px 6px rgba(var(--shade-rgb),.5);}

/* ── Drag to reorder (see shared/card-reorder.js) ──────────────────
   Cards are for clicking and dragging, not for reading off: leaving them
   selectable means every reorder ends in a swathe of blue highlight, which
   then swallows the start of the next drag. While a card is in hand the
   pointer ranges over the whole page, so the ban has to widen for the
   duration or the drag paints a selection across everything it crosses. */
.lib-grid{user-select:none;-webkit-user-select:none;}
body.sb-card-dragging{user-select:none;-webkit-user-select:none;}
/* The card in hand: lifted, following the cursor with no transition (one
   here would lag behind the pointer). pointer-events:none so the hit test
   under the cursor finds the card BENEATH it, not the card being held. */
.lib-card.dragging{transition:none;z-index:20;cursor:grabbing;pointer-events:none;box-shadow:0 18px 44px rgba(var(--shade-rgb),.6);opacity:.92;}
/* The rest glide aside. The hover lift would fight that mid-flight. */
.lib-grid.is-dragging .lib-card{cursor:grabbing;}
.lib-grid.is-dragging .lib-card:hover{transform:none;box-shadow:0 2px 10px rgba(var(--shade-rgb),.35);}
.lib-grid .lib-card{transition:transform .34s cubic-bezier(.25,.8,.3,1),box-shadow .34s cubic-bezier(.25,.8,.3,1),opacity .28s cubic-bezier(.25,.8,.3,1),border-color .2s;}
.lib-grid .lib-card:hover{transition:transform .26s cubic-bezier(.2,.65,.3,1),box-shadow .26s cubic-bezier(.2,.65,.3,1),opacity .2s cubic-bezier(.2,.65,.3,1),border-color .2s;}
/* The create tile lifts the same way so the row reads as one set. */
.lib-create-card{transition:transform .34s cubic-bezier(.25,.8,.3,1),border-color .2s,color .2s,background .2s;}
.lib-create-card:hover{transition:transform .26s cubic-bezier(.2,.65,.3,1),border-color .2s,color .2s,background .2s;}
@media (prefers-reduced-motion:reduce){
  .lib-grid .lib-card{transition:border-color .2s,box-shadow .25s;}
}

/* ── Selection (ctrl/shift-click — see shared/library-select.js) ──── */
/* .lib-grid.is-selecting is set whenever at least one card is selected. The
   per-card action icons stay available: the bin is what deletes the whole
   selection, so hiding it would take away the obvious way to act on one. */
.lib-grid.is-selecting .lib-card{cursor:pointer;}
.lib-card.is-selected{border-color:var(--crimson);box-shadow:0 0 0 2px var(--crimson),0 8px 24px rgba(var(--accent-rgb),.25);}
.lib-check{position:absolute;top:8px;right:8px;z-index:3;width:26px;height:26px;border-radius:50%;border:2px solid var(--media-line);background:var(--media-veil);display:none;align-items:center;justify-content:center;backdrop-filter:blur(2px);}
.lib-grid.is-selecting .lib-check{display:flex;}
.lib-card.is-selected .lib-check{background:var(--crimson);border-color:var(--crimson);}
.lib-check svg{width:15px;height:15px;stroke:var(--text-on-media);fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;opacity:0;}
.lib-card.is-selected .lib-check svg{opacity:1;}

/* ── Popups (image menu, AI generation, action menus) ────────────── */
.lib-pop-overlay{display:none;position:fixed;inset:0;background:rgba(var(--shade-rgb),.7);z-index:10000;align-items:center;justify-content:center;padding:20px;}
.lib-pop-overlay.open{display:flex;}
.lib-pop-box{background:var(--bark);border:1px solid var(--border);border-top:3px solid var(--crimson);border-radius:12px;max-width:420px;width:100%;padding:22px;box-shadow:0 12px 48px rgba(var(--shade-rgb),.6);}
.lib-pop-title{font-family:"Cinzel",serif;font-size:17px;font-weight:700;color:var(--ink);letter-spacing:.5px;margin-bottom:4px;}
.lib-pop-sub{font-size:13px;color:var(--gold-dim);margin-bottom:16px;line-height:1.45;}
.lib-opt{display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:var(--bark-dark);border:1px solid var(--border);border-radius:8px;padding:12px 14px;margin-bottom:8px;cursor:pointer;color:var(--ink);font-family:"Crimson Text",Georgia,serif;font-size:15px;transition:border-color .15s,background .15s;}
.lib-opt:hover{border-color:var(--crimson);background:rgba(var(--accent-rgb),.08);}
.lib-opt .oico{font-size:18px;width:22px;text-align:center;}
.lib-opt.danger:hover{border-color:var(--accent-strong);background:rgba(185,28,28,.12);}
.lib-pop-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:12px;}
.lib-ta{width:100%;min-height:74px;padding:10px 12px;background:var(--bark-dark);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-family:"Crimson Text",Georgia,serif;font-size:14px;resize:vertical;}
.lib-ta:focus{border-color:var(--crimson);outline:none;}
.lib-style-label{font-family:'Cinzel',serif;font-size:11px;letter-spacing:1px;text-transform:uppercase;color:var(--gold-dim);margin:14px 0 6px;}
.lib-styles{display:flex;gap:8px;}
.lib-style{flex:1;background:var(--bark-dark);border:1px solid var(--border);border-radius:6px;padding:9px 6px;cursor:pointer;font-family:'Cinzel',serif;font-size:12px;font-weight:700;color:var(--gold-dim);transition:all .15s;}
.lib-style:hover{border-color:var(--crimson);}
.lib-style.is-on{border-color:var(--crimson);background:rgba(var(--accent-rgb),.12);color:var(--text-strong);}
.lib-ai-loading{display:none;align-items:center;gap:8px;color:var(--gold-dim);font-size:13px;margin-top:12px;}
.lib-ai-loading.show{display:flex;}
.lib-spin{width:16px;height:16px;border:2px solid var(--border);border-top-color:var(--crimson);border-radius:50%;animation:lib-spin 1s linear infinite;}
@keyframes lib-spin{to{transform:rotate(360deg);}}
.lib-ai-error{color:var(--accent-bright);font-size:13px;margin-top:10px;min-height:1px;}
