/* =========================================================
   星TAP · 摄影站  —  cinematic editorial photography portfolio
   Dark, film-grain, asymmetric. Lenis + GSAP driven.
   移动端适配统一依赖前置于本文件的 xtap-mobile.css
   （视口 --vh/--vh-s、安全区 --safe-*、间距 --gap-* / --pad-page / --tap 令牌）。
   ========================================================= */

@layer reset, tokens, base, components, utilities;

/* 关键修复：全局重置必须放进最低优先级的 reset 层，
   否则未分层的 *{padding:0} 会盖掉 components 层里 .section/.nav 等的内边距 → 移动端全贴边、无留白 */
@layer reset {
  *{margin:0;padding:0;box-sizing:border-box}
}
html{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-stopped{overflow:hidden}

body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--body);
  font-size:16px;
  line-height:1.7;
  overflow-x:hidden;
  font-weight:400;
  letter-spacing:.01em;
}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
::selection{background:var(--accent);color:#0b0b0d}

@layer components {
/* ---------- film grain overlay ---------- */
.grain{
  position:fixed;inset:0;z-index:9000;pointer-events:none;
  opacity:.045;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size:160px 160px;
}

/* ---------- custom cursor ----------
   不用 mix-blend-mode:difference——在图片上反差色发闷难看。
   改为主题金色小点 + 柔光描边；静止时轻微"呼吸"（缩放 12→17px），
   悬停放大为半透明金环（呼吸动画让位给过渡，不冲突）。 */
[data-cursor]{
  position:fixed;left:0;top:0;width:12px;height:12px;border-radius:50%;
  background:var(--accent);z-index:9999;
  box-shadow:0 0 0 1px rgba(232,201,143,.35),0 0 16px rgba(201,163,106,.30);
  pointer-events:none;transform:translate(-50%,-50%);
  display:flex;align-items:center;justify-content:center;
  transition:width .35s var(--ease),height .35s var(--ease),background .35s var(--ease),box-shadow .35s var(--ease);
  will-change:transform;
}
[data-cursor]:not(.is-hover){animation:curBreathe 3.4s ease-in-out infinite}
@keyframes curBreathe{0%,100%{width:12px;height:12px}50%{width:17px;height:17px}}
[data-cursor] .c-label{font-family:var(--body);font-size:10px;letter-spacing:.08em;color:#141009;opacity:0;transform:scale(.6);transition:opacity .25s var(--ease),transform .25s var(--ease);text-transform:uppercase;pointer-events:none;white-space:nowrap}
[data-cursor].is-label .c-label{opacity:1;transform:scale(1)}
[data-cursor].is-hover{width:52px;height:52px;background:rgba(201,163,106,.88);
  box-shadow:0 0 0 1px rgba(232,201,143,.55),0 0 28px rgba(201,163,106,.45)}
@media (prefers-reduced-motion:reduce){[data-cursor]:not(.is-hover){animation:none}}

/* ---------- scroll progress ---------- */
.progress{position:fixed;top:0;left:0;height:2px;width:0;background:linear-gradient(90deg,var(--accent),#e8c98f);z-index:8500;transition:width .08s linear;will-change:width}

/* ---------- nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:8000;
  display:flex;align-items:center;justify-content:space-between;
  /* 左右内边距并入安全区令牌（带 0 降级，老内核不识别 env() 也不会整条声明失效） */
  padding:18px max(var(--pad),var(--safe-right));
  padding-left:max(var(--pad),var(--safe-left));
  transition:transform .5s var(--ease),background .4s var(--ease),padding .4s var(--ease),border-color .4s var(--ease);
  border-bottom:1px solid transparent;
}
.nav--solid{background:rgba(11,11,13,.72);backdrop-filter:blur(14px);border-bottom-color:var(--line-soft);padding-top:14px;padding-bottom:14px}
.nav--hide{transform:translateY(-110%)}
.brand{display:flex;align-items:center;gap:12px;flex-shrink:0;min-width:0}
.brand img{width:38px;height:38px;border-radius:50%;object-fit:cover;border:1px solid var(--line);flex-shrink:0}
.brand b{font-family:var(--display);font-weight:500;font-size:22px;letter-spacing:.04em;line-height:1.1;white-space:nowrap}
.brand span{display:block;font-size:10px;letter-spacing:.42em;color:var(--muted);text-transform:uppercase;margin-top:2px}
.nav-links{display:flex;align-items:center;gap:10px;padding-right:var(--safe-right)}
.nav-links a{font-size:13px;letter-spacing:.04em;color:var(--muted);
  padding:7px 16px;border-radius:999px;border:1px solid transparent;
  transition:color .3s,border-color .3s,background .3s;white-space:nowrap}
.nav-links a:hover{color:var(--ink);border-color:var(--line);background:var(--accent-soft)}
.nav-links a.is-active{color:var(--accent);border-color:var(--accent);background:var(--accent-soft);font-weight:600}
/* 首页新增「音乐站」入口（→ /music/ 子站），用主题金高亮，与背景乐胶囊区分 */
.nav-links a.nav-music{color:var(--accent);font-weight:600}
/* 小屏导航：改为横向滑动（像手机 App 标签栏），不再隐藏栏目，左右滑看全部 */
@media(max-width:760px){
  .nav-links{
    flex:1 1 auto;min-width:0;margin-left:14px;
    gap:8px;
    overflow-x:auto;overflow-y:hidden;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none;
    scroll-snap-type:x proximity;
    padding-bottom:3px;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 16px,#000 calc(100% - 16px),transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 16px,#000 calc(100% - 16px),transparent 100%);
  }
  .nav-links::-webkit-scrollbar{display:none}
  .nav-links a{scroll-snap-align:start;flex-shrink:0}
  .music-btn{flex-shrink:0}
  .brand b{display:none}
  .brand span{font-size:9px;letter-spacing:.3em}
}
/* 断点收敛：380 → 规范 xs 360（原 380 不在规范集内） */
@media(max-width:360px){
  .brand span{display:none}
}

/* music toggle */
.music-btn{
  display:flex;align-items:center;gap:10px;background:transparent;border:1px solid var(--line);
  color:var(--ink);border-radius:40px;padding:7px 14px 7px 11px;cursor:pointer;
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;transition:border-color .3s,color .3s;
}
.music-btn:hover{border-color:var(--accent)}
.eq{display:flex;align-items:flex-end;gap:2px;height:14px;width:16px}
.eq i{width:2px;background:var(--accent);height:30%;border-radius:2px;transition:height .2s}
.music-btn.playing .eq i{animation:eq .9s ease-in-out infinite}
.eq i:nth-child(2){animation-delay:.15s}.eq i:nth-child(3){animation-delay:.3s}.eq i:nth-child(4){animation-delay:.45s}
@keyframes eq{0%,100%{height:25%}50%{height:100%}}

/* ---------- hero ---------- */
/* hero 用「稳定视口」--vh-s（=100svh）：滚动时不随微信/浏览器工具栏收放而跳动 */
.hero{position:relative;height:var(--vh-s);min-height:620px;overflow:hidden;display:flex;align-items:flex-end}
.hero-img{position:absolute;inset:-8% 0;width:100%;height:116%;object-fit:cover;filter:brightness(.5) saturate(.9) contrast(1.02);will-change:transform}
.hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,11,13,.55) 0%,rgba(11,11,13,.15) 38%,rgba(11,11,13,.85) 100%)}
.hero-inner{position:relative;z-index:2;padding:max(100px,calc(var(--vh-s) * .14)) var(--pad) clamp(48px,calc(var(--vh-s) * .09),110px);width:100%;align-self:flex-end}
.hero-kicker{font-size:12px;letter-spacing:.5em;text-transform:uppercase;color:var(--accent);margin-bottom:18px;opacity:.9}
/* 中文大标题不能用 0.92 行高，否则“光/影”上半笔画被切；溢出不隐藏，保证字形完整 */
.hero-title{font-family:var(--display);font-weight:300;line-height:1.08;font-size:clamp(52px,12.5vw,180px);letter-spacing:.01em}
.hero-line{display:block;overflow:visible}
.hero-line .word{display:inline-block;will-change:transform}
.hero-sub{margin-top:22px;max-width:540px;color:var(--muted);font-size:clamp(15px,1.6vw,18px);line-height:1.8}
.hero-cue{position:absolute;right:var(--pad);bottom:clamp(48px,calc(var(--vh-s) * .09),110px);z-index:2;display:flex;flex-direction:column;align-items:center;gap:10px;color:var(--muted);font-size:10px;letter-spacing:.3em;text-transform:uppercase}
.hero-cue .bar{width:1px;height:54px;background:linear-gradient(var(--accent),transparent);animation:cue 2.2s var(--ease) infinite}
@media(max-width:760px){
  .hero{min-height:580px}
  .hero-title{font-size:clamp(46px,15vw,92px);line-height:1.12}
  .hero-kicker{letter-spacing:.32em;font-size:11px}
  .hero-cue{display:none}
}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}55%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

