/* =====================================================================================================
   VAULT · GALLERY + TIMELINE — media views for the YTranscript "Vault" file manager
   Immich-style justified GALLERY + Google-Photos-style date TIMELINE (scrubber-with-peek).

   INTEGRATION (read me):
     · This sheet is a SIBLING to vault.css. The Vault already loads its own CSS, so this file MUST be
       <link>ed alongside it — it is NEVER injected as a <style> string (strict CSP: style-src 'self'
       blocks inline <style>). Add ONE line to the app shell, right after vault.css:
           <link rel="stylesheet" href="vault-gallery.css">
     · Everything is scoped under `.vg`. It reuses the Vault design tokens (--hue / --accent / --ink /
       --box / --line / --radius …) which are declared on `.vlt`; `.vg` lives inside `.vlt`, so they
       inherit. Fallbacks are baked into every var() so the module still renders if mounted standalone.
     · ZERO inline styles: every dynamic geometry value (tile x/y/w/h, track height, scrubber position,
       waveform bar heights, placeholder hue) is fed through element.style.setProperty('--x', …) from
       vault-gallery.js and consumed here. No component ever assembles a style string.
     · Dark-first, container-query responsive (NOT viewport media queries). Because a container cannot
       answer its OWN @container query, the tunable tokens (--vg-row-h / --vg-gap / --vg-min-tile /
       --vg-scrub-w) are read + overridden on the SCROLL surface (a descendant of the .vg container).
   ===================================================================================================== */

/* ============================== ROOT / TOKENS ============================== */
.vg {
  /* module tunables — base (widest) values; container queries below override them on the scroll surface */
  --vg-gap: 4px;                 /* gutter between tiles */
  --vg-row-h: 208px;             /* GALLERY target justified row height (JS reads this) */
  --vg-min-tile: 136px;          /* TIMELINE min uniform tile edge */
  --vg-scrub-w: 52px;            /* TIMELINE scrubber rail width */
  --vg-tile-r: 11px;             /* tile corner radius */
  --vg-pad: 12px;                /* scroll-surface inset */

  /* local echoes of the Vault tokens, WITH fallbacks (so standalone mounts still look right) */
  --vg-hue: var(--hue, 235);
  --vg-accent: var(--accent, 268 88% 68%);
  --vg-ink: var(--ink, 235 16% 95%);
  --vg-ink-dull: var(--ink-dull, 235 11% 68%);
  --vg-ink-faint: var(--ink-faint, 235 9% 50%);
  --vg-box: var(--box, 235 14% 14.5%);
  --vg-app: var(--app, 235 15% 10.5%);
  --vg-overlay: var(--overlay, 235 16% 13%);
  --vg-line: var(--line, 235 12% 21%);
  --vg-frame: var(--frame, 235 12% 27%);
  --vg-radius: var(--radius, 12px);

  --vg-fdisplay: var(--font-display, 'Comfortaa', ui-rounded, system-ui, sans-serif);
  --vg-fbody: var(--font-body, 'Atkinson Hyperlegible', system-ui, sans-serif);
  --vg-ease: var(--ease-out, cubic-bezier(.16, 1, .3, 1));
  --vg-scrim: var(--vg-hue) 40% 4%;   /* near-black wash for scrims, tinted to the surface hue */

  position: relative;
  block-size: 100%;
  min-block-size: 0;
  inline-size: 100%;
  overflow: hidden;                    /* no horizontal body scroll ever; the inner surface scrolls */
  color: hsl(var(--vg-ink));
  font-family: var(--vg-fbody);
  container: vg / inline-size;         /* the responsive container — descendants answer @container vg */
  contain: layout style;
}
.vg, .vg *, .vg *::before, .vg *::after { box-sizing: border-box; }
.vg button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; margin: 0; padding: 0; }

/* ============================== SCROLL SURFACES ============================== */
.vg-scroll {
  position: absolute; inset: 0;
  overflow-x: hidden; overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: hsl(var(--vg-frame)) transparent;
}
.vg-scroll::-webkit-scrollbar { inline-size: 10px; }
.vg-scroll::-webkit-scrollbar-thumb { background: hsl(var(--vg-frame)); border-radius: 999px;
  border: 3px solid transparent; background-clip: content-box; }

