/* ============================================================================
   联系我们 · 开场动画（只在 /lianxi/?intro=1 加载）
   --------------------------------------------------------------------------
   画面：纸面全屏，左上大标语逐字打出，房子对齐页内 .ch-house 的画框，
        横向红线压在 54% 高度从左向右画出，房子随红线一笔一笔勾线，
        到头 100% 后渲染图接上，最后从红线位置上下拉开纸面，露出联系页。
   命名：一律 .ch-intro-{区块}（top/copy/art/draw/scan/meter/steps/stage），
        状态类统一 is-{on|in|ready|run|fast|top|bottom}。
   ⚠ 兼容性（全站共用底线）：纯 CSS，无嵌套 / 无 Sass 语法，无 !important。
        用到 var() 自定义属性、:has()、aspect-ratio、clamp()、min()、:is()、
        scaleX/translateY 变换 → 支持到 Chrome/Edge 105+、Safari 16.4+、
        Firefox 121+（:is() 更宽松：Chrome 88+/Safari 14+）。
   ⚠ 不要给 .ch-intro-photo 去掉 width/height:100%
        绝对定位的替换元素在 left/right 与 width:auto 时会用固有宽度，
        不会自动撑满画框（这里的 100% 有用，不是冗余）。
   ============================================================================ */
/* 开场期间锁滚动：html 一起锁，否则移动端地址栏收放时会露出滚动条 */
html:has(body.ch-intro-on),
body.ch-intro-on {
  overflow: hidden;
}

body.ch-intro-on {
  visibility: hidden;
}

.ch-intro {
  position: fixed;
  inset: 0;
  z-index: 99990;
  visibility: visible; /* body 被隐藏，这一层要显式可见 */
}

/* 纸面：收在 stage 层，收尾「拉开」时整层被拆成上下两半各自退场。
   底色 = 站点同款（主题底色 + 噪点纸），变量定义在 body 上，fixed 层照样继承 */
