/* ==========================================================
 * deepspace 模板 - 业务组件 (弹窗 / Toast / 详情页 / 文章 / 单页)
 * ========================================================== */

/* ==================== 骨架屏 (Skeleton) ==================== */
.ds-skeleton {
    position: relative;
    background: linear-gradient(90deg, var(--ds-bg-2) 0%, var(--ds-bg-3) 50%, var(--ds-bg-2) 100%);
    background-size: 200% 100%;
    animation: ds-skeleton-shine 1.4s ease-in-out infinite;
    border-radius: 8px;
    color: transparent !important;
    overflow: hidden;
    user-select: none;
}
@keyframes ds-skeleton-shine {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
.ds-skel-text   { height: 14px; margin: 4px 0; border-radius: 4px; }
.ds-skel-text-sm{ height: 11px; }
.ds-skel-text-lg{ height: 20px; }
.ds-skel-block  { height: 120px; border-radius: 8px; }
.ds-skel-ico    { width: 40px; height: 40px; border-radius: 8px; }
.ds-skel-cover  { aspect-ratio: 16/9; border-radius: 8px; }

/* 站点骨架卡 */
.ds-skel-site {
    display: flex; align-items: center; gap: var(--ds-gap-3);
    padding: var(--ds-gap-3);
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    overflow: hidden;
}
.ds-skel-site .ds-skel-ico { flex: 0 0 auto; }
.ds-skel-site__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.ds-skel-site__body > div { height: 12px; border-radius: 4px; }

/* 文章骨架卡 */
.ds-skel-post {
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    overflow: hidden;
}
.ds-skel-post__body { padding: var(--ds-gap-4); display: flex; flex-direction: column; gap: 8px; }
.ds-skel-post__body > div { height: 12px; border-radius: 4px; }

/* 站点详情骨架 */
.ds-skel-detail { padding: var(--ds-gap-6); background: var(--ds-bg-2); border: 1px solid var(--ds-border); border-radius: var(--ds-radius-lg); display: flex; gap: var(--ds-gap-4); align-items: center; }
.ds-skel-detail__head { width: 72px; height: 72px; border-radius: 12px; flex: 0 0 auto; }
.ds-skel-detail__body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 10px; }
.ds-skel-detail__body > div { height: 14px; border-radius: 4px; }

@media (max-width: 640px) {
    .ds-skel-detail { flex-direction: column; align-items: stretch; }
    .ds-skel-detail__head { width: 100%; height: 80px; }
}

/* 真实内容 fade-in (防止 FOUC) */
[data-skel-target] { opacity: 1; transition: opacity var(--ds-dur) var(--ds-ease); }
[data-skel][data-loading] [data-skel-target] { opacity: 0; }
[data-skel][data-loading]::before {
    content: "";
    position: absolute;
    inset: 64px 20px 20px 20px;
    background: linear-gradient(90deg, var(--ds-bg-2) 0%, var(--ds-bg-3) 50%, var(--ds-bg-2) 100%);
    background-size: 200% 100%;
    animation: ds-skeleton-shine 1.4s ease-in-out infinite;
    border-radius: 8px;
    z-index: 0;
    pointer-events: none;
}
[data-skel] { position: relative; }
[data-skel][data-loading] .ds-card__head { opacity: 0.4; }

/* ==================== 原创弹窗 ==================== */
.ds-modal {
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    display: flex; align-items: center; justify-content: center;
    z-index: 200;
    opacity: 0; visibility: hidden;
    transition: opacity var(--ds-dur) var(--ds-ease);
    padding: var(--ds-gap-4);
}
.ds-modal.is-show { opacity: 1; visibility: visible; }
.ds-modal__panel {
    width: 100%;
    max-width: 480px;
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-lg);
    transform: translateY(20px) scale(0.96);
    transition: transform var(--ds-dur) var(--ds-ease-out);
    overflow: hidden;
}
.ds-modal.is-show .ds-modal__panel { transform: translateY(0) scale(1); }
.ds-modal__head {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--ds-gap-4) var(--ds-gap-5);
    border-bottom: 1px solid var(--ds-border);
}
.ds-modal__title { font-size: var(--ds-fz-16); font-weight: 600; }
.ds-modal__close {
    width: 28px; height: 28px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--ds-text-2); border-radius: 6px;
    transition: all var(--ds-dur) var(--ds-ease);
}
.ds-modal__close:hover { color: var(--ds-text-0); background: var(--ds-surface-hover); }
.ds-modal__body { padding: var(--ds-gap-5); color: var(--ds-text-1); }
.ds-modal__foot {
    display: flex; justify-content: flex-end; gap: var(--ds-gap-3);
    padding: var(--ds-gap-3) var(--ds-gap-5);
    border-top: 1px solid var(--ds-border);
    background: rgba(0,0,0,0.15);
}