/* GALLERY scroll surface holds the absolutely-positioned justified track */
.vg-gal-scroll { padding: var(--vg-pad); }
.vg-gal-track { position: relative; inline-size: 100%; block-size: var(--vg-track-h, 0px); }

/* ============================== TILE (shared by both views) ============================== */
.vg-tile {
  position: absolute; inset-block-start: 0; inset-inline-start: 0;
  inline-size: var(--w, 160px); block-size: var(--h, 120px);
  translate: var(--x, 0px) var(--y, 0px);
  border-radius: var(--vg-tile-r);
  overflow: hidden;
  background: hsl(var(--vg-box));
  border: 1px solid hsl(var(--vg-line));
  cursor: pointer;
  isolation: isolate;
  content-visibility: auto;
  contain-intrinsic-size: var(--w, 160px) var(--h, 120px);
  transition: box-shadow .18s var(--vg-ease);
}
/* TIMELINE variant: uniform square, flows in the CSS grid (no absolute geometry) */
.vg-tile--grid {
  position: relative; inset: auto; translate: none;
  inline-size: 100%; block-size: auto; aspect-ratio: 1;
  contain-intrinsic-size: var(--vg-tile-cis, 140px) var(--vg-tile-cis, 140px);
}

/* instant gradient placeholder — a per-item hue (JS sets --ph-h); always underneath the poster */
.vg-tile__ph {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(120% 120% at 20% 0%, hsl(var(--ph-h, 268) 34% 34% / .95), transparent 62%),
    linear-gradient(150deg, hsl(var(--ph-h, 268) 30% 26%), hsl(var(--ph-h, 268) 26% 14%));
}
.vg-tile__ph::after {          /* very quiet sheen so an empty tile is not a flat block */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 42%, hsl(0 0% 100% / .05) 50%, transparent 58%);
}

/* poster image — cross-fades in over the placeholder when it loads */
.vg-tile__img {
  position: absolute; inset: 0; z-index: 1;
  inline-size: 100%; block-size: 100%; object-fit: cover; display: block;
  opacity: 0;
  transition: opacity .5s var(--vg-ease), transform .5s var(--vg-ease);
}
.vg-tile__img.is-loaded { opacity: 1; }

/* audio → generated CSS waveform tile (the transcript-native signature) */
.vg-tile__wave {
  position: absolute; inset: 0; z-index: 1;
  display: flex; align-items: center; justify-content: center; gap: 2px;
  padding: 0 14%;
  pointer-events: none;
}
.vg-tile__wave .vg-bar {
  flex: 1 1 0; min-inline-size: 2px; border-radius: 999px;
  block-size: calc(10% + var(--bh, .4) * 78%);
  background: linear-gradient(hsl(var(--vg-accent) / .95), hsl(var(--vg-accent) / .5));
}
.vg-tile[data-media="audio"] .vg-tile__ph {
  background:
    radial-gradient(120% 120% at 50% 120%, hsl(var(--vg-accent) / .18), transparent 60%),
    linear-gradient(160deg, hsl(var(--vg-hue) 16% 20%), hsl(var(--vg-hue) 18% 11%));
}

/* folder tile — reads as an object, not media */
.vg-tile[data-kind="folder"] .vg-tile__ph {
  background:
    radial-gradient(130% 100% at 30% 0%, hsl(var(--vg-accent) / .22), transparent 60%),
    linear-gradient(150deg, hsl(268 26% 24%), hsl(268 22% 13%));
}
.vg-tile__folder {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: center;
  font-size: clamp(30px, 22cqi, 52px);   /* the folder SVG is 1em → it scales with this */
  color: hsl(var(--vg-accent) / .92);
  filter: drop-shadow(0 6px 14px hsl(var(--vg-scrim) / .5));
}
.vg-tile__folder .ico { display: block; stroke-width: 1.6; }   /* thinner stroke reads better at tile scale */