/* ---------- generic section ---------- */
.section{padding:clamp(80px,calc(var(--vh-s) * .14),180px) var(--pad)}
.sec-head{display:flex;align-items:baseline;gap:18px;margin-bottom:clamp(36px,calc(var(--vh-s) * .06),72px)}
.sec-num{font-family:var(--display);font-size:clamp(40px,7vw,90px);color:var(--accent);font-weight:300;line-height:1;opacity:.55}
.sec-title{font-family:var(--display);font-weight:400;font-size:clamp(28px,4.5vw,56px);line-height:1.05}
.sec-title small{display:block;font-family:var(--body);font-size:12px;letter-spacing:.36em;text-transform:uppercase;color:var(--muted);margin-top:12px;font-weight:400}
.lead{font-family:var(--display);font-weight:300;font-size:clamp(24px,3.6vw,46px);line-height:1.4;max-width:1000px;color:var(--ink);text-wrap:pretty;word-break:keep-all;letter-spacing:.01em}
/* 中文无真斜体，浏览器伪造斜体会把字拉斜挤压；改用强调色+字重，不用 italic */
.lead em{font-style:normal;color:var(--accent);font-weight:500}

/* ---------- intro statement ---------- */
.intro{display:grid;grid-template-columns:1fr;gap:clamp(30px,5vw,70px)}
@media(min-width:880px){.intro{grid-template-columns:1.4fr .9fr;align-items:end}}
.intro p{color:var(--muted);font-size:clamp(15px,1.5vw,17px);max-width:60ch}
.intro .tag{font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent);margin-bottom:14px}

