/* style — the dev width ruler.
   One section of the old style.css. The pieces load in filename order
   and that order is the cascade, so do not rearrange them. */
/* ---------- THE DEV WIDTH RULER ----------

   Only ever drawn while `html.devw` is on, which only the dev switch sets. It
   has to be legible over anything — a black viewer, a white plate, a gallery
   of thumbnails — so it is its own chip rather than plain text, and it must
   never be in the way of the drag it exists to help with: pointer-events off,
   and pinned to the corner rather than the middle. */
html.devw #main, html.devw #gallery-pane, html.devw #nle-viewer,
html.devw #nle-bin, html.devw #nle-insp, html.devw #app, html.devw #nle-timeline {
  position: relative;
}
.devw-tag {
  position: absolute; right: 3px; bottom: 3px; z-index: var(--z-toast);
  padding: 2px 6px; border-radius: 3px; pointer-events: none;
  background: rgba(var(--accent-rgb), .92); color: #fff;
  font: 700 9.5px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .3px; font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
#gallery-scale {
  width: 62px; height: 3px; padding: 0; border: none;
  -webkit-appearance: none; appearance: none;
  border-radius: 3px; background: var(--border); outline: none; cursor: pointer;
}
#gallery-scale::-webkit-slider-thumb {
  -webkit-appearance: none; width: 10px; height: 10px; border-radius: 50%;
  background: var(--text-dim); border: none;
}
#gallery-scale::-webkit-slider-thumb:hover { background: var(--accent); }
.icon-btn.small { font-size: 12px; padding: 2px 5px; }
/* Auto-fill grid: --gal-min (slider, in px) is the SMALLEST a thumbnail may
   be, and the grid fits as many of those across as the pane is wide — so
   dragging the panel out adds columns instead of inflating two pictures.
   1fr on the upper bound lets the last row share out the remainder, so the
   tiles stay flush to both edges at any width.
   flex:1 + min-height:0 lets the grid shrink to the pane and actually scroll —
   without it the flex item refuses to shrink and rows get clipped/squashed. */
/* Single scroll region for both the generating (pending) cards and finished
   gallery items, so pending cards flow inline and scroll like normal thumbs. */
#gallery-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-bottom: 14px;
}
#gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--gal-min, 158px), 1fr)); justify-content: stretch;
  gap: 7px; align-content: start; grid-auto-rows: max-content;
}
#gallery .gal-item { width: 100%; min-width: 0; }
/* #gallery-pending is a single horizontally-scrolling row now (see the
   Simon comment on #gallery-pending in 15-layout.css) -- width:100% on a
   flex item with no basis just squeezes every tile down to fit the pane,
   which is the exact "squares get crowded and tiny" look a scrollbar was
   asked for instead of. Fixed size, and flex:0 0 that size so nothing
   shrinks to make room for a sibling -- overflow-x handles the rest. */
/* ...AND A QUARTER OF THE SIZE OF A FINISHED ONE.

   Simon: "When the items are being generated in the gallery space, we need
   the thumbnail for them to be much smaller, as at the moment it pushes the
   gallery space too far down. If we're doing multiple generations, let's make
   it so the preview generation boxes in the gallery space are a quarter of
   the size of the main objects in the gallery space."

   A pending tile was exactly the size of a finished one, and three of them
   wrapping across a narrow pane is a full row of grey squares between you and
   everything you have already made. Half the width is a quarter of the area,
   which is the reading that leaves the ring, the state line and the maker's
   mark still legible -- a quarter of the WIDTH would be a 40px square with a
   30px ring in it and nothing else visible.

   Floored at 72 rather than left to divide freely: --gal-min goes down to
   about 110 on the narrowest pane, and half of that is a tile too small to
   tell a picture from a clip. */
#gallery-pending .gal-item {
  width: max(72px, calc(var(--gal-min, 158px) / 2));
  flex: 0 0 max(72px, calc(var(--gal-min, 158px) / 2));
  min-width: 0;
}
/* The two labels on a pending card are sized for a full tile; at half the
   width they would wrap or clip, so they come down with it. */
#gallery-pending .pend-proxy { font-size: 7px; padding: 1px 4px; }
#gallery-pending .pending-card .gmodel { font-size: 7px; }
/* Only the card itself owns the drag gesture — stop nested images/videos/icons
   starting their own native drag, which leaves a sticky "ghost" drag in CEP. */
