/* style — the shared reference library picker.
   One section of the old style.css. The pieces load in filename order
   and that order is the cascade, so do not rearrange them. */
/* ---------- Shared reference library picker ---------- */
/* ABOVE THE PANEL TABS AND THE SEAMS. Simon: "When I have the reference
   panel open, I can still see the gallery tab through the reference panel,
   and I can also click to select the dividing line through the reference
   panel." #pa-tabs and the .nle-grip seams are fixed at --z-menu (300) so
   they clear every pane; this drawer sat at 220 — under them. It is a
   full-window surface, so it stands just over that tier; modals and toasts
   (900, 950) stay above it. */
/* TWO COLUMNS NOW, not a header over a grid: the filters are a list of
   categories that has to be scrollable on its own, and a row of dropdowns
   could never hold twelve of them. The approved design Simon handed over is
   a 260px rail and everything else picture. */
#reflib {
  position: fixed; inset: 0; z-index: calc(var(--z-menu) + 10); display: flex; flex-direction: row;
  background: rgba(8,8,10,.97); backdrop-filter: blur(6px);
}
#reflib.hidden { display: none; }
.reflib-side {
  flex: 0 0 260px; min-width: 0; display: flex; flex-direction: column;
  padding: 20px 16px 10px; border-right: 1px solid var(--border);
  overflow: hidden;
}
.reflib-brand { flex: none; color: var(--text); margin: 0 0 18px 2px; }
.reflib-brand svg { display: block; }
.reflib-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.reflib-head {
  display: flex; align-items: center; gap: 12px; flex: none;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.reflib-title { font-size: 12px; font-weight: 800; letter-spacing: .4px; }
#reflib-search {
  flex: none; width: 100%; margin-bottom: 14px;
  padding: 8px 10px; font-size: 11.5px; border-radius: 3px;
  background: var(--card); border: 1px solid var(--border); color: var(--text);
}
#reflib-search:focus { border-color: var(--accent); outline: none; }
/* Prompt mirror — paints the auto-injected library line grey italic. It sits
   behind the textarea with 1:1 metrics; when active the textarea's own text
   turns transparent (caret stays) and the mirror renders everything. */
#prompt-wrap { background: var(--bg); border-radius: var(--radius); }
/* Longhand offsets, not `inset: 0`. The shorthand is late enough that an older
   CEP host can drop the whole declaration, and when it does the mirror falls
   back to its static position and shrink-to-fit width — a highlight painted
   next to the words instead of on them, under a textarea whose own letters
   have been turned transparent to let it show through. */
#prompt-mirror {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 0;
  border: 1px solid transparent; border-radius: var(--radius);
  padding: 7px 10px; font-size: 12px; line-height: 1.45; font-family: inherit;
  white-space: pre-wrap; word-wrap: break-word; overflow: hidden;
  color: var(--text); pointer-events: none;
}
#prompt-mirror:empty { display: none; }
/* GREY, AND UPRIGHT. Simon: "when we add a reference image from the
   reference gallery, the text indicator is correctly aligned... the text
   indicator appears to be placed just before the word 'only', but when you
   type, the text appears after the word 'only'."

   The injected sentence was italic here and upright in the textarea, and
   the bundled Montserrat has a real italic face whose advances are not the
   upright's: measured, the sentence laid out at 904px in the mirror against
   893px in the box. Eleven pixels by the end of the line, which is the
   caret -- drawn by the textarea -- sitting a word to the left of the
   letters you can see, which are the mirror's. Same lesson as the bold on
   .pm-ref below: nothing in here may change a glyph's advance. The colour
   alone says "this is the aside". */
#prompt-mirror .auto { color: #a9a9b2; }
/* References: pink and heavy, so a resolved @token is visible as one thing in
   the middle of a sentence. Characters additionally get a tiny thumbnail on
   the @ glyph, absolutely positioned so text metrics — and the caret sitting
   behind all this in the real textarea — stay untouched.

   AND THE WEIGHT WAS THE FIDDLY PART, exactly as the note here predicted:
   "if a future font change makes the caret wander, this rule is the first
   suspect." It did and it was. Simon: "in the prompt box, I get that issue
   where the type cursor misaligns with the text itself."

   font-weight: 700 was costing two pixels per token — measured, mirror at
   x=525 against the textarea's x=523 after one @Image1 — because the bundled
   font has a real bold with wider advances rather than the synthetic one this
   was written against. Two pixels is nothing; three tokens into a sentence it
   is six, and the caret is visibly beside the letter it belongs to.

   So the token is thickened WITHOUT changing its metrics: two hairline shadows
   in the text's own colour, which paint over the glyph edges and move nothing.
   The mirror lays out identically to the textarea again, to the pixel, and the
   token still reads as bold at a glance. Anything that sets font-weight,
   font-size, letter-spacing or font-family in here brings the drift back. */
