/* Gallery (gallery.py + gallery.js), on the Float tokens.
   A masonry wall of floating tiles, a calm photo stage with a side panel, and a drop zone that fills as photos upload. */
.gal-tabs { margin-top: var(--s-2); }
.gal-grid { columns: 4 240px; column-gap: var(--gap-float); margin-top: max(var(--gap-float, 10px), var(--s-4)); }
.gal-tile { position: relative; display: block; margin: 0 0 var(--gap-float); break-inside: avoid; overflow: hidden; border-radius: var(--r-md);
  background: var(--surface-2); box-shadow: var(--e-1); transform: translateZ(0);
  transition: box-shadow var(--t-med) var(--ease-liquid), transform var(--t-med) var(--ease-spring); }
.gal-tile img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease-liquid), filter var(--t-med); }
.gal-tile-meta { position: absolute; inset: auto 0 0 0; display: flex; gap: var(--s-3); padding: 28px var(--s-3) var(--s-2); color: #fff;
  font: 600 var(--fs-xs)/1 var(--font-ui); background: linear-gradient(to top, rgb(0 0 0 / .55), transparent);
  opacity: 0; transform: translateY(6px); transition: opacity var(--t-med) var(--ease-liquid), transform var(--t-med) var(--ease-liquid); }
.gal-tile-meta .on { color: #ff8fa3; }
@media (hover: hover) {
  .gal-tile:hover { transform: translateY(-3px); box-shadow: var(--e-2); }
  .gal-tile:hover img { transform: scale(1.035); }
  .gal-tile:hover .gal-tile-meta, .gal-tile:focus-visible .gal-tile-meta { opacity: 1; transform: none; }
}
@media (hover: none) { .gal-tile-meta { opacity: 1; transform: none; padding-top: 18px; } }

/* albums */
.gal-albums { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--gap-float); margin: max(var(--gap-float, 10px), var(--s-4)) 0; }
.gal-album { display: flex; flex-direction: column; overflow: hidden; color: inherit; text-decoration: none; }
.gal-album-art { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface-2); }
.gal-album-art img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease-liquid); }
@media (hover: hover) { .gal-album:hover .gal-album-art img { transform: scale(1.04); } }
.gal-noimg { display: grid; place-items: center; height: 100%; color: var(--text-faint); } .gal-noimg svg { width: 40px; height: 40px; }
.gal-album-body { display: grid; gap: 4px; padding: var(--s-3) var(--s-4) var(--s-4); }
.gal-desc { margin-top: var(--s-2); }

/* one photo */
.gal-view { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--gap-float); align-items: start; }
.gal-stage { position: relative; margin: 0; display: grid; place-items: center; min-height: 320px; padding: var(--s-3); border-radius: var(--r-lg);
  background: radial-gradient(120% 90% at 50% 40%, #1b2133, #0c0f18); box-shadow: var(--e-2); overflow: hidden; }
.gal-full { display: block; max-width: 100%; cursor: zoom-in; }
.gal-stage img { display: block; max-width: 100%; max-height: min(78vh, 1100px); width: auto; height: auto; border-radius: var(--r-sm);
  animation: gal-in var(--t-slow) var(--ease-liquid) both; }
@keyframes gal-in { from { opacity: 0; transform: scale(.985); filter: blur(6px); } }
.gal-nav { position: absolute; top: 50%; z-index: 2; display: grid; place-items: center; width: 44px; height: 44px; margin-top: -22px; border-radius: 50%;
  background: rgb(255 255 255 / .85); color: #0f1729; font: 600 28px/1 var(--font-ui); text-decoration: none; box-shadow: var(--e-2);
  opacity: .0; transition: opacity var(--t-med), transform var(--t-fast) var(--ease-spring); }
.gal-nav.prev { left: 12px; } .gal-nav.next { right: 12px; }
.gal-stage:hover .gal-nav, .gal-nav:focus-visible { opacity: 1; } .gal-nav:active { transform: scale(.9); }
@media (hover: none) { .gal-nav { opacity: .9; } }
.gal-side { display: grid; gap: var(--gap-float); }
.gal-by { display: flex; gap: var(--s-3); align-items: center; } .gal-by > div { flex: 1; min-width: 0; }
.gal-cap { margin: var(--s-3) 0 0; font-size: var(--fs-md); overflow-wrap: anywhere; }
.gal-likes { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-3); }
.gal-meta { margin-top: var(--s-2); }
.gal-like-f { margin: 0; display: inline-flex; }
.gal-like { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 14px 0 11px; border: 0; border-radius: var(--r-pill); cursor: pointer;
  background: var(--surface-2); color: var(--text-muted); font: 700 var(--fs-sm)/1 var(--font-ui); box-shadow: inset 0 0 0 1px var(--border);
  font-variant-numeric: tabular-nums; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--t-fast), color var(--t-fast), transform var(--t-fast) var(--ease-spring), box-shadow var(--t-med) var(--ease-liquid); }
