/* ==========================================================================
   基础层：重置 + 全局排版 + 通用行为
   所有页面共用，先于页面级样式加载。
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font-sans);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img,
svg,
video,
canvas {
    max-width: 100%;
}

img {
    display: block;
    height: auto;
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    font: inherit;
    color: inherit;
}

/* 懒加载图片的占位底色，避免加载瞬间白块跳动 */
img[loading="lazy"] {
    background-color: var(--gray-100);
}

/* 骨架屏微光：懒加载图未就绪时扫光占位，就绪后由模糊转清晰淡入。
   用 html.js 做门控——脚本没跑起来时图片保持原样，绝不会白屏。 */
@keyframes skeleton-shimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

html.js img[loading="lazy"] {
    transition: filter .5s var(--ease);
}

html.js img[loading="lazy"]:not(.is-loaded) {
    filter: blur(10px);
    background-image: linear-gradient(90deg,
        transparent 0%, rgba(255, 255, 255, .07) 50%, transparent 100%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.4s linear infinite;
}

/* 统一焦点可见样式，兼顾键盘可达性 */
:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

/* 尊重系统「减少动态效果」设置 */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }

    html.js .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ── 滚动入场动画（通用，由 assets/js/reveal.js 触发 .is-visible） ──
   采用渐进增强：仅当 JS 可用（html.js）时才隐藏待入场元素，
   无脚本 / 脚本被拦截时元素天然可见，绝不会出现白屏。 */
html.js .reveal {
    opacity: 0;
    transform: translateY(var(--reveal-distance));
    transition: opacity var(--reveal-duration) var(--ease-out),
                transform var(--reveal-duration) var(--ease-out);
    transition-delay: var(--reveal-delay, 0s);
    will-change: opacity, transform;
}

html.js .reveal.is-visible {
    opacity: 1;
    transform: none;
    /* 入场结束后立即释放合成层：常驻 will-change 会让每个 .reveal 长期占据
       一层 GPU 纹理，移动端元素多时会被系统回收纹理，表现为局部空白/闪烁 */
    will-change: auto;
}