.gal-item img, .gal-item video, .gal-item svg { -webkit-user-drag: none; user-select: none; }
.gal-item {
  cursor: pointer; border: 1px solid var(--border); border-radius: 0;
  overflow: hidden; background: var(--card); margin-bottom: 0; position: relative;
}
.gal-item:hover { border-color: var(--accent); }
.gal-item .gmeta { display: none; }  /* no name/label under gallery thumbs */
.gal-item .gtype {
  position: absolute; top: 5px; left: 5px;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 3px;
  background: var(--scrim-mid); color: #fff;
}
.gal-item .gtype svg { width: 14px; height: 14px; }
/* A CROP EDIT WEARS THE CROP MARK HERE, AND BIGGER. Simon: "rather than just
   having the image top left (the image icon, as if it's an image), it needs to
   show a big crop icon there." The other badges name a file format; this one
   names a kind of work, and at 14px against a picture frame it read as another
   variety of still. */
.gal-item .gtype.crop { width: 30px; height: 30px; color: var(--accent); }
/* A 3D room's cube, sized like the crop mark rather than like a file-format
   glyph: both are standing in for a KIND OF THING you can open, not for what
   the file on disk happens to be. Left in the ordinary colour -- the crop
   mark is the accent because a crop edit is work in progress, and a room is
   simply a room. */
.gal-item .gtype.room { width: 28px; height: 28px; }
.gal-item .gtype.room svg { width: 17px; height: 17px; }
.gal-item .gtype.room ~ .gres { left: 37px; top: 12px; }
.gal-item .gtype.crop svg { width: 19px; height: 19px; stroke-width: 2.2; }
/* ...and the size chip beside it steps over to make room. */
.gal-item .gtype.crop ~ .gres { left: 39px; top: 13px; }
/* provider icon of the generating model — bottom-left */
/* ROOM FOR A WIDE MARK. Simon: "the space for the logo of the model on the
   bottom left-hand corner of the gallery items has slightly more space, as
   currently the wider logos there are being cropped at the sides." The mark
   sat in a 16px square with overflow hidden: a lettermark -- two initials
   at the 13px .micon weight, which is what every unmapped model wears --
   is wider than 16px and lost a slice off each side, and a wordmark file
   was shrunk to fit the square instead. The box is 30 wide and 18 tall
   now, letters are sized to sit inside it, and nothing is clipped. */
.gal-item .gmodel {
  position: absolute; bottom: 5px; left: 5px; z-index: 2;
  width: 36px; height: 22px; display: flex; align-items: center; justify-content: flex-start;
  background: none;   /* transparent — icon sits directly on the thumb */
  filter: drop-shadow(0 1px 2px var(--scrim-heavy));
}
.gal-item .gmodel .micon { width: 30px; height: 18px; font-size: 10.5px; letter-spacing: .2px; overflow: visible; justify-content: flex-start; }
.gal-item .gmodel .micon img { object-position: left center; }
.gal-item .gmodel .micon.drawn svg { width: 16px; height: 16px; }
.gal-item:hover .gmodel { opacity: 0; }  /* make room for the hover info */
/* SD / HD / 4K, beside the mark.

   The number is a fact and the word is what you mean by it — scanning a grid
   of dimensions to find the 4K one is reading when you wanted to look. Same
   corner as the maker's mark and it fades with it on hover, because the
   hover strip carries the exact figure and two answers to the same question
   on screen at once is one too many. */
