This commit is contained in:
谢宇宁
2026-11-05 12:48:17 +07:00
parent 23df3ae435
commit 1bacead9c4
18 changed files with 360 additions and 150 deletions
@@ -4,15 +4,15 @@
<path d="M-662 -609C-662 -610.105 -661.105 -611 -660 -611H386C387.104 -611 388 -610.105 388 -609V1887C388 1888.1 387.105 1889 386 1889H-660C-661.105 1889 -662 1888.1 -662 1887V-609Z" fill="#444444"/>
<path d="M-660 -611V-610H386V-611V-612H-660V-611ZM388 -609H387V1887H388H389V-609H388ZM386 1889V1888H-660V1889V1890H386V1889ZM-662 1887H-661V-609H-662H-663V1887H-662ZM-660 1889V1888C-660.552 1888 -661 1887.55 -661 1887H-662H-663C-663 1888.66 -661.657 1890 -660 1890V1889ZM388 1887H387C387 1887.55 386.552 1888 386 1888V1889V1890C387.657 1890 389 1888.66 389 1887H388ZM386 -611V-610C386.552 -610 387 -609.552 387 -609H388H389C389 -610.657 387.657 -612 386 -612V-611ZM-660 -611V-612C-661.657 -612 -663 -610.657 -663 -609H-662H-661C-661 -609.552 -660.552 -610 -660 -610V-611Z" fill="white" fill-opacity="0.1"/>
<g id="01. &#229;&#174;&#137;&#232;&#163;&#133;&#229;&#188;&#149;&#229;&#175;&#188; &#194;&#183; Safari">
<rect width="375" height="881" transform="translate(-87 -511)" fill="#0B0B0D"/>
<rect width="375" height="881" transform="translate(-87 -511)" fill="#090B2B"/>
<g id="content">
<g id="step">
<g id="card">
<rect x="-71" y="-19" width="343" height="139" rx="12" fill="#141417"/>
<rect x="-71" y="-19" width="343" height="139" rx="12" fill="#121A4D"/>
<rect x="-70.5" y="-18.5" width="342" height="138" rx="11.5" stroke="white" stroke-opacity="0.0705882"/>
<g id="row">
<g id="HG/chevron-right">
<path id="Icon" d="M5 2L10 7L5 12" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Icon" d="M5 2L10 7L5 12" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -4,10 +4,10 @@
<path d="M-380 -421C-380 -422.105 -379.105 -423 -378 -423H668C669.104 -423 670 -422.105 670 -421V2075C670 2076.1 669.105 2077 668 2077H-378C-379.105 2077 -380 2076.1 -380 2075V-421Z" fill="#444444"/>
<path d="M-378 -423V-422H668V-423V-424H-378V-423ZM670 -421H669V2075H670H671V-421H670ZM668 2077V2076H-378V2077V2078H668V2077ZM-380 2075H-379V-421H-380H-381V2075H-380ZM-378 2077V2076C-378.552 2076 -379 2075.55 -379 2075H-380H-381C-381 2076.66 -379.657 2078 -378 2078V2077ZM670 2075H669C669 2075.55 668.552 2076 668 2076V2077V2078C669.657 2078 671 2076.66 671 2075H670ZM668 -423V-422C668.552 -422 669 -421.552 669 -421H670H671C671 -422.657 669.657 -424 668 -424V-423ZM-378 -423V-424C-379.657 -424 -381 -422.657 -381 -421H-380H-379C-379 -421.552 -378.552 -422 -378 -422V-423Z" fill="white" fill-opacity="0.1"/>
<g id="01. Safari &#230;&#143;&#144;&#231;&#164;&#186;">
<rect width="375" height="812" transform="translate(-280 -323)" fill="#0B0B0D"/>
<rect width="375" height="812" transform="translate(-280 -323)" fill="#090B2B"/>
<g id="content">
<g id="link">
<rect x="-264" y="-20" width="343" height="56" rx="12" fill="#141417"/>
<rect x="-264" y="-20" width="343" height="56" rx="12" fill="#121A4D"/>
<rect x="-263.5" y="-19.5" width="342" height="55" rx="11.5" stroke="white" stroke-opacity="0.0705882"/>
<g id="btn-brand">
<rect x="-20" y="-16" width="92" height="48" rx="24" fill="url(#paint0_linear_16_12828)"/>
@@ -22,9 +22,9 @@
</g>
<defs>
<linearGradient id="paint0_linear_16_12828" x1="-20" y1="-16" x2="8.12142" y2="37.8994" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF4A7B"/>
<stop offset="0.52" stop-color="#EC237F"/>
<stop offset="1" stop-color="#93226F"/>
<stop stop-color="#5AA0FF"/>
<stop offset="0.52" stop-color="#4D8DFF"/>
<stop offset="1" stop-color="#1A4FD0"/>
</linearGradient>
<clipPath id="clip0_16_12828">
<rect width="16" height="16" fill="white"/>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