/* ==================== Toast ==================== */
.ds-toast-wrap {
    position: fixed; top: 80px; left: 50%; transform: translateX(-50%);
    z-index: 300;
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    pointer-events: none;
}
.ds-toast {
    display: inline-flex; align-items: center; gap: 8px;
    min-width: 180px; max-width: 90vw;
    padding: 10px 20px;
    background: var(--ds-surface-strong);
    border: 1px solid var(--ds-border-strong);
    border-left: 3px solid var(--ds-accent);
    border-radius: 12px;
    box-shadow: var(--ds-shadow-md);
    color: var(--ds-text-0);
    font-size: var(--ds-fz-13);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    opacity: 0; transform: translateY(-12px) scale(0.96);
    transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.ds-toast.is-show { opacity: 1; transform: translateY(0) scale(1); }
.ds-toast--success { border-left-color: var(--ds-success); }
.ds-toast--error   { border-left-color: var(--ds-danger); }
.ds-toast--warning { border-left-color: var(--ds-warning); }
.ds-toast--info    { border-left-color: var(--ds-accent); }
.ds-toast .ds-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ds-toast--success .ds-icon { color: var(--ds-success); }
.ds-toast--error   .ds-icon { color: var(--ds-danger); }
.ds-toast--warning .ds-icon { color: var(--ds-warning); }
.ds-toast--info    .ds-icon { color: var(--ds-accent); }

/* ==================== 站点详情页 ==================== */
.ds-site-detail__hero {
    position: relative;
    padding: var(--ds-gap-6) var(--ds-gap-5);
    background: linear-gradient(135deg, rgba(0,229,255,0.08), rgba(76,142,255,0.05));
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    margin-bottom: var(--ds-gap-5);
    overflow: hidden;
}
.ds-site-detail__hero::before {
    content: "";
    position: absolute; top: -50%; right: -10%;
    width: 400px; height: 400px;
    background: radial-gradient(circle, rgba(0,229,255,0.15), transparent 60%);
    pointer-events: none;
}
.ds-site-detail__head {
    display: flex; align-items: center; gap: var(--ds-gap-4);
    margin-bottom: var(--ds-gap-4);
    position: relative; z-index: 1;
}
.ds-site-detail__ico {
    flex: 0 0 auto;
    width: 72px; height: 72px;
    background: var(--ds-bg-3);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    overflow: hidden;
    box-shadow: var(--ds-shadow-md);
}
.ds-site-detail__ico img { width: 100%; height: 100%; object-fit: contain; }
.ds-site-detail__name { font-size: var(--ds-fz-24); font-weight: 700; margin-bottom: 4px; }
.ds-site-detail__sub { font-size: var(--ds-fz-13); color: var(--ds-text-2); }
.ds-site-detail__stats {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--ds-gap-3);
    margin: var(--ds-gap-4) 0;
    position: relative; z-index: 1;
}
.ds-site-detail__stat {
    padding: var(--ds-gap-3);
    background: rgba(10, 14, 26, 0.4);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    text-align: center;
}
.ds-site-detail__stat-k { display: block; font-size: var(--ds-fz-12); color: var(--ds-text-2); margin-bottom: 4px; }
.ds-site-detail__stat-v { display: block; font-size: var(--ds-fz-20); font-weight: 700; }
.ds-site-detail__actions {
    display: flex; flex-wrap: wrap; gap: var(--ds-gap-2);
    position: relative; z-index: 1;
}

.ds-info-table {
    width: 100%;
    border-collapse: collapse;
}
.ds-info-table th, .ds-info-table td {
    padding: 12px var(--ds-gap-4);
    text-align: left;
    font-size: var(--ds-fz-13);
    border-bottom: 1px dashed var(--ds-border);
}
.ds-info-table th { color: var(--ds-text-2); font-weight: 500; width: 100px; }
.ds-info-table td { color: var(--ds-text-1); }

/* ==================== 文章详情页 ==================== */
.ds-article {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    padding: var(--ds-gap-6);
    margin-bottom: var(--ds-gap-5);
    box-shadow: var(--ds-shadow-sm);
}
.ds-article__head { margin-bottom: var(--ds-gap-5); padding-bottom: var(--ds-gap-4); border-bottom: 1px solid var(--ds-border); }
.ds-article__title { font-size: var(--ds-fz-28); line-height: 1.4; margin-bottom: var(--ds-gap-3); }
.ds-article__meta { display: flex; flex-wrap: wrap; gap: var(--ds-gap-4); font-size: var(--ds-fz-12); color: var(--ds-text-2); }
.ds-article__meta span { display: inline-flex; align-items: center; gap: 4px; }
.ds-article__body {
    color: var(--ds-text-1);
    line-height: 1.8;
    font-size: var(--ds-fz-15);
}
.ds-article__body p { margin: var(--ds-gap-3) 0; }
.ds-article__body img { max-width: 100%; border-radius: var(--ds-radius); margin: var(--ds-gap-3) 0; }
.ds-article__body h1, .ds-article__body h2, .ds-article__body h3 { color: var(--ds-text-0); margin: var(--ds-gap-5) 0 var(--ds-gap-3); }
.ds-article__body pre, .ds-article__body code { background: var(--ds-bg-1); border-radius: 6px; padding: 2px 6px; font-family: var(--ds-font-mono); }
.ds-article__body pre { padding: var(--ds-gap-3); overflow-x: auto; }
.ds-article__body a { color: var(--ds-accent); }
.ds-article__body a:hover { text-decoration: underline; }

