/* L1 无界画布 */

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  touch-action: none;              /* 手指平移由我们接管 */
  cursor: grab;
  contain: strict;
}
.stage.is-dragging { cursor: grabbing; }

/* 只淡化卡片层：中心完全不透明，越靠近画布边缘越融入背景。 */
.canvas-fade {
  position: absolute;
  inset: 0;
  -webkit-mask-image: radial-gradient(ellipse 72% 68% at center,
                      #000 44%, rgba(0, 0, 0, .70) 65%,
                      rgba(0, 0, 0, .18) 84%, transparent 100%);
  mask-image: radial-gradient(ellipse 72% 68% at center,
              #000 44%, rgba(0, 0, 0, .70) 65%,
              rgba(0, 0, 0, .18) 84%, transparent 100%);
}
.canvas-fade.is-finite {
  -webkit-mask-image: none;
  mask-image: none;
}

@media (min-width: 901px) {
  .stage {
    left: var(--sidebar-w);
    transition: left var(--d-base) var(--ease);
  }
}

.field {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;             /* 只是个坐标原点，尺寸无意义 */
  will-change: transform;
}

/* 筛选切换：旧画布先收走，有限结果再逐张落进规则网格。 */
body.is-ready .field.is-layout-switching {
  opacity: 0;
  pointer-events: none;
  transition: opacity 170ms ease;
}
@keyframes finite-card-in {
  from { opacity: 0; filter: blur(5px); }
  to { opacity: 1; filter: none; }
}
.card.is-finite.is-layout-entering {
  animation: finite-card-in 420ms var(--ease) both;
  animation-delay: calc(var(--finite-order) * 20ms);
}

/* ── 卡片 ─────────────────────────────────────────────── */

.card {
  position: absolute;
  top: 0; left: 0;
  /* 尺寸交给 CSS：--card 由 viewport.measure() 发布，一次 resize 才变一次。
     写在 JS 里会变成每帧给每张卡重写一遍同样的值。 */
  width: var(--card, 160px);
  height: var(--card, 160px);
  border-radius: var(--card-radius);
  border: 0;
  background: #fff;
  box-shadow: 0 2px 7px -2px rgba(17, 17, 17, .34);
  isolation: isolate;              /* 让混合只作用在卡片内部 */
  contain: layout paint;           /* 每张卡独立重绘，不把滤镜刷新扩散到整块画布 */
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  opacity: .7;
  /* 刻意不加 will-change：真正在做 transform 动画的是 .field，卡片自己只在
     换绑时写一次。给 80 张卡各提一个合成层，低端安卓上是几十 MB 层内存。 */
  transition: opacity var(--d-base) var(--ease),
              filter   var(--d-base) var(--ease),
              box-shadow var(--d-base) var(--ease);
}

/* 所有非焦点卡片统一使用原来的纯黑白效果。 */
.card__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;          /* Safari 合成滤镜层时也始终由自身保持圆角 */
  background-size: cover;
  background-repeat: no-repeat;
  filter: grayscale(1);
  mix-blend-mode: multiply;
  transition: filter var(--d-base) var(--ease);
}

/* 黑色 lighten 层与灰度图组合成原有的黑白效果。 */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  background: #000;
  mix-blend-mode: lighten;
  pointer-events: none;
  opacity: 1;
  transition: opacity var(--d-base) var(--ease);
}

/* 手指拖动、惯性与吸附期间以正确的最终状态直接换帧，避免移动端同时计算
   灰度、混合、阴影过渡；停稳后的普通点击与 hover 仍保留原有动画。 */
.stage.is-moving .card,
.stage.is-moving .card__img,
.stage.is-moving .card::after {
  transition: none;
}

/* 没有卡片.webp 的作品：非焦点同样使用黑白文字卡片。 */
.card__img.is-empty {
  display: grid;
  place-items: center;
  padding: 12%;
  font-size: clamp(11px, 1.1vw, 15px);
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  color: #111;
  mix-blend-mode: normal;
  filter: none;
}