/* bottom scrim + name (revealed on hover / focus) */
.vg-tile__scrim {
  position: absolute; inset-inline: 0; inset-block-end: 0; z-index: 2;
  padding: 26px 10px 8px;
  background: linear-gradient(to top, hsl(var(--vg-scrim) / .86), hsl(var(--vg-scrim) / .3) 55%, transparent);
  opacity: 0;
  transition: opacity .18s var(--vg-ease);
  pointer-events: none;
}
.vg-tile__name {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden;
  font-size: 12px; line-height: 1.28; font-weight: 600;
  color: hsl(0 0% 100% / .96);
  text-shadow: 0 1px 3px hsl(var(--vg-scrim) / .8);
}
.vg-tile[data-kind="folder"] .vg-tile__scrim,
.vg-tile[data-media="audio"] .vg-tile__scrim { opacity: 1; }   /* folders + audio always show their name */

/* duration badge — always visible, tabular, quiet */
.vg-tile__dur {
  position: absolute; inset-block-end: 8px; inset-inline-end: 8px; z-index: 3;
  padding: 2px 6px; border-radius: 6px;
  font-family: var(--vg-fdisplay); font-size: 10.5px; font-weight: 700; letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
  color: hsl(0 0% 100% / .95);
  background: hsl(var(--vg-scrim) / .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.vg-tile__count {           /* folder item count sits where the duration would be */
  position: absolute; inset-block-start: 8px; inset-inline-end: 8px; z-index: 3;
  padding: 2px 7px; border-radius: 999px;
  font-family: var(--vg-fdisplay); font-size: 10.5px; font-weight: 700;
  color: hsl(var(--vg-ink)); background: hsl(var(--vg-scrim) / .5);
}

/* lang chip (top-left, appears on hover for media) */
.vg-tile__lang {
  position: absolute; inset-block-start: 8px; inset-inline-start: 8px; z-index: 3;
  padding: 1px 6px; border-radius: 6px;
  font-family: var(--vg-fdisplay); font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .9); background: hsl(var(--vg-scrim) / .5);
  opacity: 0; transition: opacity .18s var(--vg-ease);
}

/* selection check-circle (top-left). aria-pressed is the single truth → :has() paints the ring */
.vg-tile__check {
  position: absolute; inset-block-start: 7px; inset-inline-start: 7px; z-index: 4;
  inline-size: 22px; block-size: 22px; border-radius: 50%;
  display: grid; place-items: center;
  color: hsl(0 0% 100% / .96);
  background: hsl(var(--vg-scrim) / .42);
  border: 1.5px solid hsl(0 0% 100% / .82);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  opacity: 0; transform: scale(.86);
  transition: opacity .16s var(--vg-ease), transform .16s var(--vg-ease), background .16s, border-color .16s;
}
/* the tick itself is an inline SVG (icons.js "check"), sized 13px by the JS — same reveal choreography */
.vg-tile__check > .ico { display: block; pointer-events: none; opacity: 0; transform: scale(.6);
  transition: opacity .14s var(--vg-ease), transform .14s var(--vg-ease); }
.vg-tile:hover .vg-tile__check,
.vg-tile:focus-visible .vg-tile__check,
.vg-tile__check:focus-visible { opacity: 1; transform: scale(1); }
.vg-tile__check[aria-pressed="true"] {
  opacity: 1; transform: scale(1);
  background: hsl(var(--vg-accent)); border-color: hsl(var(--vg-accent));
  color: hsl(var(--vg-hue) 40% 8%);
}
.vg-tile__check[aria-pressed="true"] > .ico { opacity: 1; transform: scale(1); }

/* ---- interactions: hover reveal + selected ring (pure CSS via :has()) ---- */
.vg-tile:hover .vg-tile__scrim,
.vg-tile:focus-visible .vg-tile__scrim,
.vg-tile:hover .vg-tile__lang,
.vg-tile:focus-visible .vg-tile__lang { opacity: 1; }
.vg-tile:hover .vg-tile__img { transform: scale(1.045); }
.vg-tile:hover { box-shadow: 0 12px 30px -14px hsl(var(--vg-scrim) / .8); }

.vg-tile:has(> .vg-tile__check[aria-pressed="true"]) {
  box-shadow: 0 0 0 2.5px hsl(var(--vg-accent)), 0 12px 30px -14px hsl(var(--vg-scrim) / .8);
}
.vg-tile:has(> .vg-tile__check[aria-pressed="true"]) .vg-tile__img { transform: scale(.9); }
.vg-tile:has(> .vg-tile__check[aria-pressed="true"])::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: hsl(var(--vg-accent) / .16);
}

