/* ═══════════════════════════════════════════════════════════
   年轮（/rings.html）· 翠影华章的一个浏览入口
   ── 只做奶粉浅色一套（全站已恒定 data-theme="light"，暗色与切换按钮已撤除）
   ── 玻璃只给三块：顶栏、搜索胶囊、底部年份条（红线：每页真折射 ≤3 块）
   ── 年轮本体（照片云）一个 backdrop-filter 都不加
   ═══════════════════════════════════════════════════════════ */

body { overflow: hidden; }                      /* 这一页不滚动，全靠拖拽与滚轮 */
body.has-tabbar { padding-bottom: 0; }

/* ── 空间 ── */
#space {
  position: fixed; inset: 0; overflow: hidden;
  perspective: 1500px; perspective-origin: 50% 50%;
  cursor: grab; touch-action: none;
}
#space.dragging { cursor: grabbing; }
#world {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}
.ring { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-style: preserve-3d; }

/* 照片卡：沿用相册页照片格的语汇（14px 圆角、自身环境色光晕、模糊底） */
.rz-card {
  position: absolute; left: 0; top: 0; margin: 0; padding: 0;
  width: var(--w, 64px); height: var(--h, 64px);
  border-radius: var(--r-tile, 14px); cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .78);
  background: #f7ece9 center / cover no-repeat;
  box-shadow: 0 6px 18px var(--glow, rgba(122, 74, 86, .18)), 0 1px 3px rgba(122, 74, 86, .14);
  /* ⚠️⚠️ 2026-09-25 先生报「移动光标时卡片会出现一道暗带」——根因就在这里，记下来免得再犯：
     祥第一版为了做"内层浮起"，给 .rz-glare 用了 translateZ 并把卡片改成 overflow:visible +
     preserve-3d。结果一张卡被浏览器拆成**两层**合成（底下的模糊占位图一层、照片一层），
     3D 变换逐帧变化时两层对不齐，缝里就漏出底下那张模糊图 —— 看上去就是一道撕裂的暗带。
     现在回到"一张卡只画一层"：卡片自己裁切（overflow:hidden）、不开 preserve-3d，
     内层那道光改用 2D 平移做视差（--gx/--gy，由 rings-parallax.js 写），层次少了，缝也就没了。 */
  overflow: hidden;
  transition: transform 300ms cubic-bezier(.22, .7, .25, 1),
              box-shadow var(--dur-micro, 200ms) var(--ease-apple, ease),
              opacity 220ms var(--ease-apple, ease), filter 220ms var(--ease-apple, ease);
}
.rz-clip { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
/* 内层那道光：卡片一倾斜它就朝反方向滑开几像素 —— 两层错开就是"视差"，
   而且只用 2D 平移，不必把卡片拆成多层（这正是那道暗带的来处）。 */
.rz-glare {
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 46%);
  opacity: .75;
  transform: translate3d(var(--gx, 0px), var(--gy, 0px), 0);
}
/* 悬停：向前浮起 + 放大 + 亮起（同款交互动画）。角度与位移都走变量，JS 只写变量。 */
.rz-card.hot { --hz: 44px; --hsc: 1.06; z-index: 60; }
.rz-card.hot .rz-glare { opacity: 1; }
.rz-card.anim { will-change: transform; }
/* 帧预算守卫降级档：只抬不放大（跟不上时 rings.js 自动加） */
#space.hover-lite .rz-card.hot { --hsc: 1; --hz: 26px; }
@media (prefers-reduced-motion: reduce) {
  .rz-card { transition-duration: 0ms; }
  .rz-card.hot { --hz: 0px; --hsc: 1; }
}
.rz-card img {
  width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit;
  opacity: 0; transform: scale(1.04); transition: opacity .5s ease, transform .9s ease;
}
.rz-card img.in { opacity: 1; transform: none; }
.rz-card:hover { box-shadow: 0 16px 40px var(--glow, rgba(122, 74, 86, .3)), 0 2px 6px rgba(122, 74, 86, .2); }
.rz-card:focus-visible { outline: 2px solid var(--a1); outline-offset: 3px; }
/* 未定位：暖色发丝描边（与站内"待定位"同一语汇） */
.rz-card.no-loc { border-color: rgba(156, 90, 70, .5); }
/* 搜索命中的强调 / 未命中压暗 */
.rz-card.hit { outline: 2px solid var(--a1); outline-offset: 2px; }
.rz-card.dim { opacity: .28; filter: saturate(.5); }
.rz-card.sel { box-shadow: 0 22px 54px rgba(166, 79, 99, .38), 0 2px 8px rgba(122, 74, 86, .2); }