.ds-article__downloads {
    margin: var(--ds-gap-5) 0;
    padding: var(--ds-gap-4);
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
}
.ds-article__downloads h4 { font-size: var(--ds-fz-15); margin-bottom: var(--ds-gap-3); color: var(--ds-text-0); }
.ds-article__downloads ul { display: grid; gap: 8px; }
.ds-article__downloads li {
    display: flex; align-items: center; gap: var(--ds-gap-3);
    padding: 8px var(--ds-gap-3);
    background: var(--ds-bg-3);
    border-radius: 6px;
    font-size: var(--ds-fz-13);
    color: var(--ds-text-1);
}
.ds-article__downloads li::before {
    content: "";
    display: inline-block;
    width: 14px; height: 14px;
    flex: 0 0 14px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300e5ff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/><polyline points='7 10 12 15 17 10'/><line x1='12' y1='15' x2='12' y2='3'/></svg>");
    background-size: contain;
    background-repeat: no-repeat;
}

@media (max-width: 640px) {
    .ds-article { padding: var(--ds-gap-4); }
    .ds-article__title { font-size: var(--ds-fz-20); }
    .ds-site-detail__head { flex-direction: column; text-align: center; }
}

/* ==================== 文章列表卡片 ==================== */
.ds-post-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--ds-gap-4);
}
.ds-post-card {
    display: flex; flex-direction: column;
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    overflow: hidden;
    transition: all var(--ds-dur) var(--ds-ease);
}
.ds-post-card:hover {
    transform: translateY(-3px);
    border-color: var(--ds-accent);
    box-shadow: var(--ds-shadow-md);
}
.ds-post-card__cover {
    aspect-ratio: 16/9;
    background: linear-gradient(135deg, var(--ds-bg-3), var(--ds-bg-1));
    overflow: hidden;
}
.ds-post-card__cover img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--ds-dur-slow) var(--ds-ease); }
.ds-post-card:hover .ds-post-card__cover img { transform: scale(1.05); }
.ds-post-card__body { flex: 1 1 auto; padding: var(--ds-gap-4); display: flex; flex-direction: column; }
.ds-post-card__title {
    font-size: var(--ds-fz-15);
    font-weight: 600;
    color: var(--ds-text-0);
    margin-bottom: var(--ds-gap-2);
    overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.ds-post-card__excerpt {
    font-size: var(--ds-fz-12);
    color: var(--ds-text-2);
    line-height: 1.6;
    margin-bottom: var(--ds-gap-3);
    overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.ds-post-card__meta {
    margin-top: auto;
    display: flex; align-items: center; justify-content: space-between;
    font-size: var(--ds-fz-12); color: var(--ds-text-3);
}

/* ==================== 表单 ==================== */
.ds-form { display: flex; flex-direction: column; gap: var(--ds-gap-4); }
.ds-form-item { display: flex; flex-direction: column; gap: 6px; }
.ds-form-item__label { font-size: var(--ds-fz-13); color: var(--ds-text-1); }
.ds-form-item__label--req::after { content: " *"; color: var(--ds-danger); }
.ds-input, .ds-textarea, .ds-select {
    display: block; width: 100%;
    padding: 10px var(--ds-gap-3);
    font-size: var(--ds-fz-14);
    color: var(--ds-text-0);
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: 8px;
    transition: all var(--ds-dur) var(--ds-ease);
    outline: none;
}
.ds-input:focus, .ds-textarea:focus, .ds-select:focus {
    border-color: var(--ds-accent);
    box-shadow: 0 0 0 3px var(--ds-accent-soft);
}
.ds-textarea { min-height: 100px; resize: vertical; }
.ds-form-actions { display: flex; gap: var(--ds-gap-3); margin-top: var(--ds-gap-3); }

/* ==================== 单页 ==================== */
.ds-page {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    padding: var(--ds-gap-6);
    box-shadow: var(--ds-shadow-sm);
}
.ds-page h1, .ds-page h2, .ds-page h3 { color: var(--ds-text-0); margin: var(--ds-gap-5) 0 var(--ds-gap-3); }
.ds-page p { color: var(--ds-text-1); line-height: 1.8; margin: var(--ds-gap-3) 0; }
.ds-page a { color: var(--ds-accent); }
.ds-page ul, .ds-page ol { padding-left: var(--ds-gap-5); color: var(--ds-text-1); line-height: 1.9; }
.ds-page ul { list-style: disc; }
.ds-page ol { list-style: decimal; }

@media (max-width: 640px) {
    .ds-page { padding: var(--ds-gap-4); }
}

/* ==================== 跳转中转 ==================== */
.ds-goto {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 60vh;
    padding: var(--ds-gap-5);
    text-align: center;
}
.ds-goto__spinner {
    width: 56px; height: 56px;
    border: 3px solid var(--ds-border);
    border-top-color: var(--ds-accent);
    border-radius: 50%;
    margin-bottom: var(--ds-gap-4);
    animation: ds-spin 0.8s linear infinite;
}
@keyframes ds-spin { to { transform: rotate(360deg); } }
.ds-goto__title { font-size: var(--ds-fz-20); margin-bottom: var(--ds-gap-3); }
.ds-goto__desc { color: var(--ds-text-2); margin-bottom: var(--ds-gap-4); }
.ds-goto__url {
    padding: var(--ds-gap-3) var(--ds-gap-4);
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: 8px;
    color: var(--ds-accent);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-fz-13);
    word-break: break-all;
    max-width: 100%;
    margin-bottom: var(--ds-gap-4);
}

/* ==================== 404 ==================== */
.ds-404 {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 60vh;
    padding: var(--ds-gap-6) var(--ds-gap-4);
    text-align: center;
}
.ds-404__code {
    font-size: 120px; font-weight: 900; line-height: 1;
    background: var(--ds-accent-grad);
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
    margin-bottom: var(--ds-gap-3);
    letter-spacing: -4px;
}
.ds-404__title { font-size: var(--ds-fz-24); margin-bottom: var(--ds-gap-3); }
.ds-404__desc { color: var(--ds-text-2); margin-bottom: var(--ds-gap-5); max-width: 480px; }

/* ==================== 工具单页 ==================== */
.ds-tool-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--ds-gap-3);
}
.ds-tool-card {
    display: flex; flex-direction: column; align-items: center; gap: var(--ds-gap-2);
    padding: var(--ds-gap-5) var(--ds-gap-3);
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    text-align: center;
    color: var(--ds-text-1);
    transition: all var(--ds-dur) var(--ds-ease);
}
.ds-tool-card:hover {
    transform: translateY(-3px);
    border-color: var(--ds-accent);
    box-shadow: var(--ds-shadow-md), 0 0 0 1px var(--ds-accent-soft);
    color: var(--ds-text-0);
}
.ds-tool-card__ico {
    width: 48px; height: 48px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ds-accent-grad);
    border-radius: 12px;
    color: var(--ds-bg-0);
    font-size: 20px;
    margin-bottom: var(--ds-gap-2);
}
.ds-tool-card__name { font-size: var(--ds-fz-14); font-weight: 500; }
.ds-tool-card__desc { font-size: var(--ds-fz-12); color: var(--ds-text-2); }