.vg-tile:focus-visible { outline: none; }
.vg-tile:focus-visible::before {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  border-radius: inherit; box-shadow: inset 0 0 0 2px hsl(var(--vg-accent)), inset 0 0 0 4px hsl(var(--vg-scrim) / .5);
}

/* ============================== TIMELINE ============================== */
.vg-tl-scroll { padding: 0 0 40px; }
.vg-tl-inner { padding-inline: var(--vg-pad); padding-inline-end: calc(var(--vg-scrub-w) + var(--vg-pad)); }

.vg-tl-bucket { margin-block-start: 6px; }
.vg-tl-mhead {
  position: sticky; inset-block-start: 0; z-index: 6;
  display: flex; align-items: baseline; gap: 10px;
  padding: 12px 2px 10px;
  background: linear-gradient(hsl(var(--vg-app)) 62%, hsl(var(--vg-app) / 0));
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.vg-tl-mhead__title { font-family: var(--vg-fdisplay); font-weight: 700; font-size: clamp(17px, 3.4cqi, 23px);
  letter-spacing: -.01em; color: hsl(var(--vg-ink)); }
.vg-tl-mhead__count { font-size: 12px; color: hsl(var(--vg-ink-faint)); font-variant-numeric: tabular-nums; }

.vg-tl-day { margin-block-end: 14px; }
.vg-tl-day__label {
  padding: 8px 2px 7px;
  font-family: var(--vg-fdisplay); font-size: 10.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: hsl(var(--vg-ink-faint));
}
.vg-tl-grid {
  display: grid; gap: var(--vg-gap);
  grid-template-columns: repeat(auto-fill, minmax(var(--vg-min-tile), 1fr));
}

/* ---- scrubber-with-peek (the signature move) ---- */
.vg-tl-scrub {
  position: absolute; inset-block: 0; inset-inline-end: 0; z-index: 8;
  inline-size: var(--vg-scrub-w);
  padding-block: var(--vg-pad);
  touch-action: none;
  opacity: 0; transition: opacity .25s var(--vg-ease);
}
.vg[data-vg="timeline"]:hover .vg-tl-scrub,
.vg-tl-scrub.is-active,
.vg-tl-scrub:focus-within { opacity: 1; }
.vg-tl-scrub__track {
  position: relative; block-size: 100%; inline-size: 100%;
  cursor: ns-resize;
}
/* month ticks pinned along the rail (JS sets --pos as a 0–100 percentage) */
.vg-tl-tick {
  position: absolute; inset-inline-end: 0; inset-block-start: var(--pos, 0%);
  transform: translateY(-50%);
  display: flex; align-items: center; gap: 7px;
  padding: 2px 6px 2px 10px;
  color: hsl(var(--vg-ink-faint));
  font-family: var(--vg-fdisplay); font-size: 10px; font-weight: 700; letter-spacing: .04em;
  white-space: nowrap;
  transition: color .14s var(--vg-ease);
}
.vg-tl-tick__label { pointer-events: none; }
.vg-tl-tick__dot { inline-size: 6px; block-size: 6px; border-radius: 50%; flex: none;
  background: hsl(var(--vg-ink-faint) / .55); transition: background .14s, transform .14s; }
.vg-tl-tick:hover { color: hsl(var(--vg-ink)); }
.vg-tl-tick.is-current { color: hsl(var(--vg-accent)); }
.vg-tl-tick.is-current .vg-tl-tick__dot { background: hsl(var(--vg-accent)); transform: scale(1.5); }

/* the draggable thumb that tracks scroll position */
.vg-tl-thumb {
  position: absolute; inset-inline-end: 4px; inset-block-start: var(--pos, 0%);
  transform: translateY(-50%);
  inline-size: 34px; block-size: 26px; border-radius: 999px;
  background: hsl(var(--vg-overlay) / .96); border: 1px solid hsl(var(--vg-frame));
  box-shadow: 0 6px 16px -8px hsl(var(--vg-scrim) / .9);
  display: grid; place-items: center; gap: 2px; grid-auto-flow: row;
  cursor: grab;
}
.vg-tl-thumb::before, .vg-tl-thumb::after {
  content: ""; inline-size: 13px; block-size: 1.5px; border-radius: 2px; background: hsl(var(--vg-ink-dull)); }
.vg-tl-scrub.is-dragging .vg-tl-thumb { cursor: grabbing; border-color: hsl(var(--vg-accent)); }

/* floating peek bubble: big month + a mini 2×2 of thumbnails (JS sets --y) */
.vg-tl-bubble {
  position: absolute; inset-inline-end: calc(var(--vg-scrub-w) + 6px); inset-block-start: var(--y, 50%);
  transform: translateY(-50%) scale(.96);
  inline-size: 176px; padding: 12px; border-radius: 14px;
  background: hsl(var(--vg-overlay) / .97);
  border: 1px solid hsl(var(--vg-frame));
  box-shadow: 0 26px 60px -24px hsl(var(--vg-scrim) / .92), 0 0 0 .5px hsl(0 0% 100% / .04) inset;
  -webkit-backdrop-filter: blur(20px) saturate(1.3); backdrop-filter: blur(20px) saturate(1.3);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s var(--vg-ease), transform .16s var(--vg-ease), visibility .16s;
  z-index: 9;
}
.vg-tl-scrub.is-peek .vg-tl-bubble { opacity: 1; visibility: visible; transform: translateY(-50%) scale(1); }
.vg-tl-bubble__label { font-family: var(--vg-fdisplay); font-weight: 700; font-size: 15px;
  color: hsl(var(--vg-ink)); }
.vg-tl-bubble__sub { font-size: 11px; color: hsl(var(--vg-ink-faint)); margin-block-start: 1px;
  font-variant-numeric: tabular-nums; }
.vg-tl-bubble__peek { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-block-start: 10px; }
.vg-tl-peekcell { aspect-ratio: 1; border-radius: 7px; overflow: hidden; position: relative;
  background: linear-gradient(150deg, hsl(var(--ph-h, 268) 30% 26%), hsl(var(--ph-h, 268) 26% 14%)); }
.vg-tl-peekcell img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }

/* ============================== EMPTY STATE ============================== */
.vg-empty {
  position: absolute; inset: 0; margin: auto; block-size: max-content; inline-size: max-content;
  max-inline-size: 80%;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center; color: hsl(var(--vg-ink-faint));
}
.vg-empty__glyph { font-size: 30px; opacity: .7; display: grid; place-items: center; }
.vg-empty__glyph .ico { display: block; stroke-width: 1.6; }   /* icons.js "archive", explicitly sized 30px by the JS */
.vg-empty__title { font-family: var(--vg-fdisplay); font-weight: 700; font-size: 14px; color: hsl(var(--vg-ink-dull)); }
.vg-empty__hint { font-size: 12.5px; }

/* ============================== RESPONSIVE (container queries on .vg) ==============================
   Tunables are overridden on the SCROLL surfaces because a container can't answer its own query.
   vault-gallery.js reads --vg-row-h / --vg-gap off the gallery scroll surface, so these drive JS too. */
@container vg (max-width: 1000px) {
  .vg-gal-scroll, .vg-tl-scroll { --vg-row-h: 178px; --vg-min-tile: 124px; }
}
@container vg (max-width: 760px) {
  .vg-gal-scroll, .vg-tl-scroll { --vg-row-h: 150px; --vg-min-tile: 112px; --vg-gap: 3px; }
}
@container vg (max-width: 600px) {
  /* scrubber collapses to a thin touch strip; its labels hide, dots remain */
  .vg-tl-scroll { --vg-scrub-w: 20px; --vg-row-h: 132px; --vg-min-tile: 100px; }
  .vg { --vg-scrub-w: 20px; --vg-pad: 9px; }
  .vg-tl-scrub { opacity: 1; }                      /* always discoverable on touch */
  .vg-tl-tick__label { display: none; }
  .vg-tl-tick { padding-inline: 0 4px; }
  .vg-tl-thumb { inline-size: 14px; block-size: 30px; border-radius: 999px; }
  .vg-tl-thumb::before, .vg-tl-thumb::after { inline-size: 1.5px; block-size: 12px; }
  .vg-tl-bubble { inline-size: 150px; }
}
@container vg (max-width: 430px) {
  .vg-gal-scroll, .vg-tl-scroll { --vg-row-h: 116px; --vg-min-tile: 92px; }
  .vg-tile__name { -webkit-line-clamp: 1; line-clamp: 1; }
}