+10 -10
View File
@@ -4,22 +4,22 @@
<path d="M-642 -610C-642 -611.105 -641.105 -612 -640 -612H406C407.104 -612 408 -611.105 408 -610V1886C408 1887.1 407.105 1888 406 1888H-640C-641.105 1888 -642 1887.1 -642 1886V-610Z" fill="#444444"/>
<path d="M-640 -612V-611H406V-612V-613H-640V-612ZM408 -610H407V1886H408H409V-610H408ZM406 1888V1887H-640V1888V1889H406V1888ZM-642 1886H-641V-610H-642H-643V1886H-642ZM-640 1888V1887C-640.552 1887 -641 1886.55 -641 1886H-642H-643C-643 1887.66 -641.657 1889 -640 1889V1888ZM408 1886H407C407 1886.55 406.552 1887 406 1887V1888V1889C407.657 1889 409 1887.66 409 1886H408ZM406 -612V-611C406.552 -611 407 -610.552 407 -610H408H409C409 -611.657 407.657 -613 406 -613V-612ZM-640 -612V-613C-641.657 -613 -643 -611.657 -643 -610H-642H-641C-641 -610.552 -640.552 -611 -640 -611V-612Z" fill="white" fill-opacity="0.1"/>
<g id="01. &#229;&#174;&#137;&#232;&#163;&#133;&#229;&#188;&#149;&#229;&#175;&#188; &#194;&#183; Safari">
<rect width="375" height="881" transform="translate(-67 -512)" fill="#0B0B0D"/>
<rect width="375" height="881" transform="translate(-67 -512)" fill="#090B2B"/>
<g id="content">
<g id="step">
<g id="card">
<rect x="-51" y="-20" width="343" height="139" rx="12" fill="#141417"/>
<rect x="-51" y="-20" width="343" height="139" rx="12" fill="#121A4D"/>
<rect x="-50.5" y="-19.5" width="342" height="138" rx="11.5" stroke="white" stroke-opacity="0.0705882"/>
<g id="row">
<g id="HG/film" clip-path="url(#clip0_16_12828)">
<path id="Vector" d="M9.91 1H2.09C1.48801 1 1 1.48801 1 2.09V9.91C1 10.512 1.48801 11 2.09 11H9.91C10.512 11 11 10.512 11 9.91V2.09C11 1.48801 10.512 1 9.91 1Z" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_2" d="M3.5 1V11" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_3" d="M8.5 1V11" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_4" d="M1 6H11" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_5" d="M1 3.5H3.5" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_6" d="M1 8.5H3.5" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_7" d="M8.5 8.5H11" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_8" d="M8.5 3.5H11" stroke="#6B6B74" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector" d="M9.91 1H2.09C1.48801 1 1 1.48801 1 2.09V9.91C1 10.512 1.48801 11 2.09 11H9.91C10.512 11 11 10.512 11 9.91V2.09C11 1.48801 10.512 1 9.91 1Z" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_2" d="M3.5 1V11" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_3" d="M8.5 1V11" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_4" d="M1 6H11" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_5" d="M1 3.5H3.5" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_6" d="M1 8.5H3.5" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_7" d="M8.5 8.5H11" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_8" d="M8.5 3.5H11" stroke="#7C86B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -4,7 +4,7 @@
<path d="M-677 -915C-677 -916.105 -676.105 -917 -675 -917H371C372.104 -917 373 -916.105 373 -915V1581C373 1582.1 372.105 1583 371 1583H-675C-676.105 1583 -677 1582.1 -677 1581V-915Z" fill="#444444"/>
<path d="M-675 -917V-916H371V-917V-918H-675V-917ZM373 -915H372V1581H373H374V-915H373ZM371 1583V1582H-675V1583V1584H371V1583ZM-677 1581H-676V-915H-677H-678V1581H-677ZM-675 1583V1582C-675.552 1582 -676 1581.55 -676 1581H-677H-678C-678 1582.66 -676.657 1584 -675 1584V1583ZM373 1581H372C372 1581.55 371.552 1582 371 1582V1583V1584C372.657 1584 374 1582.66 374 1581H373ZM371 -917V-916C371.552 -916 372 -915.552 372 -915H373H374C374 -916.657 372.657 -918 371 -918V-917ZM-675 -917V-918C-676.657 -918 -678 -916.657 -678 -915H-677H-676C-676 -915.552 -675.552 -916 -675 -916V-917Z" fill="white" fill-opacity="0.1"/>
<g id="01. &#229;&#174;&#137;&#232;&#163;&#133;&#229;&#188;&#149;&#229;&#175;&#188; &#194;&#183; Safari">
<rect width="375" height="881" transform="translate(-102 -817)" fill="#0B0B0D"/>
<rect width="375" height="881" transform="translate(-102 -817)" fill="#090B2B"/>
<g id="content">
<g id="btn-brand">
<rect x="-86" y="-16" width="343" height="48" rx="24" fill="url(#paint0_linear_16_12828)"/>
@@ -17,9 +17,9 @@
</g>
<defs>
<linearGradient id="paint0_linear_16_12828" x1="-86" y1="-16" x2="-76.5883" y2="51.2543" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF4A7B"/>
<stop offset="0.52" stop-color="#EC237F"/>
<stop offset="1" stop-color="#93226F"/>
<stop stop-color="#5AA0FF"/>
<stop offset="0.52" stop-color="#4D8DFF"/>
<stop offset="1" stop-color="#1A4FD0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