#prompt-mirror .pm-ref {
  color: var(--accent);
  text-shadow: 0 0 0.4px currentColor, 0 0 0.4px currentColor;
}
/* Half-written, and already the right colour. Slightly softer than a finished
   token so the two are still distinguishable at a glance — this one is a
   promise, that one is a fact. */
/* Upright inside the injected sentence, so the reference reads as a reference
   rather than as part of the aside around it -- and the textarea underneath
   is upright, so this is the half of that line whose metrics were already
   right. The colour and the faux-bold come from the rule above, which matches
   a nested token just as happily. */
#prompt-mirror .auto .pm-ref { font-style: normal; }
#prompt-mirror .pm-ref.pm-part { opacity: .72; }
#prompt-mirror .pm-char { color: var(--accent); position: relative; }
/* .pm-char-thumb IS NO LONGER PAINTED. Simon: "when the @reference is added
   into the prompt, it doesn't worry about adding the little thumbnail into
   the prompt box as well. Just the pink text is fine." The rule goes with it
   rather than being left behind: a style for an element nothing emits is a
   thing the next person has to read and then discover is dead.

   position:relative stays on .pm-char above. It anchored the thumb and now
   anchors nothing, but it is also the only thing standing between this span
   and any future absolutely-positioned child, and it costs nothing.

   If it ever comes back, the shape it had is in the history and the reason it
   was absolute is in 14-prompt-mirror.js: an in-flow image adds width the
   real textarea underneath does not have, which walks the caret away from the
   letters. The node space made the same removal (.pm-ref-thumb, nodes.js). */
/* keep the mirrored textarea's own character tokens invisible but caret-true */
#prompt-wrap textarea { position: relative; z-index: 1; }
/* Dragging a picture over the prompt box — it will be described into the
   prompt, not attached. Only appears for payloads the drop actually accepts. */
#prompt-wrap textarea.describe-over {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  background: var(--accent-soft, rgba(var(--accent-rgb), .1));
}
#prompt-wrap textarea.mirrored {
  background: transparent !important;
  color: transparent; caret-color: var(--text);
}
.reflib-count { font-size: 10px; color: var(--text-faint); margin-left: auto; }
/* THE FALLBACKS ARE THE DEFAULT, not the old one. These only apply for the
   frame between the markup parsing and refLibApplyZoom running, but a grid
   that draws small and then jumps to full size is a flash of the wrong
   answer on every open. Keep the three numbers in step with RL_W_DEF in
   js/panel/15-reference-library.js. */
#reflib-grid {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 16px 18px 24px;
  display: grid;
  /* COLUMNS, NOT A MINIMUM WIDTH. auto-fill divides the room by the minimum
     and leaves the remainder down the right-hand edge, which is what made
     the old slider feel like it was doing nothing until it suddenly did a
     lot. The count comes from the ladder in 15-reference-library.js. */
  grid-template-columns: repeat(var(--rl-cols, 5), minmax(0, 1fr));
  /* 4px, per the approved design: the pictures are the index, and a wide
     gutter between them turns a contact sheet into a list. */
  gap: 4px; align-content: start;
}
/* Explicit height rather than aspect-ratio: CEP's Chromium collapses these to
   zero height otherwise, which stacks every card on top of the next. */
.reflib-item {
  position: relative; cursor: pointer; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--card);
  height: var(--rl-h, 188px);
}
/* A longer track, because it covers a much wider range now and a 90px slider
   made every step a jump. */
#reflib-zoom { width: 130px; flex: none; }
/* THE TWO ENDS OF THE ZOOM ARE TARGETS NOW. Simon: "make it so the plus and
   minus icons for adjusting the zoom are larger for the thumbnail size."
   They were 12px glyphs inside the label, which made them the smallest
   things in a row of controls and the only ones that did nothing when
   pressed. One press is one column. */
