/* Shared image lightbox — the "saves board" layout, reused everywhere.
   Pairs with anecdote-lightbox.js. The base .dict-lb chrome (backdrop, stage,
   arrows, rail, caption, zoom) lives in dictionary.css; this file adds the
   saves-edition layout: image + tools in the left 2/3, a Pinterest-style
   exploration rail in the right 1/3. Class-scoped — safe to load anywhere. */

.sv-lb.dict-lb{--reco-w:clamp(340px,38vw,560px);padding-right:var(--reco-w);z-index:400}
.sv-lb .dict-lb-stage,
.sv-lb .dict-lb-img{max-width:min(56vw,900px)}
.sv-lb .dict-lb-arrow--next{right:calc(var(--reco-w) + 26px)}

.sv-reco{
  position:absolute;top:0;right:0;bottom:0;width:var(--reco-w,clamp(340px,38vw,560px));
  background:var(--bg);border-left:1px solid rgba(var(--ink-rgb),.18);
  display:flex;flex-direction:column;
  z-index:5;
}
.sv-reco-head{
  padding:16px 18px 12px;
  font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);
  border-bottom:1px solid rgba(var(--ink-rgb),.12);
}
.sv-reco-body{
  flex:1;overflow-y:auto;min-height:0;overflow-x:hidden;
  padding:14px 16px 12px;
}
.sv-reco-empty{font-size:11.5px;color:var(--mute);line-height:1.6}