.gal-like svg { width: 18px; height: 18px; transition: fill var(--t-fast); }
.gal-like:hover { color: var(--text); transform: translateY(-1px); } .gal-like:active { transform: scale(.92); }
.gal-like[aria-pressed="true"] { color: #e64980; background: color-mix(in oklab, #e64980 12%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in oklab, #e64980 45%, transparent), 0 6px 18px -8px color-mix(in oklab, #e64980 60%, transparent); }
.gal-like[aria-pressed="true"] svg { fill: currentColor; }
.gal-like.off { cursor: default; }
.gal-like.hit .gal-heart { animation: gal-beat 560ms var(--ease-spring); }
.gal-heart { display: inline-flex; }
@keyframes gal-beat { 30% { transform: scale(1.35); } 60% { transform: scale(.9); } }
.gal-n.up { animation: gal-up 340ms var(--ease-liquid); } .gal-n.down { animation: gal-down 340ms var(--ease-liquid); }
@keyframes gal-up { from { transform: translateY(70%); opacity: 0; } } @keyframes gal-down { from { transform: translateY(-70%); opacity: 0; } }
.gal-comments h3 { margin-top: 0; }
.gal-clist { list-style: none; margin: 0 0 var(--s-3); padding: 0; display: grid; gap: var(--s-3); max-height: 56vh; overflow: auto; }
.gal-c { display: flex; gap: var(--s-2); align-items: flex-start; } .gal-c-body { min-width: 0; } .gal-c .post-body { font-size: var(--fs-sm); overflow-wrap: anywhere; }
.gal-c form.inline { display: inline; } .linkish { border: 0; background: none; padding: 0; cursor: pointer; }
.gal-cform { display: grid; gap: var(--s-2); } .gal-cform textarea { resize: vertical; } .gal-cform .btn { justify-self: end; }
.gal-tools { margin-left: auto; } .gal-tools .menu-pop { min-width: 260px; right: 0; left: auto; }

/* upload */
.gal-upload { max-width: 760px; margin-inline: auto; }
.gal-drop { position: relative; display: grid; place-items: center; min-height: 180px; padding: var(--s-5); border-radius: var(--r-lg); cursor: pointer;
  background: var(--surface-2); box-shadow: inset 0 0 0 2px var(--border); text-align: center;
  transition: background-color var(--t-fast), box-shadow var(--t-med) var(--ease-liquid), transform var(--t-med) var(--ease-spring); }
.gal-drop input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.gal-drop-in { display: grid; gap: 6px; justify-items: center; pointer-events: none; } .gal-drop-in svg { width: 34px; height: 34px; color: var(--accent); }
.gal-drop:hover, .gal-drop.over { background: var(--accent-soft); box-shadow: inset 0 0 0 2px var(--accent); }
.gal-drop.over { transform: scale(1.01); }
.gal-queue { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.gal-queue:empty { display: none; }
.gal-q { position: relative; aspect-ratio: 1; border-radius: var(--r-sm); overflow: hidden; background: var(--surface-2); box-shadow: var(--e-1); animation: gal-in var(--t-med) var(--ease-spring) both; }
.gal-q img { width: 100%; height: 100%; object-fit: cover; opacity: .45; transition: opacity var(--t-med); }
.gal-q.done img { opacity: 1; } .gal-q.fail { box-shadow: inset 0 0 0 2px var(--neg); }
.gal-q::after { content: ""; position: absolute; left: 0; bottom: 0; height: 3px; width: var(--p, 0%); background: var(--accent); transition: width var(--t-med) var(--ease-liquid); }
.gal-q.done::after { width: 100%; background: var(--pos); }

/* profile + misc */
.gal-minis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-bottom: var(--s-2); }
.gal-mini { display: block; aspect-ratio: 1; overflow: hidden; border-radius: var(--r-sm); background: var(--surface-2); }
.gal-mini img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease-liquid); }
.gal-mini:hover img { transform: scale(1.05); }

@media (max-width: 900px) {
  .gal-view { grid-template-columns: none; }
  .gal-stage { margin-inline: -16px; border-radius: 0; padding: 0; min-height: 0; }
  .gal-stage img { border-radius: 0; max-height: 70vh; }
  .gal-grid { columns: 2 140px; }
}
@media (prefers-reduced-motion: reduce) {
  .gal-tile, .gal-tile img, .gal-like, .gal-album-art img { transition: none; }
  .gal-stage img, .gal-q, .gal-like.hit .gal-heart, .gal-n.up, .gal-n.down { animation: none; }
}

/* page head: the buttons and tabs sit on the title's centre line and the subtitle runs under the title;
   on phones the tools take their own row under the subtitle */
.gal-head { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); row-gap: 6px; }
.gal-head > div:first-child { display: contents; }
.gal-head h1 { flex: 1 1 auto; min-width: 0; margin: 0; }
.gal-head > div:first-child > :not(h1) { order: 2; flex-basis: 100%; min-width: 0; }
.gal-head > .greet-tools { order: 1; margin-left: auto; width: auto; min-width: 0; }
.gal-head > .greet-tools > * { max-width: 100%; }
@media (max-width: 600px) { .gal-head > .greet-tools { order: 3; flex-basis: 100%; margin-left: 0; margin-top: var(--s-2); } }

/* an empty gallery straight under the head keeps the same air as the grid */
.gal-head + .empty, .gal-head + .box { margin-top: var(--s-5); }