/* 年份刻度：放在 2D 投影层里（跟着环的屏幕位置走），字不受透视缩放 */
.rz-labels { position: fixed; inset: 0; pointer-events: none; z-index: 50; }
.rz-ringlab {
  position: absolute; left: 0; top: 0; pointer-events: none; white-space: nowrap;
  transform: translate(-50%, -50%);
  display: flex; align-items: baseline; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(255, 252, 251, .82);
  border: 1px solid rgba(166, 79, 99, .14);
  font-size: 11px; letter-spacing: .06em; color: var(--muted); font-variant-numeric: tabular-nums;
  transition: opacity 200ms ease;
}
.rz-ringlab b { color: var(--text); font-weight: 600; font-size: 12px; }
.rz-ringlab i { font-style: normal; font-size: 10.5px; color: var(--faint); }
/* 没有拍摄时间的那一环：虚线 + 暖色，一眼看出它"不在时间里" */
.rz-card.unknown { border: 1px dashed rgba(156, 90, 70, .62); }
.rz-ringlab.unknown {
  border: 1px dashed rgba(156, 90, 70, .5);
  background: rgba(255, 249, 246, .9);
}
.rz-ringlab.unknown b { color: var(--warm); }

/* ── 三块玻璃（顶栏 / 搜索 / 年份条） ── */
.rz-top {
  position: fixed; left: 18px; right: 18px; top: 14px; z-index: 60;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 16px; border-radius: 999px;
  background: linear-gradient(160deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid rgba(255, 255, 255, .72);
  box-shadow: 0 8px 32px rgba(16, 24, 40, .10), inset 0 1px 0 rgba(255, 255, 255, .95);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
.rz-top .brand { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.rz-top .who { font-size: 12px; color: var(--muted); }
.rz-top .meta { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }

.rz-search {
  position: fixed; right: 18px; top: 78px; z-index: 60;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 999px; min-width: 268px;
  background: linear-gradient(160deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid rgba(255, 255, 255, .72);
  box-shadow: 0 8px 28px rgba(16, 24, 40, .09), inset 0 1px 0 rgba(255, 255, 255, .95);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
.rz-search svg { flex: none; color: var(--muted); }
.rz-search input {
  flex: 1; min-width: 0; border: 0; background: transparent; font: inherit;
  font-size: 13.5px; color: var(--text); outline: none;
}
.rz-search input::placeholder { color: var(--faint); }
.rz-search .enter {
  flex: none; border: 0; background: transparent; color: var(--muted);
  font-size: 15px; cursor: pointer; padding: 2px 4px; border-radius: 8px;
}
.rz-search .enter:hover { color: var(--text); }

.rz-timeline {
  position: fixed; left: 50%; bottom: 108px; transform: translateX(-50%); z-index: 60;
  display: flex; align-items: center; gap: 4px; padding: 7px 10px; border-radius: 999px;
  max-width: min(92vw, 900px); overflow-x: auto; scrollbar-width: none;
  background: linear-gradient(160deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid rgba(255, 255, 255, .72);
  box-shadow: 0 8px 28px rgba(16, 24, 40, .10), inset 0 1px 0 rgba(255, 255, 255, .95);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
.rz-timeline::-webkit-scrollbar { display: none; }
.rz-timeline button {
  font: inherit; font-size: 12px; font-weight: 600; white-space: nowrap;
  padding: 7px 13px; border-radius: 999px; border: 0; cursor: pointer;
  background: transparent; color: var(--text-2); font-variant-numeric: tabular-nums;
  transition: color var(--dur-micro, 200ms), background var(--dur-micro, 200ms);
}
.rz-timeline button:hover { background: rgba(166, 79, 99, .07); color: var(--text); }
.rz-timeline button.on {
  color: var(--on-accent);
  background: linear-gradient(135deg, var(--a1), #96536a);
  box-shadow: 0 2px 10px rgba(166, 79, 99, .26);
}
.rz-timeline button:focus-visible { outline: 2px solid var(--a1); outline-offset: 2px; }
.rz-timeline button.unknown { color: var(--warm); border: 1px dashed rgba(156, 90, 70, .45); }
.rz-timeline button.unknown.on { color: var(--on-warm); background: var(--warm); border-style: solid; }

/* ── 底部操作提示 ── */
/* （原来左下还有一句「ALL THE DAYS 日子，一圈一圈。」，2026-09-24 先生要求去掉，样式一并删除） */
.rz-hint {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 160px; z-index: 55;
  pointer-events: none; font-size: 11.5px; letter-spacing: .06em; color: var(--faint);
  padding: 5px 12px; border-radius: 999px;
  background: rgba(255, 252, 251, .68);
  border: 1px solid rgba(166, 79, 99, .10);
}
.rz-hint span { margin: 0 6px; opacity: .5; }

/* ── 聚焦：看单张（站内灯箱语汇的轻量版） ── */
.rz-viewer {
  position: fixed; inset: 0; z-index: 800; display: none;
}
.rz-viewer.on { display: block; }
.rz-viewer .scrim {
  position: absolute; inset: 0; background: rgba(68, 48, 47, .42);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.rz-viewer .box {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 92vw;
}
.rz-viewer img {
  max-width: min(92vw, 1200px); max-height: 74vh; object-fit: contain;
  border-radius: 12px; background: var(--bg-0);
  box-shadow: 0 18px 50px rgba(96, 60, 58, .38);
}
.rz-viewer .vbar { display: flex; align-items: center; gap: 10px; color: var(--text-2); font-size: 13px; }
.rz-viewer .close, .rz-viewer .nav {
  position: absolute; display: flex; align-items: center; justify-content: center;
  border-radius: 999px; cursor: pointer; font-size: 20px;
  color: var(--a1); background: rgba(255, 252, 251, .94);
  border: 1px solid rgba(122, 90, 86, .16); min-width: 44px; min-height: 44px;
}
.rz-viewer .close { top: -46px; right: 0; }
.rz-viewer .nav { top: 40%; width: 46px; height: 46px; font-size: 26px; }
.rz-viewer .nav.prev { left: -58px; }
.rz-viewer .nav.next { right: -58px; }
.rz-viewer .close:hover, .rz-viewer .nav:hover { background: var(--a1); color: var(--on-accent); border-color: transparent; }
@media (max-width: 1200px) {
  .rz-viewer .nav.prev { left: 6px; } .rz-viewer .nav.next { right: 6px; }
}
.rz-viewer .exif { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; }
.rz-viewer .exif span {
  padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 600;
  color: var(--text-2); background: rgba(255, 252, 251, .82);
  border: 1px solid var(--stroke); font-variant-numeric: tabular-nums;
}
.rz-viewer .exif span.cam { color: var(--warm); border-color: rgba(156, 90, 70, .35); }

/* ── 加载与空态 ── */
.rz-loading, .rz-empty {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 40;
  text-align: center; color: var(--muted); font-size: 14px;
}
.rz-empty .big { display: block; font-size: 15px; color: var(--text); margin-bottom: 6px; }
.rz-empty .sub { display: block; font-size: 12.5px; color: var(--faint); }

/* ── 窄屏 ── */
@media (max-width: 900px) {
  /* 顶栏在手机上会挤成三行：收掉计数与"看地图"（底部导航本来就有地图），并禁止折行 */
  .rz-top { left: 12px; right: 12px; top: 10px; padding: 8px 12px; gap: 10px; }
  .rz-top .meta, .rz-top .rz-map { display: none; }
  .rz-search { right: 12px; left: 12px; top: 60px; min-width: 0; }
  .rz-timeline { bottom: 100px; max-width: 94vw; }
  .rz-hint { bottom: 150px; font-size: 11px; white-space: nowrap; }
}
.rz-top .brand, .rz-top .link, .rz-top .meta { white-space: nowrap; }
.rz-hint { white-space: nowrap; }

/* 减少动态效果：交给 rings.js 直接不飞行动画，这里只兜底过渡 */
@media (prefers-reduced-motion: reduce) {
  .rz-card, .rz-card img { transition: none; }
}

/* ═══════════════════════════════════════════════════════════
   某一年单独成环（样品二那套：拖拽直驱 + 惯性 + 吸附）
   切换时：云那一层向四周散开并渐隐，只留这一年的环
   ═══════════════════════════════════════════════════════════ */

/* 年内模式：云已经淡出，但别让它继续截走指针 */
#space.year-mode #world, #space.year-mode .rz-labels { pointer-events: none; }

#carousel {
  position: fixed; inset: 0; z-index: 40;
  perspective: 1450px; perspective-origin: 50% 46%;
  opacity: 0; pointer-events: none;
  transition: opacity 420ms ease;
}
#carousel.on { opacity: 1; pointer-events: auto; cursor: grab; touch-action: none; }
#carousel.dragging { cursor: grabbing; }

.car-ring {
  position: absolute; left: 50%; top: 46%; width: 0; height: 0;
  transform-style: preserve-3d;
  --tilt: -13deg;                                   /* 与样品同一套俯仰：一圈才读得成"圈" */
  transform: translateZ(-170px) rotateX(var(--tilt)) rotateY(calc(var(--spin, 0) * 1deg));
  transition: transform 420ms cubic-bezier(.22, .7, .25, 1);
}
/* 拖拽期间关掉过渡 —— 这就是"跟手"的技术定义（有过渡就有滞后） */
.car-ring.no-anim { transition: none; }

.car-fig {
  position: absolute; left: 0; top: 0; margin: 0;
  width: var(--w, 150px); height: var(--h, 190px);
  transform-style: preserve-3d;
  /* 朝观看者：环转多少、自己转多少、轨道角多少，最后一次性抵消（俯仰只抵六成，留一点斜倚）。
     --dth 是悬停时"沿环滑开"的角度，--hpush/--hy/--sc 是悬停那张的向前、上移、放大。 */
  transform:
    translate(-50%, -50%)
    rotateY(calc(var(--th) + var(--dth, 0deg)))
    translateZ(var(--r))
    rotateY(calc((var(--th) + var(--dth, 0deg) + var(--spin, 0) * 1deg) * -1))
    rotateX(calc(var(--tilt, 0deg) * -0.6))
    translateZ(var(--hpush, 0px))
    translateY(var(--hy, 0px))
    translateZ(var(--lift, 0px))
    scale(var(--sc, 1))
    /* 视差（先生 2026-09-25：「特定时间点里的卡片加上视差动画」）：
       切到某一年之后，下面那排轮播卡跟着鼠标轻微倾斜；--prx/--pry 由 rings-parallax.js 写。
       ⚠️ 只能追加在这条链的**末尾** —— 前面的环定位／让位／抬升一格都不能动。 */
    rotateY(var(--prx, 0deg))
    rotateX(var(--pry, 0deg));
  /* 悬停让位的过渡：约 300ms、柔和缓动、只动 transform（先生的口述规格） */
  transition: transform 300ms cubic-bezier(.22, .7, .25, 1);
}
/* 悬停中的那一张：轻微上移 + 放大 + 向前一点（向前才能在 3D 里压住邻居） */
.car-fig.hot { --hy: -10px; --sc: 1.05; --hpush: 30px; }
/* 悬停加演（先生 2026-09-24）：**卡片那圈硬边淡出至透明，换成一圈柔光边框** ——
   硬边是画上去的一条白线；柔光边框则是一圈"糊过的光"：向外晕开、和背景融在一起，
   边缘微微溢出光晕。照片本身照旧清晰，只换它外面那一圈。
   先生看过样品卡后追加：「光效拥有呼吸效果」——所以做成**两层光**：
     · ::after  里圈：贴着边的一道亮 + 内里的微光（跟手淡入淡出）
     · ::before 外圈：更散的一团色晕，自己缓慢明灭，负责"呼吸"
   呼吸只动 transform（合成器上跑，不重绘、不碰 opacity，所以退场时的淡出过渡也不会被抢）。 */
.car-fig::after {
  content: ''; position: absolute; inset: -3px; border-radius: calc(var(--r-tile, 14px) + 2px);
  pointer-events: none; opacity: 0;
  border: 2.5px solid rgba(255, 255, 255, .95);
  box-shadow: 0 0 8px 1px rgba(255, 255, 255, .7),
    0 0 24px 5px var(--glow, rgba(166, 79, 99, .38)),
    inset 0 0 14px rgba(255, 252, 251, .45);
  filter: blur(5px);
  transition: opacity 320ms cubic-bezier(.22, .7, .25, 1);
}
.car-fig::before {
  content: ''; position: absolute; inset: -6px; border-radius: calc(var(--r-tile, 14px) + 5px);
  pointer-events: none; opacity: 0;
  box-shadow: 0 0 32px 10px var(--glow2, rgba(166, 79, 99, .5));
  filter: blur(9px);
  transition: opacity 380ms cubic-bezier(.22, .7, .25, 1);
}
.car-fig.hot::after { opacity: 1; animation: figBreathIn 2600ms cubic-bezier(.45, 0, .55, 1) infinite; }
.car-fig.hot::before { opacity: .95; animation: figBreathOut 2600ms cubic-bezier(.45, 0, .55, 1) infinite; }
.car-fig.hot .car-card { border-color: transparent; }   /* 硬边化掉，交给那两圈光 */
/* 呼吸：外圈胀得多一点、里圈少一点，光就像一呼一吸地往外漾 */
@keyframes figBreathOut { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes figBreathIn { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.028); } }
@media (prefers-reduced-motion: reduce) {
  .car-fig.hot::after, .car-fig.hot::before { animation: none; }
}
/* 动画期间才提升合成层，过渡完撤掉 */
.car-fig.anim { will-change: transform; }
/* 帧预算守卫降级档：只抬不放大（机器跟不上时 rings.js 自动加） */
#carousel.hover-lite .car-fig { transition-duration: 180ms; }
#carousel.hover-lite .car-fig.hot { --sc: 1; --hpush: 18px; }
/* 减少动态效果：不摆姿势，只留很短的反馈 */
@media (prefers-reduced-motion: reduce) {
  .car-fig { transition-duration: 110ms; }
}
.car-fig:focus-visible { outline: none; }
.car-fig:focus-visible .car-card { outline: 3px solid var(--a1); outline-offset: 3px; }

.car-card {
  position: absolute; inset: 0; margin: 0; padding: 0; width: 100%; height: 100%;
  border-radius: var(--r-tile, 14px); overflow: hidden; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .8);
  background: #f7ece9 center / cover no-repeat;
  box-shadow: 0 10px 26px var(--glow, rgba(122, 74, 86, .2)), 0 2px 6px rgba(122, 74, 86, .12);
  transition: box-shadow 280ms ease, border-color 320ms cubic-bezier(.22, .7, .25, 1);
}
.car-card.no-loc { border-color: rgba(156, 90, 70, .5); }
.car-card img {
  width: 100%; height: 100%; object-fit: contain; display: block; border-radius: inherit;
  opacity: 0; transform: scale(1.03); transition: opacity .5s ease, transform .8s ease;
}
.car-card img.in { opacity: 1; transform: none; }
/* 提亮叠层（不用 filter，只动透明度） */
.car-fig.sel .car-card { box-shadow: 0 24px 54px rgba(166, 79, 99, .3), 0 3px 10px rgba(122, 74, 86, .18); }
.car-fig.sel .car-card::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: rgba(255, 252, 251, .5); opacity: .32;
}
.car-fig figcaption {
  position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
  margin-top: 8px; font-size: 11.5px; line-height: 1.5; white-space: nowrap;
  color: var(--muted); font-variant-numeric: tabular-nums; user-select: text;
}
.car-fig figcaption b { color: var(--text); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════
   Flip to Detail —— 点封面：飞到屏幕中心并放大 → 绕 Y 轴翻到背面（轻微回弹）
   关闭：先翻回来，再飞回它原来那一格。全程只动 transform / opacity。
   ═══════════════════════════════════════════════════════════ */
/* 飞走之后原位不再显示那张照片（免得同一张同时出现在两处） */
.car-fig.flip-hidden { opacity: 0; transition: opacity 240ms ease, transform 300ms cubic-bezier(.22,.7,.25,1); }
/* 动画过程中背景变柔：**只模糊年环那一层**。
   云那层（#space）在年内模式下本来就是 opacity:0（看不见），模糊它是白花钱——
   祥第一版两层都模糊，实测出现一帧 154ms 的长帧。顶栏与筹码保持清楚，只被压暗。
   ⚠️ 这里**不写 transition**：模糊的浓度由 bgRide() 用 WAAPI 跟着飞行那一段走
   （同一个时长、同一条曲线），写成 CSS 过渡会变成背景自己演一段、卡片另演一段＝割裂。
   will-change 留着：先让这层成为合成层，否则"第一帧加模糊"要现场重绘，实测冒一帧 70ms。 */
#carousel { will-change: filter; }
/* ── 翻层样式已整段删除（2026-09-25）────────────────────────────
   先生要「相册同款动画」，而这里原先躺着年轮**自己的一份拷贝**（#flip / .flip-card /
   .flip-meta …），与相册那份已经走散：相册后来加的"鼠标 3D 倾斜""内层浮起视差"
   "关闭时先收倾角"，年轮这边一样都没有。
   现在改用相册那份唯一的 public/flip-detail.css（在 rings.html 里排在 rings.css 之前）。
   本文件只保留年轮自己那两条：.car-fig.flip-hidden 与 #carousel 的 will-change: filter。 */

/* ── 卡片视差的内层深度（角度见上面 .car-fig 那条 transform 链的末尾）──
   照片 6px、说明牌 18px：卡片一倾斜，两层就错开，这就是"视差"的来处。 */
.car-card { transform: translateZ(6px); }
.car-fig figcaption { transform: translateZ(18px); }
@media (prefers-reduced-motion: reduce) {
  .car-fig { --prx: 0deg; --pry: 0deg; }
}