+196
View File
@@ -0,0 +1,196 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import QrcodeVue from 'qrcode.vue'
import { APP_NAME } from '~/config/app'
import dramas from '~/data/b-land/dramas.json'
import { useAppDownload } from '~/utils/useAppDownload'
import IosInstallGuide from '~/components/mobile/IosInstallGuide.vue'
import IosSafariOpenGuide from '~/components/mobile/IosSafariOpenGuide.vue'
import AndroidInstallTip from '~/components/mobile/AndroidInstallTip.vue'
const { init, download, isIos, hasIosStore, isSocialInApp, guide } = useAppDownload()
const mobile = /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)
const tabs = ['精选', '短剧', '都市', '悬疑', '古装', '奇幻']
const activeTab = ref('精选')
const items = computed(() => activeTab.value === '精选'
? dramas
: dramas.filter(item => item.kind === activeTab.value || item.tags.includes(activeTab.value)))
const qrUrl = window.location.href
const showQr = ref(false)
const busy = ref(false)
const message = ref('')
const asset = (path: string) => `/b-land/assets/${path}`
async function startDownload(index = 0) {
if (!mobile) {
showQr.value = true
return
}
if (busy.value) return
busy.value = true
message.value = ''
try {
if (!await download(index)) message.value = '暂时无法获取下载链接,请稍后重试'
} finally {
busy.value = false
}
}
const previousOverflow = document.documentElement.style.overflow
function closeOnEscape(event: KeyboardEvent) {
if (event.key === 'Escape') showQr.value = false
}
onMounted(() => {
document.documentElement.style.overflow = 'auto'
window.addEventListener('keydown', closeOnEscape)
init()
})
onBeforeUnmount(() => {
document.documentElement.style.overflow = previousOverflow
window.removeEventListener('keydown', closeOnEscape)
})
</script>
<template>
<main class="reference-page">
<div class="landing-frame">
<header class="masthead">
<a class="brand" href="#" aria-label="返回首页" @click.prevent="activeTab = '精选'">
<img :src="asset('logo-icon-brick.png')" :alt="APP_NAME" width="44" height="44" />
<span><strong>{{ APP_NAME }}</strong><small>精彩短剧 · 每日更新</small></span>
</a>
<button class="header-action" type="button" @click="startDownload()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><path d="M12 3v12m-5-5 5 5 5-5M4 16v5h16v-5" /></svg>
<span>下载</span>
</button>
</header>
<section class="hero" aria-label="精彩短剧推荐">
<div class="hero-posters" aria-hidden="true">
<img :src="asset('hero/04-prism-cover.jpg')" alt="" />
<img :src="asset('hero/02-yujing-cover.jpg')" alt="" />
<img :src="asset('hero/05-feichai-cover.jpg')" alt="" />
</div>
<div class="hero-copy">
<span class="hero-label">{{ APP_NAME }} · 精彩随时看</span>
<h1>好故事<br />一看就入戏</h1>
<p>海量高清短剧,发现你的下一部心动</p>
<button type="button" class="hero-cta" @click="startDownload()">立即体验 <span aria-hidden="true">↗</span></button>
</div>
</section>
<section class="library" aria-label="短剧列表">
<nav class="category-tabs" aria-label="短剧分类">
<button v-for="tab in tabs" :key="tab" type="button" :class="{ active: activeTab === tab }" :aria-pressed="activeTab === tab" @click="activeTab = tab">{{ tab }}</button>
</nav>
<div class="library-heading"><h2>{{ activeTab === '精选' ? '热门推荐' : activeTab + '推荐' }}</h2><span>{{ items.length }} 部好剧</span></div>
<div class="poster-grid">
<button v-for="(item, index) in items" :key="item.id" class="drama-card" type="button" :aria-label="'在 App 中观看' + item.title" @click="startDownload()">
<div class="cover">
<img :src="asset(item.cover)" :alt="item.title" :loading="index < 4 ? 'eager' : 'lazy'" width="300" height="450" />
<span class="cover-tag">{{ item.tags[0] }}</span>
<span class="episode">{{ item.episodes ? item.episodes + '集' : '持续更新' }} <span aria-hidden="true">▶</span></span>
</div>
<h3>{{ item.title }}</h3>
<p>{{ item.tags.join(' · ') }}</p>
</button>
</div>
<p v-if="!items.length" class="empty">更多精彩内容即将上线</p>
<p class="list-end">更多精彩,尽在 {{ APP_NAME }} App</p>
</section>
<aside class="download-dock" aria-label="下载 App">
<div class="dock-copy"><span class="dock-label">随时随地 · 想看就看</span><strong>好剧不等待,精彩随身带</strong></div>
<div class="download-actions">
<button class="download-primary" type="button" :disabled="busy" @click="startDownload()"><span aria-hidden="true">↓</span> {{ busy ? '正在获取…' : isIos ? 'iOS 轻量版下载' : mobile ? 'Android 下载' : '立即下载 App' }}</button>
<button v-if="isIos && hasIosStore" class="download-store" type="button" :disabled="busy" @click="startDownload(1)">App Store</button>
</div>
<p v-if="message" class="download-error" role="status">{{ message }}</p>
<div v-if="!mobile" class="desktop-qr"><div class="qr"><QrcodeVue :value="qrUrl" :size="80" level="M" /></div><div><strong>手机扫码下载</strong><p>iOS / Android 均可使用</p><small>精彩内容,打开 App 即可观看</small></div></div>
</aside>
</div>
<div v-if="showQr" class="qr-overlay" @click.self="showQr = false" @keydown.esc="showQr = false">
<section class="qr-dialog" role="dialog" aria-modal="true" aria-label="扫码下载">
<button class="close-modal" type="button" aria-label="关闭" autofocus @click="showQr = false">×</button>
<h2>手机扫码下载 {{ APP_NAME }}</h2>
<p>使用手机浏览器打开,选择对应版本安装</p>
<div class="modal-qr"><QrcodeVue :value="qrUrl" :size="200" level="M" /></div>
<span>iOS / Android</span>
</section>
</div>
<IosSafariOpenGuide v-if="isSocialInApp && guide === 'ios'" :show="true" :url="qrUrl" @close="guide = null" />
<IosInstallGuide v-else :show="guide === 'ios'" @close="guide = null" />
<AndroidInstallTip :show="guide === 'android'" @close="guide = null" />
</main>
</template>
<style scoped>
.reference-page { --blue: #296ff5; min-height: 100dvh; background: #1e1e1e; color: #fff; font: 14px/1.5 -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif; }
.reference-page button, .reference-page a { -webkit-tap-highlight-color: transparent; }
.reference-page button { font: inherit; cursor: pointer; }
.reference-page button:focus-visible, .reference-page a:focus-visible { outline: 2px solid #92caff; outline-offset: 4px; }
.landing-frame { width: 100%; max-width: 430px; margin: auto; min-height: 100dvh; padding-bottom: 240px; background: linear-gradient(180deg, #090731 5%, #101d63 100%); }
.masthead { position: sticky; top: 0; z-index: 10; height: 72px; padding: 12px 17px; display: flex; align-items: center; justify-content: space-between; background: #090731; border-bottom: 1px solid #ffffff0b; }
.brand { display: flex; align-items: center; gap: 9px; color: inherit; text-decoration: none; }
.brand img { border-radius: 10px; object-fit: cover; }
.brand strong { display: block; font-size: 22px; line-height: 1.2; letter-spacing: 1px; }
.brand small { display: block; margin-top: 3px; font-size: 11px; color: #c1c5ed; letter-spacing: 1px; }
.header-action { border: 0; background: transparent; color: #dce9ff; display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 10px !important; padding: 0 6px; }
.header-action svg { width: 22px; height: 22px; }
.hero { position: relative; height: 200px; overflow: hidden; background: #151454; isolation: isolate; }
.hero::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(90deg, #111343 5%, #111343e6 35%, #11134300 85%), linear-gradient(0deg, #090731, transparent 60%); }
.hero-posters { position: absolute; z-index: -2; inset: -40px -55px -35px 125px; display: flex; gap: 9px; transform: rotate(13deg); opacity: .85; }
.hero-posters img { width: 110px; height: 255px; object-fit: cover; border: 1px solid #8da3f533; border-radius: 10px; }
.hero-posters img:nth-child(2) { margin-top: 35px; }
.hero-copy { padding: 18px 20px; }
.hero-label { color: #9eafff; font-size: 10px; letter-spacing: 2px; }
.hero h1 { font-size: 31px; line-height: 1.2; letter-spacing: 2px; margin: 8px 0; font-weight: 900; }
.hero p { font-size: 10px; color: #c5cbea; }
.hero-cta { margin-top: 12px; border: 1px solid #7aa4ff66; border-radius: 20px; background: #296ff5; color: #fff; padding: 6px 15px; font-size: 11px !important; }
.hero-cta span { margin-left: 15px; }
.library { margin: 12px 16px 0; padding: 9px; border: 1px solid #2347c6; border-radius: 22px; background: #08052b; }
.category-tabs { display: flex; gap: 3px; padding: 4px; border: 1px solid #4384ff; border-radius: 30px; background: var(--blue); }
.category-tabs button { flex: 1; min-width: 0; border: 0; border-radius: 20px; height: 30px; padding: 0 2px; color: #fff; background: transparent; font-size: 12px; white-space: nowrap; }
.category-tabs button.active { color: var(--blue); background: #fff; font-weight: 700; }
.library-heading { display: flex; justify-content: space-between; align-items: center; padding: 15px 3px 10px; }
.library-heading h2 { font-size: 14px; }
.library-heading > span { color: #8588b2; font-size: 10px; }
.poster-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 10px; }
.drama-card { display: block; min-width: 0; border: 0; padding: 0; background: transparent; text-align: left; color: #fff; }
.cover { position: relative; aspect-ratio: 159 / 248; overflow: hidden; border-radius: 7px; background: #191a40; }
.cover::after { content: ''; position: absolute; inset: 65% 0 0; background: linear-gradient(transparent, #000b); }
.cover img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .2s; }
.drama-card:hover .cover img { transform: scale(1.035); }
.cover-tag { position: absolute; top: 6px; left: 6px; padding: 1px 6px; border-radius: 4px; background: #171437a6; color: #fff; font-size: 9px; backdrop-filter: blur(8px); }
.episode { position: absolute; z-index: 1; bottom: 7px; left: 8px; right: 8px; display: flex; justify-content: space-between; align-items: center; font-size: 10px; }
.episode > span { border-radius: 50%; width: 21px; height: 21px; text-align: center; line-height: 21px; background: #ffffff26; font-size: 9px; }
.drama-card h3 { margin-top: 6px; font-size: 12px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drama-card p { color: #777b9f; font-size: 10px; margin-top: 2px; }
.empty, .list-end { padding: 24px 0 14px; text-align: center; font-size: 10px; color: #777b9f; }
.download-dock { position: fixed; z-index: 15; bottom: 0; left: 50%; transform: translateX(-50%); width: min(100%, 430px); padding: 15px 20px max(15px, env(safe-area-inset-bottom)); border: 1px solid #477dff5c; border-bottom: 0; border-radius: 22px 22px 0 0; background: radial-gradient(ellipse at 90% 10%, #414fbe 0%, transparent 55%), linear-gradient(120deg, #172f8c, #101954); box-shadow: 0 -10px 40px #03032066; }
.dock-copy { display: flex; flex-direction: column; gap: 2px; }
.dock-label { font-size: 9px; color: #a8c4ff; letter-spacing: 2px; }
.dock-copy strong { font-size: 18px; font-weight: 800; letter-spacing: .5px; }
.download-actions { display: flex; gap: 8px; margin-top: 11px; }
.download-primary { flex: 1; min-height: 42px; border: 1px solid #bad5ff; border-radius: 24px; background: linear-gradient(180deg, #fff, #c8dcff); color: #174cb4; font-size: 14px !important; font-weight: 800 !important; box-shadow: 0 4px 0 #112567; }
.download-primary > span { margin-right: 8px; font-size: 20px; line-height: 1; }
.download-store { border: 1px solid #7399f5; border-radius: 24px; padding: 0 12px; background: #ffffff12; color: #fff; font-size: 11px !important; }
.download-actions button:disabled { opacity: .65; cursor: wait; }
.download-error { margin-top: 8px; color: #ffdfac; font-size: 11px; }
.desktop-qr { display: flex; gap: 15px; align-items: center; padding-top: 16px; margin-top: 15px; border-top: 1px solid #ffffff20; }
.qr { background: #fff; padding: 5px; border-radius: 6px; line-height: 0; }
.desktop-qr strong { font-size: 15px; }
.desktop-qr p { margin-top: 4px; font-size: 11px; color: #c7d5ff; }
.desktop-qr small { font-size: 9px; color: #91a5dd; }
.qr-overlay { position: fixed; z-index: 100; inset: 0; background: #000a; display: grid; place-items: center; padding: 20px; backdrop-filter: blur(8px); }
.qr-dialog { position: relative; width: min(100%, 360px); padding: 35px 20px 25px; border: 1px solid #4c69c5; border-radius: 20px; background: #101641; text-align: center; }
.qr-dialog h2 { font-size: 20px; }
.qr-dialog p { margin-top: 10px; font-size: 12px; color: #a9b7dc; }
.modal-qr { padding: 15px; margin: 24px auto 15px; width: fit-content; border-radius: 12px; background: #fff; line-height: 0; }
.qr-dialog > span { font-size: 12px; color: #a9b7dc; }
.close-modal { position: absolute; right: 12px; top: 6px; border: 0; background: transparent; color: #a9b7dc; font-size: 26px !important; }
@media (max-width: 767px) { .landing-frame { max-width: 100%; padding-bottom: 165px; } .download-dock { width: 100%; } .hero { height: 46vw; min-height: 190px; max-height: 280px; } .hero-posters { left: 36%; right: -35px; } .hero-posters img { width: 33%; height: 125%; } .library { margin-top: 10px; } }
@media (min-width: 768px) { .landing-frame, .download-dock { max-width: 375px; } .landing-frame { padding-bottom: 270px; } .library { margin-left: 12px; margin-right: 12px; } }
@media (prefers-reduced-motion: reduce) { .cover img { transition: none; } }
</style>
+31 -31
View File
@@ -110,8 +110,8 @@ const {
<header class="nav" :class="{ scrolled: isScrolled }">
<div class="wrap">
<a class="logo" href="#" @click.prevent="switchView('landing')">
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<img class="wm" :src="assetUrl('wordmark-white-1line.png')" alt="51短剧" />
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<img class="wm" :src="assetUrl('wordmark-white-1line.png')" alt="海角社区" />
</a>
<div class="right">
<button class="btn glass xs" @click="handleDownload()">
@@ -164,7 +164,7 @@ const {
{{ (currentHero?.tags || []).join(' ') }}&nbsp;&nbsp;{{ currentHero?.eps ? `全 ${currentHero.eps} 集 更新至第 ${currentHero.eps} 集` : '连载中' }}&nbsp;&nbsp;2026
</div>
<p class="syn">
{{ currentHero?.syn || '精彩短剧,51短剧独家呈现。高清画质与震撼剧情,畅享视听盛宴。' }}
{{ currentHero?.syn || '精彩短剧,海角社区独家呈现。高清画质与震撼剧情,畅享视听盛宴。' }}
</p>
<div class="dlhero">
<div class="dlbtns">
@@ -215,7 +215,7 @@ const {
下载 Android 版
</button>
<a class="link brand open-app" href="#" @click.prevent="handleOpenAppDeepLink">
已安装?打开51短剧 App
已安装?打开海角社区 App
<svg class="ic"><use href="#i-arrow-right" /></svg>
</a>
</template>
@@ -354,18 +354,18 @@ const {
<div class="col">
<span class="kicker">关于我们</span>
<h2 class="h2">不是所有短剧,<br />都能被称作作品。</h2>
<p class="sub">51短剧,因为专业,所以领先。</p>
<p class="sub">海角社区,因为专业,所以领先。</p>
<p>
别人拼命追赶风口,我们定义创造标准。每一支作品都经过精心制作,分镜反复推敲,为一句台词的语气重新生成十次,字幕与剪辑的表情调整到满意为止。这就是我们的匠人精神,也是51短剧品质唯一的定义。
别人拼命追赶风口,我们定义创造标准。每一支作品都经过精心制作,分镜反复推敲,为一句台词的语气重新生成十次,字幕与剪辑的表情调整到满意为止。这就是我们的匠人精神,也是海角社区品质唯一的定义。
</p>
<p>
我们用 AI 帮助提升作品的品质,把不可能的画面化为可能。题材多元,都会、悬疑、古装、奇幻同步推进;每日更新,精彩不断。短剧与影集双轨并行,仿真与动画齐发。我们只做一件事:把每一支作品,做到值得被记得。
</p>
<p class="slogan">51短剧一开,全射出来,每一帧都能解你的色。</p>
<p class="slogan">海角社区一开,全射出来,每一帧都能解你的色。</p>
</div>
<div>
<div class="vis">
<img :src="assetUrl('about-visual.png')" alt="51短剧 作品视觉" />
<img :src="assetUrl('about-visual.png')" alt="海角社区 作品视觉" />
</div>
<div class="tags">
<span class="chip">短剧与影集双轨并行</span>
@@ -377,12 +377,12 @@ const {
</div>
</section>
<!-- ④ 51短剧特色 -->
<!-- ④ 海角社区特色 -->
<section class="sec" style="padding-top: 0">
<div class="wrap">
<div class="secHead" data-reveal>
<div class="left">
<span class="kicker">51短剧特色</span>
<span class="kicker">海角社区特色</span>
<h2 class="h2">把最好看的留给你</h2>
</div>
</div>
@@ -416,7 +416,7 @@ const {
<div class="wscrim"></div>
<div class="wrap in">
<div data-reveal>
<h2>现在下载,海量短剧尽在51短剧</h2>
<h2>现在下载,海量短剧尽在海角社区</h2>
<p class="sub">
支援 iOS / Android&nbsp;&nbsp;双版本 APP,即刻下载,追剧不断档
</p>
@@ -468,7 +468,7 @@ const {
<div class="wrap faq">
<div class="left" data-reveal>
<span class="kicker">常见问题</span>
<h2 class="h2">关于51短剧,<br />你想知道的</h2>
<h2 class="h2">关于海角社区,<br />你想知道的</h2>
</div>
<div class="acc" data-reveal>
<div
@@ -560,12 +560,12 @@ const {
<footer>
<div class="wrap in">
<div class="lockup">
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<img class="wm" :src="assetUrl('wordmark-white-2line.png')" alt="51短剧" />
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<img class="wm" :src="assetUrl('wordmark-white-2line.png')" alt="海角社区" />
</div>
<div class="fl">
<a href="#works" @click.prevent="switchView('landing', '#works')">作品精选</a>
<a href="#about" @click.prevent="switchView('landing', '#about')">关于51短剧</a>
<a href="#about" @click.prevent="switchView('landing', '#about')">关于海角社区</a>
<a href="#faq" @click.prevent="switchView('landing', '#faq')">常见问题</a>
<a href="#" @click.prevent="handleDownload()">下载 APP</a>
</div>
@@ -574,7 +574,7 @@ const {
<p>本网站所呈现之所有人员,于拍摄当时均已年满 18 岁,符合 18 U.S.C. 第 2257 章规定。</p>
</div>
<div class="bot">
<span>© 2026 51短剧 51DJ&nbsp;&nbsp;All rights reserved.</span>
<span>© 2026 海角社区 HJSQ&nbsp;&nbsp;All rights reserved.</span>
<span>官方地址&nbsp;&nbsp;{{ APP_DOMAIN }}</span>
<span>仅限 18 岁以上成年人</span>
</div>
@@ -582,9 +582,9 @@ const {
</footer>
<!-- ============ H5 底部常驻下载条 ============ -->
<div class="mdl" :class="{ show: showMobileStickyBar }">
<img :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<img :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<div class="c">
<b>51短剧 App</b>
<b>海角社区 App</b>
<span>免费下载&nbsp;&nbsp;海量短剧每日更新</span>
</div>
<button class="btn primary" @click="handleDownload()">
@@ -599,10 +599,10 @@ const {
<div class="bd"></div>
<div class="dlg">
<div class="grab" aria-hidden="true"></div>
<img class="age-ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" width="72" height="72" />
<img class="age-ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" width="72" height="72" />
<h3 id="agegate-title">本站含成人内容</h3>
<p>
51短剧仅限 18 岁以上成年人访问。进入即表示您已年满 18 岁、所在地区法律允许浏览成人内容,并同意<a class="privacy" href="#" @click.prevent>《隐私政策》</a>。
海角社区仅限 18 岁以上成年人访问。进入即表示您已年满 18 岁、所在地区法律允许浏览成人内容,并同意<a class="privacy" href="#" @click.prevent>《隐私政策》</a>。
</p>
<button class="btn primary md block enter" type="button" @click="confirmAge">
我已年满 18 岁,进入
@@ -618,13 +618,13 @@ const {
:class="{ open: showInstallGuideModal, in: showInstallGuideModal }"
role="dialog"
aria-modal="true"
aria-label="下载51短剧 App"
aria-label="下载海角社区 App"
>
<div class="dlg">
<header class="install-nav">
<button class="back" type="button" aria-label="返回" @click="showInstallGuideModal = false">
<svg class="ic"><use href="#i-chevron-left" /></svg>
<span>下载51短剧 App</span>
<span>下载海角社区 App</span>
</button>
</header>
@@ -632,7 +632,7 @@ const {
<template v-if="installGuideTab === 'ios'">
<div class="install-scroll">
<div class="hd">
<img :src="assetUrl('logo-icon-activity.png')" alt="51短剧" width="72" height="72" />
<img :src="assetUrl('logo-icon-activity.png')" alt="海角社区" width="72" height="72" />
<h3>安装 iOS 版</h3>
<p>
{{
@@ -672,7 +672,7 @@ const {
<svg class="ic"><use href="#i-si-apple" /></svg>
</div>
<div class="store-title">
<b>51短剧&nbsp;&nbsp;App Store 版</b>
<b>海角社区&nbsp;&nbsp;App Store 版</b>
<span class="tag-rec">推荐</span>
</div>
<p>
@@ -713,7 +713,7 @@ const {
<span class="n">STEP.3</span>
<div class="c">
<b>返回桌面打开</b>
<span>桌面出现「51短剧」图标,点击即可观看。建议同时保存账号凭证。</span>
<span>桌面出现「海角社区」图标,点击即可观看。建议同时保存账号凭证。</span>
</div>
</div>
<div class="tip">
@@ -740,7 +740,7 @@ const {
</template>
</button>
<a class="link brand open-app" href="#" @click.prevent="handleOpenAppDeepLink">
已安装?打开51短剧 App
已安装?打开海角社区 App
<svg class="ic"><use href="#i-arrow-right" /></svg>
</a>
</div>
@@ -750,7 +750,7 @@ const {
<template v-else>
<div class="install-scroll">
<div class="hd">
<img :src="assetUrl('logo-icon-activity.png')" alt="51短剧" width="72" height="72" />
<img :src="assetUrl('logo-icon-activity.png')" alt="海角社区" width="72" height="72" />
<h3>安装 Android 版</h3>
<p>已识别为 Android 设备,下载 APK 直接安装。</p>
</div>
@@ -773,8 +773,8 @@ const {
<div class="step">
<span class="n">STEP.3</span>
<div class="c">
<b>打开51短剧</b>
<span>安装完成后点击「打开」,或在桌面找到「51短剧」图标即可观看。</span>
<b>打开海角社区</b>
<span>安装完成后点击「打开」,或在桌面找到「海角社区」图标即可观看。</span>
</div>
</div>
<div class="tip">
@@ -794,7 +794,7 @@ const {
下载 Android 版
</button>
<a class="link brand open-app" href="#" @click.prevent="handleOpenAppDeepLink">
已安装?打开51短剧 App
已安装?打开海角社区 App
<svg class="ic"><use href="#i-arrow-right" /></svg>
</a>
</div>
@@ -1907,7 +1907,7 @@ section.sec {
margin-top: 20px;
}
/* ============ 51短剧特色 ============ */
/* ============ 海角社区特色 ============ */
.feat {
margin-top: 40px;
display: flex;
+29 -29
View File
@@ -113,8 +113,8 @@ const {
<header class="nav" :class="{ scrolled: isScrolled }">
<div class="wrap">
<a class="logo" href="#" @click.prevent="switchView('landing')">
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<img class="wm" :src="assetUrl('wordmark-white-1line.png')" alt="51短剧" />
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<img class="wm" :src="assetUrl('wordmark-white-1line.png')" alt="海角社区" />
</a>
<nav class="links">
<a
@@ -129,7 +129,7 @@ const {
:class="{ on: activeAnchor === '#about' && currentView === 'landing' }"
@click.prevent="switchView('landing', '#about')"
>
关于51短剧
关于海角社区
</a>
<a
href="#faq"
@@ -192,7 +192,7 @@ const {
{{ (currentHero?.tags || []).join(' ') }}&nbsp;&nbsp;{{ currentHero?.eps ? `全 ${currentHero.eps} 集 更新至第 ${currentHero.eps} 集` : '连载中' }}&nbsp;&nbsp;2026
</div>
<p class="syn">
{{ currentHero?.syn || '精彩短剧,51短剧独家呈现。高清画质与震撼剧情,畅享视听盛宴。' }}
{{ currentHero?.syn || '精彩短剧,海角社区独家呈现。高清画质与震撼剧情,畅享视听盛宴。' }}
</p>
<div class="dlhero">
<div class="qrbox">
@@ -390,18 +390,18 @@ const {
<div class="col">
<span class="kicker">关于我们</span>
<h2 class="h2">不是所有短剧,<br />都能被称作作品。</h2>
<p class="sub">51短剧,因为专业,所以领先。</p>
<p class="sub">海角社区,因为专业,所以领先。</p>
<p>
别人拼命追赶风口,我们定义创造标准。每一支作品都经过精心制作,分镜反复推敲,为一句台词的语气重新生成十次,字幕与剪辑的表情调整到满意为止。这就是我们的匠人精神,也是51短剧品质唯一的定义。
别人拼命追赶风口,我们定义创造标准。每一支作品都经过精心制作,分镜反复推敲,为一句台词的语气重新生成十次,字幕与剪辑的表情调整到满意为止。这就是我们的匠人精神,也是海角社区品质唯一的定义。
</p>
<p>
我们用 AI 帮助提升作品的品质,把不可能的画面化为可能。题材多元,都会、悬疑、古装、奇幻同步推进;每日更新,精彩不断。短剧与影集双轨并行,仿真与动画齐发。我们只做一件事:把每一支作品,做到值得被记得。
</p>
<p class="slogan">51短剧一开,全射出来,每一帧都能解你的色。</p>
<p class="slogan">海角社区一开,全射出来,每一帧都能解你的色。</p>
</div>
<div>
<div class="vis">
<img :src="assetUrl('about-visual.png')" alt="51短剧 作品视觉" />
<img :src="assetUrl('about-visual.png')" alt="海角社区 作品视觉" />
</div>
<div class="tags">
<span class="chip">短剧与影集双轨并行</span>
@@ -413,12 +413,12 @@ const {
</div>
</section>
<!-- ④ 51短剧特色 -->
<!-- ④ 海角社区特色 -->
<section class="sec" style="padding-top: 0">
<div class="wrap">
<div class="secHead" data-reveal>
<div class="left">
<span class="kicker">51短剧特色</span>
<span class="kicker">海角社区特色</span>
<h2 class="h2">把最好看的留给你</h2>
</div>
</div>
@@ -452,7 +452,7 @@ const {
<div class="wscrim"></div>
<div class="wrap in">
<div data-reveal>
<h2>现在下载,海量短剧尽在51短剧</h2>
<h2>现在下载,海量短剧尽在海角社区</h2>
<p class="sub">
支援 iOS / Android&nbsp;&nbsp;双版本 APP,即刻下载,追剧不断档
</p>
@@ -472,7 +472,7 @@ const {
<span class="qr-lab">扫码下载 App</span>
</div>
<div class="col">
<h4>扫码安装 51短剧 App</h4>
<h4>扫码安装 海角社区 App</h4>
<div class="btns">
<template v-if="hasIosShopPackage">
<button
@@ -533,7 +533,7 @@ const {
<div class="wrap faq">
<div class="left" data-reveal>
<span class="kicker">常见问题</span>
<h2 class="h2">关于51短剧,<br />你想知道的</h2>
<h2 class="h2">关于海角社区,<br />你想知道的</h2>
</div>
<div class="acc" data-reveal>
<div
@@ -625,12 +625,12 @@ const {
<footer>
<div class="wrap in">
<div class="lockup">
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<img class="wm" :src="assetUrl('wordmark-white-2line.png')" alt="51短剧" />
<img class="ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<img class="wm" :src="assetUrl('wordmark-white-2line.png')" alt="海角社区" />
</div>
<div class="fl">
<a href="#works" @click.prevent="switchView('landing', '#works')">作品精选</a>
<a href="#about" @click.prevent="switchView('landing', '#about')">关于51短剧</a>
<a href="#about" @click.prevent="switchView('landing', '#about')">关于海角社区</a>
<a href="#faq" @click.prevent="switchView('landing', '#faq')">常见问题</a>
<a href="#" @click.prevent="handleDownload()">下载 APP</a>
</div>
@@ -639,7 +639,7 @@ const {
<p>本网站所呈现之所有人员,于拍摄当时均已年满 18 岁,符合 18 U.S.C. 第 2257 章规定。</p>
</div>
<div class="bot">
<span>© 2026 51短剧 51DJ&nbsp;&nbsp;All rights reserved.</span>
<span>© 2026 海角社区 HJSQ&nbsp;&nbsp;All rights reserved.</span>
<span>官方地址&nbsp;&nbsp;{{ APP_DOMAIN }}</span>
<span>仅限 18 岁以上成年人</span>
</div>
@@ -659,7 +659,7 @@ const {
/>
</span>
<div class="c">
<b>扫码下载51短剧 App</b>
<b>扫码下载海角社区 App</b>
<span>支援 iOS / Android</span>
<button class="btn primary" @click="handleDownload()">
<svg class="ic"><use href="#i-download" /></svg>
@@ -678,10 +678,10 @@ const {
<div class="modal agegate" :class="{ open: showAgeGate, in: showAgeGate }" role="dialog" aria-modal="true" aria-labelledby="agegate-title-pc">
<div class="bd"></div>
<div class="dlg">
<img class="age-ico" :src="assetUrl('logo-icon-activity.png')" alt="51短剧" width="72" height="72" />
<img class="age-ico" :src="assetUrl('logo-icon-activity.png')" alt="海角社区" width="72" height="72" />
<h3 id="agegate-title-pc">本站含成人内容</h3>
<p>
51短剧仅限 18 岁以上成年人访问。进入即表示您已年满 18 岁、所在地区法律允许浏览成人内容,并同意<a class="privacy" href="#" @click.prevent>《隐私政策》</a>。
海角社区仅限 18 岁以上成年人访问。进入即表示您已年满 18 岁、所在地区法律允许浏览成人内容,并同意<a class="privacy" href="#" @click.prevent>《隐私政策》</a>。
</p>
<button class="btn primary lg block enter" type="button" @click="confirmAge">
我已年满 18 岁,进入
@@ -699,7 +699,7 @@ const {
<svg class="ic"><use href="#i-x" /></svg>
</button>
<div class="hd">
<h3>下载51短剧 App</h3>
<h3>下载海角社区 App</h3>
<p>
<template v-if="targetDramaForDownload">
下载后即可观看<b>《{{ targetDramaForDownload.t }}》</b>全 {{ targetDramaForDownload.eps || '' }} 集及更多原创作品&nbsp;&nbsp;支援 iOS / Android
@@ -763,7 +763,7 @@ const {
<div class="bot">
<span>
已安装?
<a class="link brand" href="#" @click.prevent="handleOpenAppDeepLink">打开51短剧 App</a>
<a class="link brand" href="#" @click.prevent="handleOpenAppDeepLink">打开海角社区 App</a>
</span>
<a
class="link guide"
@@ -785,8 +785,8 @@ const {
<svg class="ic"><use href="#i-x" /></svg>
</button>
<div class="hd">
<img :src="assetUrl('logo-icon-activity.png')" alt="51短剧" />
<h3>安装51短剧 App</h3>
<img :src="assetUrl('logo-icon-activity.png')" alt="海角社区" />
<h3>安装海角社区 App</h3>
<p>三步完成,约 1 分钟。安装后可在桌面直接打开。</p>
</div>
<div class="seg">
@@ -812,7 +812,7 @@ const {
<span class="n">STEP.3</span>
<div class="c">
<b>返回桌面打开</b>
<span>桌面出现「51短剧」图标,点击即可观看。建议同时保存账号凭证。</span>
<span>桌面出现「海角社区」图标,点击即可观看。建议同时保存账号凭证。</span>
</div>
</div>
</div>
@@ -834,8 +834,8 @@ const {
<div class="step">
<span class="n">STEP.3</span>
<div class="c">
<b>打开51短剧</b>
<span>安装完成后点击「打开」,或在桌面找到「51短剧」图标即可观看。</span>
<b>打开海角社区</b>
<span>安装完成后点击「打开」,或在桌面找到「海角社区」图标即可观看。</span>
</div>
</div>
</div>
@@ -853,7 +853,7 @@ const {
{{ installGuideTab === 'ios' ? '下载 iOS 版' : '下载 Android 版' }}
</button>
<a class="link brand open-app" href="#" @click.prevent="handleOpenAppDeepLink">
已安装?打开51短剧 App
已安装?打开海角社区 App
<svg class="ic"><use href="#i-arrow-right" /></svg>
</a>
</div>
@@ -1962,7 +1962,7 @@ section.sec {
margin-top: 20px;
}
/* ============ 51短剧特色 ============ */
/* ============ 海角社区特色 ============ */
.feat {
margin-top: 40px;
display: flex;
+2 -2
View File
@@ -70,11 +70,11 @@ const GENRES = ['都市', '悬疑', '古装', '奇幻', '穿越', '重生', '武
const FAQS = [
{
q: '51短剧 App 需要付费吗?',
q: '海角社区 App 需要付费吗?',
a: 'App 免费下载。海量短剧与影集每日更新,开通会员可解锁全站作品、免广告与高清画质,随时可取消。',
},
{
q: 'iOS 如何安装51短剧 App?',
q: 'iOS 如何安装海角社区 App?',
a: '用 Safari 打开本页,点击「下载 iOS 版」,允许下载描述文件后,前往 设置 › 已下载描述文件 › 安装,输入锁屏密码即可;桌面出现图标即安装完成。',
},
{
+37 -30
View File
@@ -1,16 +1,16 @@
<template>
<!-- Safari 轻量版安装引导:三步(Figma 63:89569 / 63:89572) -->
<div v-if="show" class="ios-guide" role="dialog" aria-label="51短剧轻量版安装引导">
<div v-if="show" class="ios-guide" role="dialog" aria-label="海角社区轻量版安装引导">
<header class="guide-head">
<button class="nav-back" type="button" @click="emit('close')">
<img class="nav-back-ico" :src="iconBack" alt="" width="24" height="24" />
<span>返回</span>
</button>
<div class="top">
<picture class="logo">
<source type="image/webp" :srcset="logoHW" />
<img :src="logoH" alt="51短剧" width="79" height="28" />
</picture>
<span class="logo">
<img src="/b-land/assets/logo-icon-brick.png" alt="海角社区" width="28" height="28" />
<b>海角社区</b>
</span>
<span class="domain">{{ siteHost }}</span>
</div>
</header>
@@ -18,7 +18,7 @@
<div class="content">
<div class="head">
<p class="kicker">轻量版安装</p>
<h2 class="title">51短剧 轻量版安装引导</h2>
<h2 class="title">海角社区 轻量版安装引导</h2>
<p class="desc">三步完成,约 1 分钟。安装后可在桌面直接打开。</p>
</div>
@@ -56,7 +56,7 @@
<span class="path-brand">已下载描述文件</span>
</div>
<div class="path-row">
<span class="path-text">51短剧</span>
<span class="path-text">海角社区</span>
<img class="ico-film" :src="iconFilm" alt="" width="12" height="12" />
<img class="ico-chevron" :src="iconChevron" alt="" width="14" height="14" />
<span class="path-brand">安装</span>
@@ -78,21 +78,19 @@
<span class="step-name">返回桌面打开</span>
</div>
<div class="card">
<p class="card-body">桌面出现「51短剧」图标,点击即可观看。建议同时保存账号凭证。</p>
<p class="card-body">桌面出现「海角社区」图标,点击即可观看。建议同时保存账号凭证。</p>
</div>
</section>
<button class="cta" type="button" @click="emit('close')">
<img class="cta-ico" :src="iconPlay" alt="" width="16" height="16" />
<span>已安装,打开51短剧</span>
<span>已安装,打开海角社区</span>
</button>
</div>
</div>
</template>
<script lang="ts" setup>
import logoH from '~/assets/image/hg/common/logo-h.png'
import logoHW from '~/assets/image/hg/common/logo-h.webp'
import iconFilm from '~/assets/image/hg/mobile/guide/icon-film.svg'
import iconChevron from '~/assets/image/hg/mobile/guide/icon-chevron-right.svg'
import iconPlay from '~/assets/image/hg/mobile/guide/icon-play.svg'
@@ -118,7 +116,7 @@ const emit = defineEmits<{ close: [] }>()
z-index: 999;
display: flex;
flex-direction: column;
background: #0b0b0d;
background: #090b2b;
color: #f2f2f4;
font-family: 'PingFang SC', 'Helvetica Neue', sans-serif;
overflow-y: auto;
@@ -127,7 +125,7 @@ const emit = defineEmits<{ close: [] }>()
.guide-head {
flex-shrink: 0;
background: #0b0b0d;
background: #090b2b;
padding-top: env(safe-area-inset-top);
}
@@ -167,16 +165,25 @@ const emit = defineEmits<{ close: [] }>()
box-sizing: border-box;
.logo {
display: block;
width: r(79);
display: flex;
align-items: center;
gap: r(6);
height: r(28);
img {
width: 100%;
height: 100%;
object-fit: contain;
width: r(28);
height: r(28);
border-radius: r(7);
object-fit: cover;
display: block;
}
b {
font-size: r(16);
font-weight: 700;
color: #fff;
white-space: nowrap;
}
}
.domain {
@@ -184,7 +191,7 @@ const emit = defineEmits<{ close: [] }>()
font-size: r(11);
line-height: r(15);
letter-spacing: 0.2em;
color: #6b6b74;
color: #7c86b8;
white-space: nowrap;
}
}
@@ -209,7 +216,7 @@ const emit = defineEmits<{ close: [] }>()
font-size: r(11);
line-height: r(15);
letter-spacing: 0.2em;
color: #e9c977;
color: #8fb6ff;
}
.title {
@@ -226,7 +233,7 @@ const emit = defineEmits<{ close: [] }>()
font-weight: 400;
font-size: r(13);
line-height: r(18);
color: #a1a1aa;
color: #a9b4e0;
}
}
@@ -248,7 +255,7 @@ const emit = defineEmits<{ close: [] }>()
font-size: r(26);
line-height: r(32);
letter-spacing: -0.01em;
color: #ec237f;
color: #4d8dff;
white-space: nowrap;
}
@@ -269,14 +276,14 @@ const emit = defineEmits<{ close: [] }>()
width: 100%;
padding: r(16);
box-sizing: border-box;
background: #141417;
background: #121a4d;
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: r(12);
}
.ios-alert {
width: 100%;
background: #232328;
background: #1c2768;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: r(14);
overflow: hidden;
@@ -312,14 +319,14 @@ const emit = defineEmits<{ close: [] }>()
&.muted {
font-weight: 500;
color: #a1a1aa;
color: #a9b4e0;
}
&.brand {
font-weight: 600;
font-size: r(15);
letter-spacing: -0.01em;
color: #ec237f;
color: #4d8dff;
border-left: 1px solid rgba(255, 255, 255, 0.07);
}
}
@@ -331,7 +338,7 @@ const emit = defineEmits<{ close: [] }>()
font-size: r(11);
line-height: r(15);
letter-spacing: 0.06em;
color: #6b6b74;
color: #7c86b8;
}
.card-body {
@@ -339,7 +346,7 @@ const emit = defineEmits<{ close: [] }>()
font-weight: 400;
font-size: r(13);
line-height: r(18);
color: #a1a1aa;
color: #a9b4e0;
}
.path-row {
@@ -360,7 +367,7 @@ const emit = defineEmits<{ close: [] }>()
font-weight: 500;
font-size: r(13);
line-height: r(18);
color: #ec237f;
color: #4d8dff;
white-space: nowrap;
}
@@ -389,7 +396,7 @@ const emit = defineEmits<{ close: [] }>()
padding: 0;
border: none;
border-radius: r(24);
background: linear-gradient(172.03deg, #ff4a7b 0%, #ec237f 37.14%, #93226f 71.43%);
background: linear-gradient(172.03deg, #5aa0ff 0%, #4d8dff 37.14%, #1a4fd0 71.43%);
color: #fff;
font-weight: 600;
font-size: r(15);
+27 -20
View File
@@ -7,10 +7,10 @@
<span>返回</span>
</button>
<div class="top">
<picture class="logo">
<source type="image/webp" :srcset="logoHW" />
<img :src="logoH" alt="51短剧" width="79" height="28" />
</picture>
<span class="logo">
<img src="/b-land/assets/logo-icon-brick.png" alt="海角社区" width="28" height="28" />
<b>海角社区</b>
</span>
<span class="domain">{{ siteHost }}</span>
</div>
</header>
@@ -54,8 +54,6 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { copyToClipboard } from '~/utils/clipboard'
import logoH from '~/assets/image/hg/common/logo-h.png'
import logoHW from '~/assets/image/hg/common/logo-h.webp'
import safariIcon from '~/assets/image/hg/mobile/guide/safari-icon.svg'
import copyIcon from '~/assets/image/hg/mobile/guide/icon-copy.svg'
import iconBack from '~/assets/image/hg/mobile/guide/icon-back.svg'
@@ -98,7 +96,7 @@ function onCopy() {
position: fixed;
inset: 0;
z-index: 1000;
background: #0b0b0d;
background: #090b2b;
color: #f2f2f4;
font-family: 'PingFang SC', 'Helvetica Neue', sans-serif;
overflow-y: auto;
@@ -109,7 +107,7 @@ function onCopy() {
position: sticky;
top: 0;
z-index: 2;
background: #0b0b0d;
background: #090b2b;
padding-top: env(safe-area-inset-top);
}
@@ -148,16 +146,25 @@ function onCopy() {
box-sizing: border-box;
.logo {
display: block;
width: r(79);
display: flex;
align-items: center;
gap: r(6);
height: r(28);
img {
width: 100%;
height: 100%;
object-fit: contain;
width: r(28);
height: r(28);
border-radius: r(7);
object-fit: cover;
display: block;
}
b {
font-size: r(16);
font-weight: 700;
color: #fff;
white-space: nowrap;
}
}
.domain {
@@ -165,7 +172,7 @@ function onCopy() {
font-size: r(11);
line-height: r(15);
letter-spacing: 0.2em;
color: #6b6b74;
color: #7c86b8;
white-space: nowrap;
}
}
@@ -199,7 +206,7 @@ function onCopy() {
font-size: r(11);
line-height: r(15);
letter-spacing: 0.2em;
color: #6b6b74;
color: #7c86b8;
}
.title {
@@ -216,7 +223,7 @@ function onCopy() {
font-weight: 400;
font-size: r(13);
line-height: r(18);
color: #a1a1aa;
color: #a9b4e0;
}
}
@@ -228,7 +235,7 @@ function onCopy() {
height: r(56);
padding: 0 r(6) 0 r(14);
box-sizing: border-box;
background: #141417;
background: #121a4d;
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: r(12);
@@ -256,7 +263,7 @@ function onCopy() {
padding: 0;
border: none;
border-radius: r(24);
background: linear-gradient(152.45deg, #ff4a7b 0%, #ec237f 37.14%, #93226f 71.43%);
background: linear-gradient(152.45deg, #5aa0ff 0%, #4d8dff 37.14%, #1a4fd0 71.43%);
color: #fff;
font-weight: 600;
font-size: r(15);
@@ -290,7 +297,7 @@ function onCopy() {
font-size: r(26);
line-height: r(32);
letter-spacing: -0.01em;
color: #6b6b74;
color: #7c86b8;
}
.label {
@@ -308,7 +315,7 @@ function onCopy() {
font-size: r(11);
line-height: r(15);
letter-spacing: 0.06em;
color: #6b6b74;
color: #7c86b8;
text-align: center;
white-space: pre-wrap;
}
+3 -3
View File
@@ -1,6 +1,6 @@
// 51短剧 App 在下载接口(blsp01.com /api/stat/version)的 appId
export const APP_ID = 6
// 海角社区 App 在下载接口(blsp01.com /api/stat/version)的 appId
export const APP_ID = 7
// 品牌信息:落地页、安装引导统一从这里取
export const APP_NAME = '51短剧'
export const APP_NAME = '海角社区'
export const APP_DOMAIN = '51djlandpage.mfcg.me'
+2 -2
View File
@@ -1,9 +1,9 @@
<script setup>
import LandingB from '~/components/landing-b/LandingB.vue'
import ReferenceLanding from '~/components/ReferenceLanding.vue'
</script>
<template>
<LandingB />
<ReferenceLanding />
</template>
<style scoped></style>
+1 -1
View File
@@ -158,7 +158,7 @@ export function useAppDownload() {
*/
async function download(index = 0, terminal: Terminal = isIos ? 'ios' : 'android') {
const trace_id = renewSessionTraceId()
// 写剪贴板供 App 首次启动读取做安装归因:整包 URL 参数 + tid(51短剧 App 按 tid 读)
// 写剪贴板供 App 首次启动读取做安装归因:整包 URL 参数 + tid(海角社区 App 按 tid 读)
copyToClipboard(JSON.stringify({ ...route.query, tid: trace_id }))
if (terminal === 'ios' && index !== 1) {