.ch-intro-stage {
  position: absolute;
  inset: 0;
  background: var(--body-bg-color, #f5f2ec) var(--ch-noise, none) repeat;
  background-size: 124px 124px;
  overflow: hidden;
}

/* 拉开用的两半纸面：JS 收尾时把 stage 塞进上半、克隆一份进下半，
   切缝处的灰线就是两半各自的描边，跟着纸面一起走 */
.ch-intro-shutter {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  box-sizing: border-box; /* JS 按红线高度写 height，1px 描边要算进高度里 */
  overflow: hidden;
  will-change: transform;
  transition: transform .95s cubic-bezier(.65, 0, .35, 1);
}

.ch-intro-shutter.is-top {
  top: 0;
  border-bottom: 1px solid #a9a59c;
}

.ch-intro-shutter.is-bottom {
  bottom: 0;
  border-top: 1px solid #a9a59c;
}

.ch-intro-shutter.is-top.is-run {
  transform: translateY(-102%);
}

.ch-intro-shutter.is-bottom.is-run {
  transform: translateY(102%);
}

/* 跳过时只把拉开压快，不做别的动画 */
.ch-intro.is-fast .ch-intro-shutter {
  transition-duration: .38s;
}

/* ---- 顶部两枚小字 ---- */
.ch-intro-top {
  position: absolute;
  left: 4vw;
  right: 4vw;
  top: 28px;
  display: flex;
  justify-content: space-between;
  gap: 20px;
  font-family: var(--ch-font-mono, ui-monospace, monospace);
  font-size: 10px;
  letter-spacing: .2em;
  color: rgba(31, 31, 31, .5);
}

/* ---- 左上大标语 ----
   max-width 要容得下「第二行缩进 3.5 字」后的整行，窄了会把尾字挤到下一行 */
.ch-intro-copy {
  position: absolute;
  left: 4vw;
  top: 13vh;
  max-width: 60vw;
}

.ch-intro-title {
  margin: 0;
  font-size: clamp(28px, 4vw, 62px);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.02em;
  color: #1b1b1b;
}

/* 第二行错位：起点落在第一行「重」字的右半边附近 */
.ch-intro-title .ch-intro-l2 {
  padding-left: 3.5em;
}

/* 标题逐字打上去：JS 把文字拆成 .ch-ch，逐个点亮 */
.ch-intro-title .ch-ch {
  opacity: 0;
}

.ch-intro-title .ch-ch.is-on {
  opacity: 1;
}

.ch-intro-sub {
  margin: 22px 0 0;
  max-width: 34em;
  font-size: clamp(15px, 1.15vw, 18px);
  line-height: 1.85;
  color: rgba(31, 31, 31, .58);
  opacity: 0;
  transition: opacity .5s ease;
}

.ch-intro-sub.is-in {
  opacity: 1;
}

/* ---- 右下：16:9 画框（桌面上 JS 会按页内 .ch-house 重设成同位同尺寸） ---- */
.ch-intro-art {
  position: absolute;
  right: 0;
  bottom: 0;
  width: min(68vw, 1280px);
  aspect-ratio: 16 / 9;
}

.ch-intro-draw {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  aspect-ratio: 1576 / 700;
  overflow: hidden;
}

/* 主题的 img,svg{max-width:100%} 会把按百分比放大的线稿夹回 100%，比例全乱 ——
   图片与内联 svg 都要解掉这条限制 */
.ch-intro-draw img,
.ch-intro-lines {
  max-width: none;
  max-height: none;
}

.ch-intro-draw img {
  position: absolute;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

/* 渲染图：勾完线才淡入 */
.ch-intro-photo {
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity .75s ease;
}

.ch-intro-photo.is-in {
  opacity: 1;
}

/* 线稿：按实测比例叠在图上（left -8.1% / top -19% / 115.7% × 135.5%），
   每一笔都正好落在房子的墙、屋顶、窗和台阶上 */
.ch-intro-lines {
  position: absolute;
  left: -8.1%;
  top: -19.006%;
  width: 115.747%;
  height: 135.473%;
  overflow: visible; /* 内联 svg 默认 overflow:hidden，放大后会裁掉伸出画框的笔画 */
  pointer-events: none;
  opacity: 0;
  transition: opacity .7s ease;
}

.ch-intro-lines.is-ready {
  opacity: 1;
}

/* 线稿用铅笔灰，别是纯黑。主题给 svg path 兜了深色 fill，会把闭合轮廓填成实心块，
   用 #chIntro 的 ID 特异性压回 fill:none（链上不出现 !important） */
#chIntro .ch-intro-lines :is(path, line) {
  fill: none;
  stroke: #24242a;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- 满屏红线：横线压在 54% 高度（正好穿过房子中部），从左向右画出 ----
   用 scaleX 从左缘长大；整条线平移会变成「右边先有、往左缩」的镜像 */
.ch-intro-scan {
  position: absolute;
  left: 0;
  right: 0;
  top: 54%;
  z-index: 4;
  height: 1px;
  background: #e4002b;
  box-shadow: 0 1px 10px rgba(228, 0, 43, .28);
  opacity: 0;
  pointer-events: none;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: opacity .25s ease;
}

.ch-intro-scan.is-on {
  opacity: 1;
}

/* ---- 进度读数：缀在红线头后面（位置由 JS 每帧写 transform） ---- */
.ch-intro-meter {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 5;
  font-family: var(--ch-font-mono, ui-monospace, monospace);
  font-size: 11px;
  letter-spacing: .12em;
  color: #e4002b;
  white-space: nowrap;
}

/* ---- 右上：加载步骤（红线扫不到这里） ---- */
.ch-intro-steps {
  position: absolute;
  right: 4vw;
  top: 9.5vh;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: right;
  font-family: var(--ch-font-mono, ui-monospace, monospace);
  font-size: 10px;
  line-height: 2.05;
  color: rgba(31, 31, 31, .8);
}

.ch-intro-steps em {
  font-style: normal;
  color: rgba(31, 31, 31, .4);
}

.ch-intro-steps li {
  opacity: .22;
  transition: opacity .25s ease;
}

.ch-intro-steps li.is-on {
  opacity: 1;
}

/* 矮屏（13 寸笔记本等）把画收小，别顶到标题 */
@media (max-height: 780px) and (min-width: 992px) {
  .ch-intro-art {
    width: min(56vw, 980px);
  }
}

@media (max-width: 991.98px) {
  .ch-intro-copy {
    top: 11vh;
    right: 4vw;
    max-width: none;
  }

  .ch-intro-art {
    width: 100vw;
  }

  .ch-intro-steps {
    display: none; /* 窄屏放不下，直接不渲染 */
  }
}

@media (max-width: 600px) {
  .ch-intro-top {
    left: 20px;
    right: 20px;
    top: 20px;
  }

  .ch-intro-copy {
    left: 20px;
    right: 20px;
    top: 9vh;
  }

  .ch-intro-sub {
    font-size: 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ch-intro-photo,
  .ch-intro-lines {
    transition: none;
  }
}