/* ============================== MOTION — one orchestrated enter, reduced-motion guarded ============================== */
@media (prefers-reduced-motion: no-preference) {
  .vg[data-anim="in"] .vg-tile {
    animation: vg-tile-in .42s var(--vg-ease) both;
    animation-delay: calc(min(var(--i, 0), 26) * 11ms);
  }
  @keyframes vg-tile-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }
}
@media (prefers-reduced-motion: reduce) {
  .vg *, .vg *::before, .vg *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  .vg-tile__img { opacity: 1; }                     /* no cross-fade → just show it */
}
@media (prefers-reduced-transparency: reduce) {
  .vg-tl-mhead, .vg-tl-bubble, .vg-tl-thumb, .vg-tile__dur { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .vg-tl-bubble { background: hsl(var(--vg-overlay)); }
  .vg-tl-mhead { background: hsl(var(--vg-app)); }
}
@media (forced-colors: active) {
  .vg-tile { border-color: CanvasText; }
  .vg-tile:has(> .vg-tile__check[aria-pressed="true"]) { outline: 3px solid Highlight; }
  .vg-tl-tick.is-current { color: Highlight; }
}

/* ============================== DEMO HARNESS ONLY (vault-gallery-test.html) ==============================
   These .vgx-* rules style the throwaway ?demo=1 test page. They are NOT part of the production module —
   the Vault mounts .vg roots directly into its explorer surface. Kept here only so the harness stays
   script/style-free under strict CSP. */
.vgx-page { block-size: 100%; min-block-size: 0; display: flex; flex-direction: column; overflow-y: auto;
  overflow-x: hidden; background: hsl(var(--vg-app)); }
.vgx-sec { flex: 0 0 auto; display: flex; flex-direction: column; }
.vgx-sec__head { display: flex; align-items: center; gap: 10px; padding: 14px 16px 8px; }
.vgx-sec__eyebrow { font-family: var(--vg-fdisplay); font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: hsl(var(--vg-accent)); }
.vgx-sec__title { font-family: var(--vg-fdisplay); font-size: 16px; font-weight: 700; color: hsl(var(--vg-ink)); }
.vgx-sec__note { font-size: 12px; color: hsl(var(--vg-ink-faint)); margin-inline-start: auto; }
.vgx-mount { position: relative; block-size: 62vh; min-block-size: 360px; margin: 0 12px 18px;
  border: 1px solid hsl(var(--vg-line)); border-radius: 14px; overflow: hidden; background: hsl(var(--vg-app)); }
.vgx-selbar { flex: 0 0 auto; padding: 6px 16px 14px; font-size: 12px; color: hsl(var(--vg-ink-faint));
  font-variant-numeric: tabular-nums; }

/* #5 per-tile "set preview image" affordance */
.vg-tile__edit { position: absolute; inset-block-start: 6px; inset-inline-end: 6px; inline-size: 27px; block-size: 27px; border-radius: 7px; background: hsl(var(--vg-overlay) / .82); border: 1px solid hsl(var(--vg-line)); color: hsl(var(--vg-ink)); font-size: 13px; display: grid; place-items: center; z-index: 4; cursor: pointer; opacity: 0; transition: opacity .15s, border-color .15s; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.vg-tile__edit .ico { display: block; pointer-events: none; }   /* icons.js "image", explicitly sized 15px by the JS */
.vg-tile:hover .vg-tile__edit, .vg-tile:focus-within .vg-tile__edit { opacity: 1; }
.vg-tile__edit:hover { border-color: hsl(var(--vg-accent)); }
@media (pointer: coarse) { .vg-tile__edit { opacity: .9; } }