/* ==================== 排行榜单页 ==================== */
.ds-rank-tabs {
    display: flex; flex-wrap: wrap; gap: var(--ds-gap-2);
    margin-bottom: var(--ds-gap-4);
    padding: 4px;
    background: var(--ds-bg-2);
    border: 1px solid var(--ds-border);
    border-radius: 999px;
    width: fit-content;
}
.ds-rank-tab {
    padding: 6px var(--ds-gap-4);
    font-size: var(--ds-fz-13);
    color: var(--ds-text-1);
    border-radius: 999px;
    transition: all var(--ds-dur) var(--ds-ease);
}
.ds-rank-tab:hover { color: var(--ds-accent); }
.ds-rank-tab.is-active {
    color: var(--ds-bg-0);
    background: var(--ds-accent-grad);
    font-weight: 600;
}

/* ==================== 动效 ==================== */
@keyframes ds-fade-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.ds-fade-in { animation: ds-fade-in var(--ds-dur) var(--ds-ease-out) backwards; }
.ds-fade-in-1 { animation-delay: 50ms; }
.ds-fade-in-2 { animation-delay: 100ms; }
.ds-fade-in-3 { animation-delay: 150ms; }
.ds-fade-in-4 { animation-delay: 200ms; }

@keyframes ds-shine {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}
.ds-shine {
    background: linear-gradient(90deg, transparent, rgba(0,229,255,0.15), transparent);
    background-size: 200% 100%;
    animation: ds-shine 2.4s linear infinite;
}