/* ---------- gallery (masonry) ---------- */
.gallery{columns:3;column-gap:clamp(14px,1.6vw,26px)}
@media(max-width:1000px){.gallery{columns:2}}
/* 断点收敛：620 → 规范 md 640 */
@media(max-width:640px){.gallery{columns:1}}
.shot{break-inside:avoid;margin-bottom:clamp(14px,1.6vw,26px);position:relative;overflow:hidden;border-radius:3px;cursor:pointer;background:var(--bg-2)}
.shot img{width:100%;height:auto;opacity:0;transition:opacity .8s var(--ease),transform 1.1s var(--ease),filter .6s var(--ease);filter:brightness(.92) saturate(.95)}
.shot img.is-loaded{opacity:1}
.shot:hover img{transform:scale(1.045);filter:brightness(1) saturate(1.02)}
.shot figcaption{position:absolute;left:0;right:0;bottom:0;padding:18px 18px 16px;display:flex;justify-content:space-between;align-items:flex-end;gap:10px;
  background:linear-gradient(0deg,rgba(11,11,13,.82),transparent);opacity:0;transform:translateY(8px);transition:opacity .45s var(--ease),transform .45s var(--ease)}
.shot:hover figcaption{opacity:1;transform:translateY(0)}
.shot figcaption b{font-family:var(--display);font-weight:500;font-size:21px;letter-spacing:.02em}
.shot figcaption span{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--accent)}

/* ---------- feature full-bleed ---------- */
.feature{position:relative;height:clamp(420px,calc(var(--vh-s) * .78),860px);overflow:hidden;display:flex;align-items:flex-end}
.feature img{position:absolute;inset:-10% 0;width:100%;height:120%;object-fit:cover;filter:brightness(.62) saturate(.95);will-change:transform}
.feature .cap{position:relative;z-index:2;padding:var(--pad);max-width:680px}
/* 短引语/标题：用 text-wrap:balance 让浏览器在任意窗口宽度下动态均衡分行，
   从根本解决"末行甩一个字"的断头字问题（窗口缩放/全屏/半屏都自适应）。
   配合 word-break:keep-all 防止 CJK 被按单字硬拆（中文断头字另一根源）。
   长正文才用 text-wrap:pretty（防孤字孤行），二者按文本长度分工。 */