.gal-item .gres {
  /* TOP-LEFT, beside the still/clip icon rather than beside the maker's mark.
     They answer the same kind of question — what IS this file — and the two of
     them together read as one line: a clip, and it is 4K. Down in the other
     corner it was a second place to look for the same sort of fact. */
  position: absolute; left: 35px; top: 11px; z-index: 3;
  font-size: 9px; font-weight: 800; letter-spacing: .6px;
  color: #fff; pointer-events: none;
  transition: opacity .12s;
  /* No pill behind it. A shadow rather than a background, the same way the
     maker's mark next to it stays legible — a dark chip on a dark frame is a
     rectangle you notice before the word inside it. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, .95), 0 0 2px rgba(0, 0, 0, .8);
}
/* It stays on hover. The strip that replaces the maker's mark is along the
   BOTTOM, so there is nothing competing for this corner — and the strip's
   exact figure and this word are then on screen together, which is the pair
   you want when you are deciding whether to upscale. */
.gal-item .gtype svg { display: block; }

/* "this picture has a 3D scene" — beside the type badge, and it is the door
   to that scene rather than just a note that one exists. */
.gal-item .g3d {
  position: absolute; top: 5px; left: 36px; z-index: 3;
  width: 26px; height: 26px; border-radius: 3px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--scrim-mid); border: 1px solid transparent;
  color: var(--accent); cursor: pointer;
}
.gal-item .g3d:hover { background: var(--accent); color: #fff; }
.gal-item .g3d svg { width: 14px; height: 14px; display: block; }

/* "this tile is a crop edit project" — the crop mark, bottom-left, and
   it is a door to the stored project (the actions strip carries an Edit
   button too, for while the hover strip covers this corner). */
.gal-item .gcrop {
  position: absolute; bottom: 5px; left: 5px; z-index: 3;
  width: 22px; height: 22px; border-radius: 3px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--scrim-mid); border: 1px solid transparent;
  color: var(--accent); cursor: pointer;
}
.gal-item .gcrop:hover { background: var(--accent); color: #fff; }
.gal-item .gcrop svg { width: 13px; height: 13px; display: block; }
/* the maker's mark steps one seat right when the crop mark is home */
.gal-item .gcrop ~ .gmodel { left: 32px; }

/* the original still, tucked into the corner of a 3D tile */
.gal-item .m3d-src {
  position: absolute; left: 5px; bottom: 5px; z-index: 2;
  width: 40px; height: 30px; border-radius: 3px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.28); background: #000;
  box-shadow: 0 2px 8px var(--scrim-mid);
}
.gal-item .m3d-src img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* It used to fade out of the way on hover, back when it was decoration. It is
   now the thing you drag into a reference slot, so it has to stay grabbable —
   it steps back a little and comes fully forward under the cursor. */
.gal-item:hover .m3d-src { opacity: .75; cursor: grab; }
.gal-item .m3d-src:hover { opacity: 1; border-color: var(--accent); transform: scale(1.06); }
.gal-item .m3d-src:active { cursor: grabbing; }
.gal-item .m3d-src { transition: opacity .12s, transform .12s, border-color .12s; }
/* Two action groups: pink "edit" actions pin to the TOP-right, the white
   file/comp actions to the BOTTOM-right. Both reveal on hover only. */
.gal-actions, .gal-actions-w {
  position: absolute; right: 5px; z-index: 2;
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px;
  max-width: calc(100% - 10px);
  opacity: 0; transition: opacity .12s;
  pointer-events: none;   /* invisible until hover — never swallow clicks */
}
.gal-actions   { top: 5px;    align-content: flex-start; }
.gal-actions-w { bottom: 5px; align-content: flex-end; }
.gal-item:hover .gal-actions,
.gal-item:hover .gal-actions-w { opacity: 1; pointer-events: auto; }
/* Button size scales with the thumbnail: --gact-size is set from the rendered
   card width in JS (syncGalBtnSize), so buttons shrink as the gallery gets
   smaller / more columns. Falls back to 23px before the first measure. */