.sv-reco-label{
  font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--mute);margin:16px 0 8px;
}
.sv-reco-label:first-child{margin-top:0}
.sv-reco-works{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.sv-rw{
  border:1px solid rgba(var(--ink-rgb),.14);background:var(--paper);
  padding:0;cursor:pointer;font:inherit;color:inherit;text-align:left;
  overflow:hidden;border-radius:8px;
}
.sv-rw:hover{border-color:var(--ink)}
.sv-rw img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block}
.sv-rw-t{
  display:block;font-size:10.5px;font-weight:700;letter-spacing:-.01em;
  padding:6px 9px 7px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.sv-rp{
  display:flex;align-items:center;gap:10px;width:100%;
  border:0;background:none;padding:6px 4px;cursor:pointer;
  font:inherit;color:inherit;text-align:left;border-radius:8px;
}
.sv-rp:hover{background:rgba(var(--ink-rgb),.05)}
.sv-rp img,.sv-rp-empty{
  width:34px;height:34px;object-fit:cover;flex:0 0 34px;display:block;
  border-radius:6px;background:rgba(var(--ink-rgb),.08);
}
.sv-rp-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.sv-rp-name{font-size:12.5px;font-weight:700;letter-spacing:-.01em}
.sv-rp-role{
  font-size:9.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.sv-reco-movs{display:flex;flex-wrap:wrap;gap:6px}
.sv-reco-chip{
  display:inline-block;font:inherit;font-size:10.5px;font-weight:600;cursor:pointer;
  border:1px solid rgba(var(--ink-rgb),.22);background:none;color:var(--mute);
  padding:4px 10px;border-radius:999px;
}
.sv-reco-chip:hover{color:var(--ink);border-color:var(--ink)}
.sv-reco-full{
  display:block;break-inside:avoid;margin-top:6px;padding:10px 2px 0;
  border-top:1px solid rgba(var(--ink-rgb),.12);
  font-size:11px;font-weight:700;color:var(--accent);
}

/* ≤980px: Pinterest-style page (2026-07-22, owner) — no dark blur, no bottom
   sheet. The lightbox becomes an opaque scrolling page: image on top, caption,
   a compact action bar, then the exploration grid inline below. Pull down at
   the top and it minimizes closed (JS in anecdote-lightbox.js). !important
   where we must beat dictionary.css/saves.css absolute-overlay positioning. */
@media (max-width:980px){
  .sv-lb.dict-lb{
    padding:0 !important;
    background:var(--bg);
    overflow-y:auto;overflow-x:hidden;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
    overflow-anchor:none;   /* ROOT CAUSE of "opens scrolled down": when the
                               image loads and grows above the scroll position,
                               scroll anchoring shoves scrollTop down. Off = the
                               page stays pinned at the top where open() put it. */
  }
  .sv-lb .dict-lb-imgbox,
  .sv-lb .dict-lb-stage{ overflow-anchor:none; }
  .sv-lb.dict-lb.is-open{
    display:flex !important;flex-direction:column;
    /* ⭐ THE real "opens scrolled down" cause: base .dict-lb centers its child
       (justify/align center) to float the image mid-screen. On mobile the tall
       scrolling column then gets vertically CENTERED — the image floats above
       the reachable scroll top, so you land mid-page on the rail. Anchor the
       column to the top and stretch it full width. */
    justify-content:flex-start !important;
    align-items:stretch !important;
  }
  .sv-lb.is-minimizing{
    transform:translateY(12%) scale(.93);opacity:0;
    transition:transform .26s ease,opacity .26s ease;
  }
  .sv-lb .dict-lb-backdrop{display:none}   /* opaque page — no blurred mess */

  /* 1 · the work — min-height reserves the image area BEFORE the photo
     loads, so late image layout can never shove the page mid-scroll */
  .sv-lb .dict-lb-stage{
    position:relative !important;inset:auto !important;
    order:1;flex:none;
    max-width:100% !important;width:100%;
    min-height:44vh;
    padding:56px 14px 10px !important;
    display:flex;align-items:center;justify-content:center;
    cursor:default;
  }
  .sv-lb .dict-lb-imgbox{max-width:100%}
  .sv-lb .dict-lb-img{
    max-width:100% !important;max-height:56vh;
    border-radius:14px;box-shadow:0 10px 34px rgba(0,0,0,.18);
  }

  /* 2 · caption (on paper now, not over a dark backdrop — !important because
     saves.css/dictionary.css set the white-on-dark colors) */
  .sv-lb .dict-lb-caption{
    position:static !important;order:2;flex:none;
    padding:2px 18px 4px;text-align:center;
    color:var(--ink) !important;font-size:12.5px;line-height:1.5;
  }
  .sv-lb .dict-lb-caption b,
  .sv-lb .dict-lb-cap-title{color:var(--ink) !important}
  .sv-lb .dict-lb-cap-count{color:var(--mute) !important}
  .sv-lb .dict-lb-cap-hint{display:none}

  /* 3 · compact action bar (was a huge floating pill cluster) */
  .sv-lb .dict-lb-rail{
    position:static !important;order:3;flex:none;
    margin:8px auto 6px;width:calc(100% - 28px);max-width:520px;
    display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:center;
    /* FIXED dark surface in BOTH themes — the cream action buttons + cream tool
       icons are designed for a dark rail. Using var(--ink-rgb) here flipped the
       rail to light in dark mode → cream-on-light = invisible (the inversion). */
    background:rgba(28,25,18,.94) !important;border-radius:14px;
    padding:10px 12px;
  }
  .sv-lb .dict-lb-rail-group{
    display:flex;flex-wrap:wrap;gap:6px;justify-content:center;
    margin:0 !important;padding:0 !important;border:0 !important;
  }
  .sv-lb .dict-lb-action{font-size:9.5px !important;padding:8px 12px !important}
  .sv-lb .dict-lb-tool{width:30px !important;height:30px !important}

  /* 4 · exploration grid, inline — scroll through it like Pinterest */
  .sv-lb .sv-reco{
    position:static !important;order:4;flex:none;
    width:100% !important;height:auto !important;
    transform:none !important;transition:none !important;
    border:0 !important;border-top:1px solid rgba(var(--ink-rgb),.14) !important;
    border-radius:0 !important;box-shadow:none !important;
    margin-top:8px;
  }
  .sv-lb .sv-reco-head{cursor:default;padding:16px 18px 10px}
  .sv-lb .sv-reco-head::after{display:none !important;content:none}
  .sv-lb .sv-reco-body{overflow:visible;padding:6px 16px 40px}

  /* arrows overlay the image and scroll away with it — never over the grid */
  .sv-lb .dict-lb-arrow{
    position:absolute !important;top:calc(56px + 24vh) !important;bottom:auto !important;
    z-index:5;
  }
  .sv-lb .dict-lb-arrow--prev{left:8px !important}
  .sv-lb .dict-lb-arrow--next{right:8px !important}

  /* ✕ stays reachable while you scroll */
  .sv-lb .dict-lb-close{position:fixed !important;top:12px;right:12px;z-index:6}
}

/* ═══ 2026-09-09 round (owner feedback) ═══ */

/* Page scroll lock while the lightbox is open — the page underneath must
   never scroll along with the exploration rail (the double-scroll glitch). */
html.alb-lock, html.alb-lock body { overflow: hidden !important; }

/* One dark layer, ever. The base .dict-lb-backdrop's blur(6px) forced a
   full-screen re-blur on every flight frame AND every rail scroll — that was
   the open lag and most of the rail lag. No blur; slightly deeper dim; one
   short fade-in on open (so there's no veil→backdrop double-dark flash). */
.sv-lb .dict-lb-backdrop{
  backdrop-filter:none !important; -webkit-backdrop-filter:none !important;
  background:rgba(17,15,12,.88);
}
.sv-lb.dict-lb.is-open .dict-lb-backdrop{ animation:albFadeIn .28s ease both; }
@keyframes albFadeIn{ from{ opacity:0; } }

/* The flight handover: the IMAGE leads. While the clone flies, everything is
   hidden (card fully transparent — it must never appear before the image).
   When the clone lands, the card BUILDS FROM the image: paper fades in around
   it, then the sections cascade downward — title, maker, description,
   research, actions — each fading in as it settles into place. */
/* transition:none while arriving — hiding must be INSTANT. Without it, a
   REOPEN transitioned the previous card's content 1→0 through the cascade
   delays, so the old card sat visible while the image flew at it. */
.sv-lb.dict-lb.is-arriving .dict-lb-stage,
.sv-lb.dict-lb.is-arriving .dict-lb-rail,
.sv-lb.dict-lb.is-arriving .dict-lb-caption,
.sv-lb.dict-lb.is-arriving .dict-lb-arrow,
.sv-lb.dict-lb.is-arriving .dict-lb-close,
.sv-lb.dict-lb.is-arriving .alb-info-head,
.sv-lb.dict-lb.is-arriving .alb-maker,
.sv-lb.dict-lb.is-arriving .alb-desc,
.sv-lb.dict-lb.is-arriving .alb-fact,
.sv-lb.dict-lb.is-arriving .sv-reco{ opacity:0 !important; transition:none !important; }
.sv-lb.dict-lb.is-arriving .alb-card{ transition:none !important; }
@media (min-width:981px){
  /* the cascade: shared transition + increasing delays, top to bottom */
  .sv-lb .alb-info-head,
  .sv-lb .alb-maker,
  .sv-lb .alb-desc,
  .sv-lb .alb-fact,
  .sv-lb .dict-lb-rail,
  .sv-lb .sv-reco{ transition:opacity .26s ease, transform .26s ease; }
  .sv-lb .alb-info-head{ transition-delay:.05s; }
  .sv-lb .alb-maker{ transition-delay:.12s; }
  .sv-lb .alb-desc{ transition-delay:.19s; }
  .sv-lb .alb-fact{ transition-delay:.26s; }
  .sv-lb .dict-lb-rail{ transition-delay:.33s; }
  .sv-lb .sv-reco{ transition-delay:.2s; }
  .sv-lb.dict-lb.is-arriving .alb-card{ background:transparent; box-shadow:none; }
  .sv-lb.dict-lb.is-arriving .alb-info-head,
  .sv-lb.dict-lb.is-arriving .alb-maker,
  .sv-lb.dict-lb.is-arriving .alb-desc,
  .sv-lb.dict-lb.is-arriving .alb-fact,
  .sv-lb.dict-lb.is-arriving .dict-lb-rail{ transform:translateY(-8px); transition-delay:0s; }
  .sv-lb.dict-lb.is-arriving .sv-reco{ transition-delay:0s; }
}

/* ═══ the object card (2026-09-10 round) ═══
   Mobile keeps its Pinterest-page layout untouched: the wrapper is
   display:contents, so its children stay direct flex items of .sv-lb. */
.alb-card{ display:contents; }

/* ── label block (both viewports) ── */
.alb-info-head{ display:flex; align-items:baseline; gap:10px; }
.alb-title{
  font-size:16.5px; font-weight:800; letter-spacing:-.01em; color:var(--ink);
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.alb-year{ font-size:11.5px; font-weight:600; color:var(--mute); font-variant-numeric:tabular-nums; white-space:nowrap; }
.alb-count{ margin-left:auto; font-size:10px; font-weight:600; color:var(--mute); font-variant-numeric:tabular-nums; white-space:nowrap; }
.alb-maker{
  display:flex; align-items:center; gap:11px; width:100%;
  margin:10px 0 0; padding:8px 10px; cursor:pointer; text-align:left;
  font:inherit; color:inherit;
  background:none; border:1px solid rgba(var(--ink-rgb),.14); border-radius:10px;
  transition:border-color .16s ease, background .16s ease;
}
.alb-maker:hover{ border-color:var(--ink); }
.alb-maker-pic{
  width:42px; height:42px; flex:0 0 42px; border-radius:9px; overflow:hidden;
  background:rgba(var(--ink-rgb),.08);
  display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:800; color:var(--mute); letter-spacing:.04em;
}
.alb-maker-pic img{ width:100%; height:100%; object-fit:cover; display:block; }
.alb-maker-txt{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.alb-maker-name{ font-size:13px; font-weight:700; letter-spacing:-.01em; color:var(--ink); }
.alb-maker-role{
  font-size:9px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--accent); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.alb-maker-go{
  margin-left:auto; flex:none;
  font-size:10px; font-weight:700; color:var(--mute); white-space:nowrap;
}
.alb-maker:hover .alb-maker-go{ color:var(--ink); }
.alb-desc{ margin:10px 2px 0; font-size:12.5px; line-height:1.6; color:var(--ink); }
.alb-fact{
  margin:10px 0 0; padding:9px 12px;
  border-left:2px solid var(--accent); background:rgba(var(--ink-rgb),.045);
  font-size:11.5px; line-height:1.55; color:var(--ink);
}
.alb-fact-k{
  display:block; margin-bottom:3px;
  font-size:8.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--accent);
}
.alb-fact-t{ display:inline; }
.alb-fact-src{ margin-left:6px; font-size:10px; font-weight:700; color:var(--accent); white-space:nowrap; }
.alb-hint{
  margin-left:auto; align-self:center;
  font-size:8.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--mute);
}

/* ── desktop: the paper card ── */
@media (min-width:981px){
  .sv-lb .alb-card{
    display:flex; flex-direction:column; align-items:stretch;
    position:relative; z-index:2;
    background:var(--paper); border-radius:14px; overflow:hidden;
    box-shadow:0 34px 90px rgba(0,0,0,.5);
    /* width is set by JS (sizeStage) = image width + equal 22px padding all
       around, so the card always hugs the picture; these are just guards */
    min-width:340px; max-width:96vw; max-height:94vh;
    transition:background-color .28s ease, box-shadow .28s ease;
  }
  .sv-lb .dict-lb-stage{ padding:22px 22px 0; justify-content:center; }  /* the image matted on the paper */
  .sv-lb .dict-lb-img{ box-shadow:none !important; }   /* the base lightbox's image shadow darkened the label */
  .sv-lb .alb-info{ padding:15px 22px 0; }
  .sv-lb .dict-lb-rail{
    position:static; margin:14px 0 0; padding:11px 22px 13px;
    background:none !important; border:0; border-top:1px solid rgba(var(--ink-rgb),.1);
    border-radius:0; backdrop-filter:none !important;
    justify-content:flex-start; gap:10px; flex-wrap:wrap;
  }
  /* actions restyled for paper: quiet outline pills, Save carries the accent */
  .sv-lb .dict-lb-action{
    background:none; border:1px solid rgba(var(--ink-rgb),.28); color:var(--ink);
  }
  .sv-lb .dict-lb-action:hover{ border-color:var(--ink); background:rgba(var(--ink-rgb),.05); }
  .sv-lb .dict-lb-action[data-lb="save"]{
    background:var(--accent); border-color:var(--accent); color:#fff;
  }
  .sv-lb .dict-lb-action[data-lb="save"]:hover{ background:#a93d21; border-color:#a93d21; }
  .sv-lb .dict-lb-tool{ background:none; border:1px solid rgba(var(--ink-rgb),.28); color:var(--ink); }
  .sv-lb .dict-lb-caption{ display:none; }             /* the card header replaces it */
}

/* ── mobile: slot the label block into the existing page flow ── */
@media (max-width:980px){
  .sv-lb .alb-info{ order:3; padding:6px 18px 0; }
  .sv-lb .dict-lb-rail{ order:4; }
  .sv-lb .sv-reco{ order:5; }
  .sv-lb .alb-info-head{ display:none; }               /* the caption already names the work */
  .alb-hint{ display:none; }
}

/* ⭐ Uniform stage v2: every image opens at the SAME height (64vh); the frame's
   WIDTH is fitted to each image's true aspect by JS (sizeStage in
   anecdote-lightbox.js) using the natural dimensions — so the frame IS the
   image: no letterboxing, the caption/actions sit tight under the picture at
   a constant height, and the gallery flight can land on the exact rect.
   The base .dict-lb-stage max-height:70vh + overflow:hidden must not clip. */
@media (min-width:981px){
  .sv-lb .dict-lb-stage{
    max-height:none !important; max-width:none !important;
    overflow:visible; flex:none;
  }
  .sv-lb .dict-lb-img{
    width:100% !important; height:100% !important;
    max-width:none !important; max-height:none !important;
    object-fit:contain;
  }
  .sv-lb .dict-lb-rail{ margin-top:14px; }
  .sv-lb .dict-lb-caption{ margin-top:10px; }
}
@media (max-width:980px){
  .sv-lb .dict-lb-imgbox{ width:100%; height:52vh; }
  .sv-lb .dict-lb-img{
    width:100% !important; height:100% !important;
    max-width:none !important; max-height:none !important;
    object-fit:contain;
    border-radius:0; box-shadow:none;   /* contain letterboxes — chrome on the empty box looks wrong */
  }
}

/* Exploration rail performance: off-screen cards skip layout/paint entirely
   (the rail scrolls hundreds of full-res hotlink thumbs — this is the fix
   for the scroll lag), and hovers stay border-only (no repaint storms). */
.sv-rw{ content-visibility:auto; contain-intrinsic-size:auto 168px; }

/* Skeleton shimmer while rail thumbs load (the dictionary node-hover
   pattern): a grey shimmer holds the 4/3 space, the image fades in. */
.sv-rw-ph{
  position:relative; aspect-ratio:4/3; overflow:hidden;
  background:rgba(var(--ink-rgb),.06);
}
.sv-rw-ph::after{
  content:""; position:absolute; top:0; bottom:0; left:-60%; width:60%;
  background:linear-gradient(100deg,transparent,rgba(var(--ink-rgb),.12),transparent);
  /* transform sweep — runs on the compositor, unlike a background-position
     animation which repaints every cell every frame (that was lag too) */
  animation:albSweep 1.25s linear infinite;
  will-change:transform;
}
.sv-rw-ph.is-loaded::after{ display:none; }
.sv-rw-ph img, .sv-rw-ph canvas{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block;
  opacity:0; transition:opacity .5s ease;
}
.sv-rw-ph.is-loaded img, .sv-rw-ph.is-loaded canvas{ opacity:1; }
@keyframes albSweep{
  to{ transform:translateX(280%); }
}
@media (prefers-reduced-motion: reduce){
  .sv-rw-ph::after{ animation:none; }
  .sv-rw-ph img, .sv-rw-ph canvas{ transition:none; }
}