.feature .cap b{font-family:var(--display);font-weight:300;font-size:clamp(26px,4vw,52px);line-height:1.15;display:block;text-wrap:balance;word-break:keep-all}
.feature .cap span{color:var(--muted);font-size:13px;letter-spacing:.2em;text-transform:uppercase}

/* ---------- words rotator ---------- */
.words{background:var(--bg-2);border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}
.rotator{min-height:clamp(180px,calc(var(--vh-s) * .30),320px);display:flex;align-items:center;position:relative}
.quote{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;opacity:0;transition:opacity .9s var(--ease)}
.quote.active{opacity:1}
.quote q{font-family:var(--display);font-weight:300;font-style:normal;font-size:clamp(26px,4.4vw,60px);line-height:1.3;quotes:none;max-width:1100px;word-break:normal;overflow-wrap:anywhere}
/* 标点参与断行：悬挂标点（Safari 渐进增强，其他浏览器忽略）+ 超窄屏溢出兜底 */
.lead,.quote q,.feature .cap b{hanging-punctuation:force-end allow-end}
@media(max-width:360px){
  .lead,.quote q,.feature .cap b{overflow-wrap:anywhere}
}
.quote q::before,.quote q::after{content:""}
.quote cite{display:block;margin-top:22px;font-style:normal;font-size:12px;letter-spacing:.28em;text-transform:uppercase;color:var(--accent)}
.words-nav{display:flex;gap:10px;margin-top:38px}
.words-nav button{width:var(--tap);height:var(--tap);border-radius:50%;border:1px solid var(--line);background:transparent;color:var(--ink);cursor:pointer;font-size:15px;transition:border-color .3s,background .3s}
.words-nav button:hover{border-color:var(--accent);background:var(--accent-soft)}

/* ---------- motion cards ---------- */
.motion-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2vw,30px)}
@media(max-width:760px){.motion-grid{grid-template-columns:1fr}}
.motion{position:relative;overflow:hidden;border-radius:3px;aspect-ratio:16/10;cursor:pointer;background:#000}
.motion video,.motion img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:brightness(.8)}
.motion .play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;z-index:2}
.motion .play span{width:74px;height:74px;border-radius:50%;border:1px solid rgba(236,231,221,.7);display:flex;align-items:center;justify-content:center;
  backdrop-filter:blur(4px);background:rgba(11,11,13,.35);transition:transform .4s var(--ease),background .4s}
.motion:hover .play span{transform:scale(1.1);background:var(--accent)}
.motion .play span::before{content:"";border-left:16px solid var(--ink);border-top:10px solid transparent;border-bottom:10px solid transparent;margin-left:5px}
.motion .m-cap{position:absolute;left:0;bottom:0;z-index:2;padding:18px;background:linear-gradient(0deg,rgba(11,11,13,.8),transparent);width:100%}
.motion .m-cap b{font-family:var(--display);font-weight:500;font-size:22px}
.motion .m-cap span{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--accent)}

/* ---------- about / footer ---------- */
.about{display:grid;gap:clamp(30px,5vw,70px)}
@media(min-width:880px){.about{grid-template-columns:1fr 1fr;align-items:start}}
.about p{color:var(--muted);max-width:54ch}
.links{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.links a{border:1px solid var(--line);border-radius:40px;padding:10px 18px;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);transition:border-color .3s,color .3s}
.links a:hover{border-color:var(--accent);color:var(--accent)}
.foot{padding:clamp(40px,calc(var(--vh-s) * .07),80px) var(--pad);border-top:1px solid var(--line-soft);display:flex;flex-wrap:wrap;gap:18px;justify-content:space-between;align-items:center;color:var(--faint);font-size:12px;letter-spacing:.08em}
.foot .credit b{color:var(--muted);font-weight:400}

/* ---------- lightbox ---------- */
.lb{position:fixed;inset:0;z-index:9500;background:rgba(7,7,9,.94);backdrop-filter:blur(8px);display:none;align-items:center;justify-content:center;flex-direction:column;padding:clamp(20px,5vw,70px)}
.lb.open{display:flex}
.lb-stage{position:relative;flex:1;width:100%;display:flex;align-items:center;justify-content:center;perspective:2200px;transform-style:preserve-3d}
/* 3D 立体卡片轮播：active 居中 / prev·next 居于侧后方(景深+旋转+模糊+低透明)，
   切换时两张卡同时在场、互让位（手法学自用户 2025 摄影展网页画廊，沿用本站点暗色电影感） */