.gact {
  width: var(--gact-size, 23px); height: var(--gact-size, 23px);
  border-radius: 3px; border: none; cursor: pointer;
  background: var(--scrim-mid); color: #fff; line-height: 1;
  font-size: calc(var(--gact-size, 23px) * 0.56);   /* text-glyph buttons (⟳, ▶) scale too */
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.gact svg { display: block; width: 52%; height: 52%; }
.gact:hover { background: var(--accent); }
/* Edit-family actions (reuse, regenerate, upscale, create character)
   read pink so they group visually at the head of the row. */
.gact.edit { color: var(--accent); }
.gact.edit:hover { background: var(--accent); color: #fff; }
/* …except the one that is not an edit. Simon: "Move the Create Video
   button over the gallery items so it's further to the left, and now it's
   white colour icon." Turn into video does not change this picture, it
   starts a new generation from it -- so it sits at the head of the row and
   comes out of the pink. */
.gact.edit.g-tovid { color: #fff; }
/* AND IT IS ALWAYS THE FIRST ONE. Simon: "Make it so the Create Video button
   is always furthest to the left in the gallery buttons that appear when you
   hover over a gallery item."

   It was first by being appended first, which is a promise the next person to
   add a button can break without noticing. `order` is the same promise made
   to the layout instead of to the insertion order, so it holds however the
   strip is built -- and on a narrow card, where the row wraps, it keeps it at
   the start of the first line rather than wherever the wrap left it. */
.gal-actions .gact.g-tovid { order: -1; }
.gact.danger:hover { background: var(--red); }
.empty { color: var(--text-faint); font-size: 11px; }

/* When the panel is dragged narrower than the two columns need (AE lets docked
   panels ignore the manifest MinSize), stack the gallery UNDER the controls so
   the full width is always visible instead of being clipped off-screen. */
@media (max-width: 664px) {
  #layout { flex-direction: column; }  /* no overflow-x — it would break sticky */
  #main { width: 100%; flex: 0 0 auto; min-height: 0; }  /* natural height so the gallery stacks under it */
  #gallery-resizer { display: none; }
  #gallery-pane {
    width: 100%; min-width: 0; flex: 0 0 auto; padding-left: 0; position: static;
    max-height: 60vh; border-top: 1px solid var(--border); margin-top: 8px;
  }
}

/* ---------- split view: the second gallery pane ----------

   Simon, second time round: "a button that says 'Split View'... it splits
   into two different vertical sections: the left has images, and the right
   has videos." #gallery-split is a row holding #gallery-scroll, the divider
   and the second pane (built by js/panel/47b-gallery-second.js); with the
   split off the row holds the scroller alone and is invisible as a layer.

   Its own --gal-min. The grid rule is written against the variable and
   inherits, so the second pane setting its own overrides the column's for
   everything inside it — which is what makes the two zooms independent
   without a second copy of the grid rule. */
#gallery-split {
  flex: 1 1 0; min-height: 0; display: flex; flex-direction: row; min-width: 0;
}
#gallery-split > #gallery-scroll { flex: 1 1 0; min-width: 0; min-height: 0; }
/* The left half: its own head (the control row lives here while split) over
   the scroller. The row is left-aligned here, over its own grid, rather than
   pushed to the right the way the pane head's is. */
#gallery-a-col { flex: 1 1 0; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
#gallery-a-col > #gallery-scroll { flex: 1 1 0; min-height: 0; }
#gal-a-head { flex: none; display: flex; align-items: center; gap: 6px; padding: 0 0 6px; min-width: 0; }
#gal-a-head:empty { display: none; }
#gal-a-head .gal-tools { justify-content: flex-start; }
.gallery-head.split-on { min-height: 0; }
.gal2-rz {
  flex: none; width: 7px; margin: 0 2px; cursor: col-resize;
  position: relative;
}
.gal2-rz::after {
  content: ''; position: absolute; top: 6px; bottom: 6px; left: 3px;
  width: 1px; background: var(--border);
}
.gal2-rz:hover::after { background: var(--accent); }
/* NO min-width HERE. The floor belongs to gal2SetWidth, which also knows how
   much room the row has. One owner for the number. */
.gal2-pane {
  flex: none; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  padding-left: 4px; border-left: 1px solid var(--border);
}
.gal2-head {
  flex: none; display: flex; align-items: center; gap: 6px;
  padding: 0 0 6px; min-width: 0; flex-wrap: wrap;
}
.gal2-head .gal2-sp { flex: 1 1 auto; min-width: 0; }
.gal2-shot select {
  background: var(--card); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); font-family: inherit; font-size: 10px;
  padding: 2px 4px; max-width: 118px; outline: none;
}
.gal2-shot select:focus { border-color: var(--accent); }
#gallery-scale-b {
  width: 62px; height: 3px; padding: 0; border: none;
  -webkit-appearance: none; appearance: none;
  border-radius: 3px; background: var(--border); outline: none; cursor: pointer;
}
#gallery-scale-b::-webkit-slider-thumb {
  -webkit-appearance: none; width: 10px; height: 10px; border-radius: 50%;
  background: var(--text-dim); border: none;
}
#gallery-scale-b::-webkit-slider-thumb:hover { background: var(--accent); }
.gal2-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-bottom: 10px; }
/* The same grid as the first pane, reading the same variable — which this
   pane has set to its own value. One rule, two answers. */
#gallery-b {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--gal-min, 158px), 1fr));
  justify-content: stretch; gap: 7px; align-content: start; grid-auto-rows: max-content;
}
#gallery-b .gal-item { width: 100%; min-width: 0; }
.gal2-pane.hidden, .gal2-rz.hidden { display: none; }
/* The button reads as what it does. */
#btn-gallery-split { font-size: 10px; font-weight: 700; letter-spacing: .04em; padding: 0 7px; height: 22px; white-space: nowrap; }
#btn-gallery-split.on { color: var(--accent); border-color: var(--accent); }
/* The gallery's 4K button (47-gallery-load.js, 28 Sep): the letters are the icon. */
.gact .gact-4k { font-size: 9.5px; font-weight: 800; letter-spacing: .02em; line-height: 1; }