.reflib-zoomstep {
  flex: none; width: 24px; height: 24px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font: inherit; font-size: 19px; line-height: 1;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--text-dim); cursor: pointer;
}
.reflib-zoomstep:hover { color: #fff; border-color: var(--accent); background: var(--card-hover); }
.reflib-zoomstep:active { background: var(--accent-soft, rgba(var(--accent-rgb), .14)); }
/* THE ONE THING IN THE ROW THAT ADDS ANYTHING, and it says so. A bare + next
   to a bare × is two mystery glyphs a centimetre apart, and the one that
   uploads to the shared team library is the wrong one to leave guessable. */
.reflib-addbtn {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px; white-space: nowrap; cursor: pointer;
  font: inherit; font-size: 11px; color: #fff;
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  background: var(--accent-soft, rgba(var(--accent-rgb), .12));
}
.reflib-addbtn:hover { background: var(--accent); }
.reflib-addplus { font-size: 15px; line-height: 1; }
.reflib-item:hover { border-color: var(--accent); }
/* CONTAIN ON BLACK, not cover. Simon's design: "pure black thumbnail
   backgrounds". A frame is a composition and cropping it to fill a tile
   throws away the thing somebody is choosing it for -- the edges. Black
   rather than the card colour so the letterboxing reads as the picture's
   own shape and not as a gap in the grid. */
.reflib-item { background: #000; border-color: transparent; }
.reflib-item img { width: 100%; height: 100%; object-fit: contain; display: block; -webkit-user-drag: none; }
.reflib-status { flex: none; padding: 8px 14px 12px; font-size: 10.5px; color: var(--text-dim); }
.reflib-status a { color: var(--accent); }

/* Star button on empty image reference cards → opens the reference library.
   NOTE: #input-slots .slot-label is display:none, so slot-level controls must
   live inside the cards themselves, not in the label row. */
.ec-btn.ec-star { color: var(--accent); }
.ec-btn.ec-star:hover { color: #fff; background: var(--accent); border-color: var(--accent); }

/* ---------- the categories, down the side ----------

   Twelve categories, one selection each, combining with AND. A row is a
   radio in everything but name: pressing the one that is already on turns it
   off, pressing another in the same category replaces it. That is Simon's
   rule and it is what makes the list usable without a Clear button --
   nothing can accumulate.

   The rail scrolls; the search box and the active list above it do not. */
.reflib-filters {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-width: thin;
}
.reflib-active { flex: none; display: grid; gap: 2px; margin-bottom: 14px; }
.reflib-active:empty { display: none; }
.reflib-cat { border-top: 1px solid var(--border); }
.reflib-cat > summary {
  display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer;
  padding: 11px 2px; font-size: 11.5px; color: var(--text-dim);
}
.reflib-cat > summary::-webkit-details-marker { display: none; }
.reflib-cat > summary::before { content: '\203A'; color: var(--text-faint); transition: transform .15s; }
.reflib-cat[open] > summary::before { transform: rotate(90deg); color: var(--accent); }
.reflib-cat > summary:hover { color: var(--text); }
.reflib-catn { margin-left: auto; color: var(--accent); font-size: 10px; }
.reflib-cattags {
  padding: 0 0 10px; display: flex; flex-direction: column; gap: 1px;
  max-height: 260px; overflow-y: auto; scrollbar-width: thin;
}
/* THE ROW IS THE TARGET, not the dot: an 11px circle is a thing you miss,
   and every other toggle in this app is a whole word wide. */
.reflib-tagrow {
  display: flex; align-items: center; gap: 9px; width: 100%; min-height: 30px;
  font: inherit; font-size: 11.5px; padding: 5px 8px; border: 0; border-radius: 2px;
  background: transparent; color: var(--text-dim); text-align: left; cursor: pointer;
  line-height: 1.35; overflow-wrap: anywhere;
}
.reflib-tagrow::before {
  content: ''; width: 11px; height: 11px; flex: 0 0 11px; box-sizing: border-box;
  border: 1px solid var(--border-dash); border-radius: 50%;
}
.reflib-tagrow:hover { color: var(--text); background: var(--card-hover); }
.reflib-tagrow[aria-pressed="true"] {
  color: #fff; background: var(--accent-soft); box-shadow: inset 2px 0 var(--accent);
}
.reflib-tagrow[aria-pressed="true"]::before {
  border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 2px #171014;
}
.reflib-active .reflib-tagrow::after { content: '\00d7'; margin-left: auto; color: var(--accent); font-size: 15px; }
.reflib-zoomwrap {
  display: flex; align-items: center; gap: 8px; margin-left: auto;
  color: var(--text-faint); font-size: 12px;
}
.reflib-tagbar {
  display: flex; align-items: center; gap: 10px; flex: none; flex-wrap: wrap;
  padding: 8px 14px; border-bottom: 1px solid var(--border);
}
.reflib-tagbar.hidden { display: none; }
/* The tag bar is the one that CHANGES things, and it sits two centimetres from
   a row that only narrows what you can see. Tinted so the difference is
   visible before you have read either of them. */
.reflib-tagbar { background: rgba(var(--accent-rgb, 255,60,120), .07); }
.reflib-tagcount { font-size: 10px; color: var(--text-dim); margin-left: auto; }

/* THE ROW OF DROPDOWNS IS GONE, and so are the captions and the tag line that
   used to sit on every card. Both were answers to a question the new gallery
   asks differently: the categories are a rail you scan down, and the tiles
   are pictures with nothing written on them -- Simon: "images-only gallery:
   no visible film-title or tag captions". The names are still the tile's
   accessible name and its tooltip, which is where a name belongs when it is
   not the thing you are choosing by. */
/* In tag mode the cards are targets rather than doors, and the one thing that
   has to be unmistakable is which ones are already selected — an accidental
   Apply over the wrong thirty is a slow thing to undo. */
#reflib.tagging .reflib-item { cursor: cell; }
#reflib.tagging .reflib-item.picked { border-color: var(--accent); }
#reflib.tagging .reflib-item.picked::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 3px var(--accent);
}