.lb-card{position:absolute;top:50%;left:50%;display:none;align-items:center;justify-content:center;max-width:92vw;max-height:calc(var(--vh) * .8);transform-style:preserve-3d;will-change:transform,opacity,filter;pointer-events:none;
  transition:transform var(--lb-dur) var(--lb-ease),opacity var(--lb-dur) var(--lb-ease),filter var(--lb-dur) var(--lb-ease)}
.lb-card.active{display:flex;z-index:100;transform:translate(-50%,-50%) translate3d(0,0,0) rotateY(0deg);opacity:1;pointer-events:auto}
.lb-card.prev{display:flex;z-index:50;transform:translate(-50%,-50%) translate3d(-90%,0,-850px) rotateY(44deg);opacity:.16;filter:blur(5px)}
.lb-card.next{display:flex;z-index:50;transform:translate(-50%,-50%) translate3d(90%,0,-850px) rotateY(-44deg);opacity:.16;filter:blur(5px)}
.lb-card img{max-width:92vw;max-height:calc(var(--vh) * .8);object-fit:contain;border-radius:2px;box-shadow:0 40px 120px rgba(0,0,0,.9);border:1px solid rgba(236,231,221,.08);backface-visibility:hidden}
/* 视频默认不接收指针事件；只有 active 卡内的视频可交互，杜绝 prev/next 位置的视频铺满屏后拦截翻页按钮点击 */
.lb-card video{max-width:92vw;max-height:calc(var(--vh) * .8);object-fit:contain;border-radius:2px;box-shadow:0 40px 120px rgba(0,0,0,.9);border:1px solid rgba(236,231,221,.08);backface-visibility:hidden;pointer-events:none}
.lb-card.active video{pointer-events:auto}
.lb .lb-cap{position:relative;z-index:200;margin-top:18px;color:var(--muted);font-size:13px;letter-spacing:.12em;text-align:center}
.lb .lb-cap b{color:var(--ink);font-family:var(--display);font-size:20px;font-weight:500;margin-right:10px}
/* 控制层（关闭/翻页）必须压在 active 媒体卡之上，否则视频铺满屏时按钮点不到 —— 这是"退不回去"的根因 */
.lb .lb-close{position:absolute;top:22px;right:26px;width:46px;height:46px;border-radius:50%;border:1px solid var(--line);background:transparent;color:var(--ink);font-size:20px;cursor:pointer;z-index:200}
.lb .lb-close:hover{border-color:var(--accent)}
.lb .lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:54px;height:54px;border-radius:50%;border:1px solid var(--line);background:rgba(11,11,13,.4);color:var(--ink);font-size:20px;cursor:pointer;z-index:200}
.lb .lb-nav:hover{border-color:var(--accent)}
.lb .lb-prev{left:18px}.lb .lb-next{right:18px}

/* 移动端灯箱：控制按钮并入安全区（iPhone 刘海/手势条），放大点按热区 */
@media(max-width:760px){
  .lb .lb-close{top:calc(22px + var(--safe-top));right:calc(26px + var(--safe-right));width:var(--tap);height:var(--tap)}
  .lb .lb-nav{width:54px;height:54px}
  .lb .lb-prev{left:10px}.lb .lb-next{right:10px}
  .lb-stage{padding:0 var(--pad-page)}
}
} /* end @layer components */

/* ---------- reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  *{animation:none !important;transition:none !important}
  .grain{display:none}
  [data-cursor]{display:none}
  .hero-img,.feature img{transform:none !important}
  .shot img{opacity:1}
}
@media(pointer:coarse){
  [data-cursor]{display:none}
  .shot figcaption{opacity:1;transform:none}
}

/* ---------- Plyr 播放器（开源框架托管媒体生命周期） ---------- */
.lb-card .plyr{width:92vw;max-width:92vw;max-height:calc(var(--vh) * .8);border-radius:2px;box-shadow:0 40px 120px rgba(0,0,0,.9);border:1px solid rgba(236,231,221,.08);--plyr-color-main:var(--accent,#c9a24b)}
.lb-card .plyr video{max-width:100%;max-height:calc(var(--vh) * .8)}
.lb-card .plyr--video{background:#000}