/* 没有图片的文字卡片同样以中性灰呈现。 */
.card.is-text { background: #e7e7e3; }
.card.is-text::after { display: none; }
.card.is-text.is-focus { background: var(--card-color, #777); }
.card.is-text.is-focus .card__img { color: var(--card-ink, #fff); }

/* 阅读与点赞状态共用高度、底色和动画，形状按内容区分。 */
.card__heart,
.card__read {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  height: 21px;
  border-radius: var(--r-pill);
  background: rgba(17, 17, 17, .35);
  opacity: 0;
  transform: scale(.82);
  pointer-events: none;
  transition: opacity var(--d-fast) var(--ease), transform var(--d-fast) var(--ease);
}

/* 投过票：右下角红色爱心。 */
.card__heart {
  bottom: 9px;
  right: 9px;
  width: 21px;
  min-width: 21px;
  padding: 0;
  border-radius: 50%;
  color: var(--heart);
  transform-origin: bottom right;
}
.card.is-voted .card__heart { opacity: 1; transform: none; }

/* 已读：左下角文字胶囊。 */
.card__read {
  left: 9px;
  bottom: 9px;
  min-width: 34px;
  padding: 0 7px;
  color: rgba(255, 255, 255, .86);
  font-size: 10px;
  line-height: 1;
  letter-spacing: .04em;
  transform-origin: bottom left;
}
.card.is-read .card__read { opacity: 1; transform: none; }

/* ── 三种状态 ─────────────────────────────────────────── */

/* 已读与未读共用同一套卡片效果，只以左下角标签区分。 */
.card.is-read .card__img { filter: grayscale(1); mix-blend-mode: multiply; }
.card.is-read::after { opacity: 1; }

/* 焦点：原图全彩 */
/* 缩放走变量：位置是 JS 内联写的 translate3d，样式表里的 transform 压不过它。
   render.js 把 scale(var(--k,1)) 写进内联 transform，这里只改变量。 */
.card.is-focus {
  opacity: 1;
  z-index: 3;
  --k: 1.10;
  box-shadow: 0 24px 64px -14px rgba(17, 17, 17, .50);
}
.card.is-focus .card__img { filter: none; mix-blend-mode: normal; }
.card.is-focus::after { opacity: 0; }

/* 有限画布用于浏览筛选结果：所有作品都恢复主题色，不再用黑白区分状态。 */
.card.is-finite .card__img { filter: none; mix-blend-mode: normal; }
.card.is-finite::after { opacity: 0; }
.card.is-finite { opacity: 1; }
.card.is-finite.is-text { background: var(--card-color, #777); }
.card.is-finite.is-text .card__img { color: var(--card-ink, #fff); }

@media (hover: hover) {
  .card:not(.is-focus):hover .card__img { filter: none; mix-blend-mode: normal; }
  .card:not(.is-focus):hover::after { opacity: 0; }
  .card.is-text:not(.is-focus):hover { background: var(--card-color, #777); }
  .card.is-text:not(.is-focus):hover .card__img { color: var(--card-ink, #fff); }
}

/* ── 侧栏收起时顶部的焦点信息胶囊 ─────────────────────── */

.focus-label {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: fit-content;
  max-width: min(520px, calc(100% - 184px));
  height: 42px;
  min-width: 0;
  padding: 3px var(--s4);
  border: 1px solid #34343A;
  border-radius: var(--r-pill);
  background: #0C0C0E;
  color: #F2F0EC;
  box-shadow: 0 5px 18px rgba(17, 17, 17, .18);
  text-align: center;
  appearance: none;
  font: inherit;
  cursor: pointer;
  pointer-events: auto;
  overflow: hidden;
  will-change: width;
  transition: opacity var(--d-base) var(--ease);
}
.focus-label__name {
  display: block;
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.focus-label__blurb {
  display: block;
  margin-top: 2px;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.15;
  color: #909096;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.is-ready.is-locked .focus-label { opacity: 0; pointer-events: none; }

/* 桌面侧栏展开时信息已在列表中；手机侧栏打开时画布被覆盖，均隐藏胶囊。 */
@media (min-width: 901px) {
  body.is-ready:not(.sidebar-collapsed) .focus-label { opacity: 0; pointer-events: none; }
}
@media (max-width: 900px) {
  .focus-label {
    left: auto;
    right: 0;
    transform: none;
    max-width: calc(100% - 104px);
  }
  body.is-ready.sidebar-open .focus-label { opacity: 0; pointer-events: none; }
}
