feat(site): rewrite the landing page around verified facts and accessible controls
- Replace claims that contradicted the app: the default hotkey is Right Alt (hold to talk), local features are free with no daily cap, there is no 14-day trial, Team/SSO/SCIM/ZDR are not offered, and the repository is not public. Remove invented metrics, status badges, the competitor table, the ad-mediation changelog, the hash calculator and the duplicate demo. - Seven sections: hero with one labelled example, features, how it works, privacy, pricing (Free / Pro 2,900 / Pro+ 8,900 KRW a month), download, FAQ. Footer links the privacy policy, terms and account deletion pages. - All copy moves into i18n and every one of the 10 locales is translated. Pricing and cloud quotas come from site/src/pricing.ts. - Accessibility: skip link, labelled sections, aria-expanded with Esc and focus return for the menu, language list and FAQ, live status for the example, reduced-motion support, 44px targets, AA contrast on the primary button. Korean keep-all line breaking is scoped to :lang(ko) because Tailwind's break-keep blocked wrapping in Japanese and Chinese. - JS 111 -> 98 KB gzip, CSS 7.8 -> 5.2 KB gzip.
This commit is contained in:
parent
ad6bb70c20
commit
e689683b72
44 changed files with 2198 additions and 3782 deletions
|
|
@ -1,399 +1,69 @@
|
|||
import { useState, type ChangeEvent, type DragEvent } from 'react'
|
||||
import { Container } from '../components/Container'
|
||||
import { SectionHeader } from '../components/SectionHeader'
|
||||
import { useI18n } from '../i18n'
|
||||
import { SectionHeading } from '../components/SectionHeading'
|
||||
import { DownloadIcon, ExternalIcon } from '../components/icons'
|
||||
import { fmt, useI18n } from '../i18n'
|
||||
import {
|
||||
DESKTOP_FEED_URL,
|
||||
DESKTOP_RELEASE_DATE,
|
||||
DESKTOP_RELEASE_HUB_URL,
|
||||
DESKTOP_VERSION,
|
||||
DESKTOP_WINDOWS_INSTALLER_FILENAME,
|
||||
DESKTOP_WINDOWS_INSTALLER_URL,
|
||||
} from '../release'
|
||||
|
||||
export function Download() {
|
||||
const { locale } = useI18n()
|
||||
const isKo = locale === 'ko'
|
||||
const { t, bcp47 } = useI18n()
|
||||
|
||||
const [verifyStatus, setVerifyStatus] = useState<'idle' | 'computing' | 'custom'>('idle')
|
||||
const [computedHash, setComputedHash] = useState('')
|
||||
const [fileName, setFileName] = useState('')
|
||||
const [isDragOver, setIsDragOver] = useState(false)
|
||||
|
||||
const computeFileHash = async (file: File) => {
|
||||
setFileName(`${file.name} (${(file.size / (1024 * 1024)).toFixed(1)} MB)`)
|
||||
setVerifyStatus('computing')
|
||||
|
||||
try {
|
||||
const arrayBuffer = await file.arrayBuffer()
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer)
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
||||
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
|
||||
|
||||
setComputedHash(hashHex)
|
||||
setVerifyStatus('custom')
|
||||
} catch {
|
||||
setVerifyStatus('custom')
|
||||
}
|
||||
}
|
||||
|
||||
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const files = e.target.files
|
||||
if (files && files.length > 0) {
|
||||
void computeFileHash(files[0])
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault()
|
||||
setIsDragOver(true)
|
||||
}
|
||||
|
||||
const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault()
|
||||
setIsDragOver(false)
|
||||
}
|
||||
|
||||
const handleDrop = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault()
|
||||
setIsDragOver(false)
|
||||
const files = e.dataTransfer.files
|
||||
if (files && files.length > 0) {
|
||||
void computeFileHash(files[0])
|
||||
}
|
||||
}
|
||||
const date = new Intl.DateTimeFormat(bcp47, { dateStyle: 'long', timeZone: 'UTC' }).format(
|
||||
new Date(`${DESKTOP_RELEASE_DATE}T00:00:00Z`),
|
||||
)
|
||||
const details = fmt(t.download.details, { date })
|
||||
|
||||
return (
|
||||
<section id="download" className="py-20 md:py-28 bg-surface-900/60 border-t border-white/[0.04] relative">
|
||||
<section id="download" aria-labelledby="download-title" className="section border-t border-white/10">
|
||||
<Container>
|
||||
<SectionHeader
|
||||
index="06 / DOWNLOAD"
|
||||
title={isKo ? 'D3RO Voice 릴리스 센터' : 'D3RO Voice Release Center'}
|
||||
subtitle={
|
||||
isKo
|
||||
? `공식 릴리스 v${DESKTOP_VERSION} 설치 파일을 게시된 피드에서 내려받을 수 있습니다. 설치 후 자동 업데이트로 이후 버전을 받습니다.`
|
||||
: `Download the official v${DESKTOP_VERSION} installer from the published update feed. Auto-update delivers later versions after install.`
|
||||
}
|
||||
/>
|
||||
<SectionHeading id="download-title" title={t.download.title} subtitle={t.download.subtitle} />
|
||||
|
||||
{/* Primary Recommended OS Download Card */}
|
||||
<div className="max-w-3xl mx-auto mb-16 p-7 md:p-9 rounded-3xl bg-surface-800/90 border border-brand-blue/40 shadow-glow-md relative overflow-hidden backdrop-blur-2xl noise-texture">
|
||||
<div className="absolute top-0 right-0 w-64 h-64 bg-brand-blue/10 rounded-full blur-3xl pointer-events-none" />
|
||||
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-6 mb-7">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-13 h-13 rounded-2xl bg-brand-blue/15 border border-brand-blue/30 flex items-center justify-center text-brand-blue shadow-sm p-3">
|
||||
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<path d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2.5 mb-1">
|
||||
<h3 className="text-xl sm:text-2xl font-medium text-neutral-50">
|
||||
D3RO Voice Desktop {DESKTOP_VERSION}
|
||||
</h3>
|
||||
<span className="px-2.5 py-0.5 rounded-full text-xs font-medium bg-emerald-500/20 text-emerald-300 border border-emerald-500/35">
|
||||
{isKo ? '공식 릴리스' : 'OFFICIAL STABLE RELEASE'}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs sm:text-sm text-neutral-300 font-normal">
|
||||
Windows 10 / 11 (x64) · NSIS standalone installer
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 bg-surface-700/80 px-3 py-1 rounded-full border border-white/10">
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-400" />
|
||||
<span className="text-xs font-medium text-neutral-200">v{DESKTOP_VERSION} RELEASE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Primary Action Button */}
|
||||
<div className="mb-5">
|
||||
<a
|
||||
href={DESKTOP_WINDOWS_INSTALLER_URL}
|
||||
className="glow-btn w-full py-4.5 sm:py-5 px-8 sm:px-10 rounded-2xl bg-brand-blue text-white text-base sm:text-lg font-medium flex items-center justify-center gap-3 leading-normal shadow-glow-sm hover:shadow-glow-md active:scale-[0.99] transition-all"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<path d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||
</svg>
|
||||
<span>{isKo ? `Windows용 다운로드 (x64) - v${DESKTOP_VERSION}` : `Download for Windows (x64) - v${DESKTOP_VERSION}`}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Update Feed Verification Strip */}
|
||||
<div className="pt-3.5 border-t border-white/10 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 text-xs">
|
||||
<div className="flex items-center gap-2 text-neutral-300">
|
||||
<span className="font-medium text-neutral-400">SHA-512:</span>
|
||||
<a
|
||||
href={`${DESKTOP_FEED_URL}/latest.yml`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="font-mono text-neutral-200 bg-surface-900/60 px-2 py-0.5 rounded border border-white/10 hover:text-brand-blue"
|
||||
>
|
||||
latest.yml
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<a
|
||||
href={DESKTOP_RELEASE_HUB_URL}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-brand-blue hover:underline"
|
||||
>
|
||||
{isKo ? '릴리스 노트' : 'Release notes'}
|
||||
</a>
|
||||
<span className="text-xs text-emerald-300 font-medium flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-400" />
|
||||
{isKo ? '업데이트 피드 연결됨' : 'Update feed connected'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* All Platform Packages Bento Grid */}
|
||||
<div className="mb-16">
|
||||
<div className="flex items-center justify-between mb-5">
|
||||
<h3 className="text-xl font-medium text-neutral-100">
|
||||
{isKo ? '전체 플랫폼 설치 패키지' : 'All Platform Packages'}
|
||||
</h3>
|
||||
<span className="text-xs text-neutral-400 font-normal">
|
||||
{isKo ? '자동 업데이트: 서명된 피드 검증 후 활성화' : 'Auto-update: activates after signed feed verification'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{/* Windows Package */}
|
||||
<div className="p-6 rounded-2xl bg-surface-800/80 border border-white/10 hover:border-brand-blue/40 shadow-glass-card backdrop-blur-xl transition-all flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-xs font-medium text-brand-blue">WINDOWS 10 / 11</span>
|
||||
<span className="font-mono text-xs text-neutral-400">x64</span>
|
||||
</div>
|
||||
<h4 className="text-lg font-medium text-neutral-50 mb-1.5">Windows Setup</h4>
|
||||
<p className="text-xs sm:text-sm text-neutral-300 mb-5 leading-relaxed font-normal">
|
||||
{isKo
|
||||
? '무설정 자동 업데이트와 오프라인 Whisper 로컬 AI를 지원하는 공식 설치 패키지입니다.'
|
||||
: 'Official installation package with background auto-updates and zero-latency local AI.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href={DESKTOP_WINDOWS_INSTALLER_URL}
|
||||
className="w-full py-2.5 px-3.5 rounded-xl bg-brand-blue/20 hover:bg-brand-blue/30 border border-brand-blue/40 text-brand-blue text-xs font-medium flex items-center justify-between transition-all"
|
||||
>
|
||||
<span>{DESKTOP_WINDOWS_INSTALLER_FILENAME}</span>
|
||||
<span>{isKo ? '다운로드 (.exe)' : 'Download (.exe)'}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* macOS Package */}
|
||||
<div className="p-6 rounded-2xl bg-surface-800/80 border border-white/10 hover:border-purple-400/40 shadow-glass-card backdrop-blur-xl transition-all flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-xs font-medium text-purple-300">MACOS 12.0+</span>
|
||||
<span className="font-mono text-xs text-neutral-400">Apple Silicon</span>
|
||||
</div>
|
||||
<h4 className="text-lg font-medium text-neutral-50 mb-1.5">macOS DMG</h4>
|
||||
<p className="text-xs sm:text-sm text-neutral-300 mb-5 leading-relaxed font-normal">
|
||||
{isKo
|
||||
? 'Apple Silicon 후보 빌드의 코드 서명과 설치 동작을 검증 중입니다.'
|
||||
: 'The Apple Silicon candidate is undergoing code-signing and installation verification.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div
|
||||
aria-disabled="true"
|
||||
className="w-full py-2.5 px-3.5 rounded-xl bg-surface-900/60 border border-white/10 text-neutral-400 text-xs font-medium flex items-center justify-between"
|
||||
>
|
||||
<span>Apple Silicon DMG</span>
|
||||
<span>{isKo ? '검증 대기' : 'Verification pending'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Android / iOS Mobile */}
|
||||
<div className="p-6 rounded-2xl bg-surface-800/80 border border-white/10 hover:border-emerald-500/40 shadow-glass-card backdrop-blur-xl transition-all flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-xs font-medium text-emerald-400">ANDROID</span>
|
||||
<span className="text-xs text-neutral-400">Mobile Edition</span>
|
||||
</div>
|
||||
<h4 className="text-lg font-medium text-neutral-50 mb-1.5">D3RO Voice Mobile</h4>
|
||||
<p className="text-xs sm:text-sm text-neutral-300 mb-5 leading-relaxed font-normal">
|
||||
{isKo
|
||||
? 'Google Play용 AAB와 스토어 메타데이터의 검증을 마친 뒤 Android 배포를 시작합니다.'
|
||||
: 'Android distribution begins after the Play AAB and store metadata are verified.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div
|
||||
aria-disabled="true"
|
||||
className="w-full py-2.5 px-3.5 rounded-xl bg-surface-900/60 border border-white/10 text-neutral-400 text-xs font-medium flex items-center justify-between"
|
||||
>
|
||||
<span>{isKo ? 'Android 공식 APK' : 'Official Android APK'}</span>
|
||||
<span>{isKo ? '서명 증거 확인 대기' : 'Unavailable — evidence pending'}</span>
|
||||
</div>
|
||||
<div className="w-full py-2 px-3.5 rounded-xl bg-surface-900/50 text-neutral-500 text-xs flex items-center justify-between">
|
||||
<span>iOS App Store / TestFlight</span>
|
||||
<span>{isKo ? '검증된 배포 없음' : 'No verified distribution'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Client-Side Cryptographic Verifier Box */}
|
||||
<div className="p-7 md:p-8 rounded-3xl bg-surface-800/70 border border-white/10 shadow-glass-card backdrop-blur-xl mb-16">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-6">
|
||||
<div>
|
||||
<span className="text-xs font-medium text-brand-blue uppercase tracking-wider block mb-1">
|
||||
LOCAL FILE UTILITY
|
||||
</span>
|
||||
<h3 className="text-lg sm:text-xl font-medium text-neutral-50 mb-1">
|
||||
{isKo ? '로컬 SHA-256 계산기' : 'Client-Side SHA-256 Calculator'}
|
||||
<div className="mt-14 grid grid-cols-1 gap-5 lg:grid-cols-12">
|
||||
<div className="rounded-2xl border border-brand-blue/50 bg-surface-800 p-6 md:p-9 lg:col-span-8">
|
||||
<div className="flex flex-wrap items-baseline justify-between gap-3">
|
||||
<h3 className="text-h3 font-medium text-neutral-50">
|
||||
{t.download.windowsName}{' '}
|
||||
<span className="font-mono text-base font-normal text-neutral-300">v{DESKTOP_VERSION}</span>
|
||||
</h3>
|
||||
<p className="text-xs sm:text-sm text-neutral-300 font-normal">
|
||||
{isKo
|
||||
? '선택한 파일의 SHA-256 값을 브라우저에서 계산합니다. 공식 릴리스 판정은 제공하지 않습니다.'
|
||||
: 'Compute a selected file hash locally with WebCrypto. This does not certify an official release.'}
|
||||
</p>
|
||||
<p className="text-sm text-neutral-300">{t.download.windowsMeta}</p>
|
||||
</div>
|
||||
<label className="px-4 py-2 rounded-xl bg-surface-700 hover:bg-surface-600 border border-white/10 hover:border-brand-blue/40 text-neutral-200 text-xs font-medium cursor-pointer transition-all flex items-center gap-2">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="17 8 12 3 7 8" />
|
||||
<line x1="12" y1="3" x2="12" y2="15" />
|
||||
</svg>
|
||||
<span>{isKo ? '파일 선택하여 검증' : 'Select File'}</span>
|
||||
<input type="file" onChange={handleFileChange} className="hidden" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Drag & Drop Target Area */}
|
||||
<div
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
className={`p-7 rounded-2xl border-2 border-dashed transition-all text-center ${
|
||||
isDragOver
|
||||
? 'border-brand-blue bg-brand-blue/10'
|
||||
: 'border-white/15 bg-surface-900/50 hover:border-white/25'
|
||||
}`}
|
||||
>
|
||||
{verifyStatus === 'idle' && (
|
||||
<div className="space-y-1.5 text-neutral-400">
|
||||
<p className="text-xs sm:text-sm font-normal text-neutral-200">
|
||||
{isKo ? '설치 파일(.exe / .dmg / .zip)을 이곳에 끌어다 놓으세요' : 'Drop installer file here to compute cryptographic hash'}
|
||||
</p>
|
||||
<p className="text-xs text-neutral-400 font-normal">
|
||||
{isKo ? '파일은 서버로 전송되지 않고 로컬 브라우저에서 안전하게 계산됩니다.' : 'Calculated in-memory locally via browser WebCrypto.'}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{verifyStatus === 'computing' && (
|
||||
<div className="flex items-center justify-center gap-3 text-brand-blue text-xs sm:text-sm font-medium">
|
||||
<span className="w-2 h-2 rounded-full bg-brand-blue animate-ping" />
|
||||
<span>{isKo ? 'SHA-256 해시 계산 중...' : 'Computing SHA-256 hash locally...'}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{verifyStatus === 'custom' && (
|
||||
<div className="space-y-2 text-left bg-surface-950 p-4 rounded-xl border border-white/10">
|
||||
<div className="flex items-center justify-between text-xs text-neutral-300">
|
||||
<span className="font-medium text-brand-blue">{isKo ? '로컬 해시 계산 완료' : 'Local Hash Computed'}</span>
|
||||
<span>{fileName}</span>
|
||||
</div>
|
||||
<div className="font-mono text-xs text-neutral-200 break-all pt-1 border-t border-white/10">
|
||||
{computedHash}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Release History Section */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-5">
|
||||
<div>
|
||||
<span className="text-xs font-medium text-brand-blue uppercase tracking-wider block mb-1">
|
||||
VERSION ARCHIVE
|
||||
</span>
|
||||
<h3 className="text-xl font-medium text-neutral-50">
|
||||
{isKo ? '릴리스 버전 히스토리' : 'Release Archive & Changelog'}
|
||||
</h3>
|
||||
</div>
|
||||
<a
|
||||
href={DESKTOP_RELEASE_HUB_URL}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-xs text-brand-blue hover:text-brand-blue-light transition-colors font-medium flex items-center gap-1.5"
|
||||
>
|
||||
<span>Forgejo Git 릴리스 전체 보기</span>
|
||||
<span>→</span>
|
||||
<a href={DESKTOP_WINDOWS_INSTALLER_URL} className="btn btn-primary btn-lg mt-7 w-full sm:w-auto">
|
||||
<DownloadIcon />
|
||||
{t.download.cta}
|
||||
</a>
|
||||
|
||||
<p className="mt-5 keep-ko text-sm leading-relaxed text-neutral-400">{details}</p>
|
||||
|
||||
<p className="mt-3 flex flex-wrap gap-x-6 text-sm">
|
||||
<a href={DESKTOP_RELEASE_HUB_URL} target="_blank" rel="noopener" className="link inline-flex min-h-[44px] items-center gap-1">
|
||||
{t.download.releaseNotes}
|
||||
<ExternalIcon />
|
||||
<span className="sr-only">({t.a11y.opensInNewTab})</span>
|
||||
</a>
|
||||
<a href={`${DESKTOP_FEED_URL}/latest.yml`} target="_blank" rel="noopener" className="link inline-flex min-h-[44px] items-center gap-1">
|
||||
{t.download.checksum}
|
||||
<ExternalIcon />
|
||||
<span className="sr-only">({t.a11y.opensInNewTab})</span>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{/* v1.0.0 Release */}
|
||||
<div className="p-6 rounded-2xl bg-surface-800/80 border-l-4 border-l-brand-blue border border-white/10 shadow-glass-card">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-3 pb-3 border-b border-white/[0.06]">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-base font-medium text-neutral-100">v1.0.0</span>
|
||||
<span className="px-2.5 py-0.5 rounded-full text-xs font-medium bg-brand-blue/15 text-brand-blue border border-brand-blue/30">
|
||||
ARCHIVED · DOWNLOAD UNAVAILABLE
|
||||
</span>
|
||||
<span className="text-xs text-neutral-400">2026-08-20</span>
|
||||
</div>
|
||||
<span
|
||||
aria-disabled="true"
|
||||
className="px-3.5 py-1.5 rounded-xl bg-surface-900/60 text-neutral-400 border border-white/10 text-xs font-medium self-start sm:self-auto"
|
||||
>
|
||||
{isKo ? '과거 바이너리 미제공' : 'Historical binary unavailable'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<ul className="space-y-1.5 text-xs sm:text-sm text-neutral-300 mb-3.5 font-normal leading-relaxed">
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-brand-blue font-medium">•</span>
|
||||
<span><strong className="text-neutral-100 font-medium">10+ 글로벌 광고 미디에이션</strong>: EthicalAds, Carbon Ads, GAM, Playwire, AppLovin, Unity Ads 실시간 입찰.</span>
|
||||
<div className="rounded-2xl border border-white/10 p-6 md:p-7 lg:col-span-4">
|
||||
<h3 className="text-sm font-medium text-neutral-300">{t.download.soonTitle}</h3>
|
||||
<ul className="mt-4 divide-y divide-white/10">
|
||||
{t.download.soon.map((item) => (
|
||||
<li key={item.title} className="py-4 first:pt-0 last:pb-0">
|
||||
<p className="text-base text-neutral-100">{item.title}</p>
|
||||
<p className="mt-1 keep-ko text-sm leading-relaxed text-neutral-400">{item.body}</p>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-brand-blue font-medium">•</span>
|
||||
<span><strong className="text-neutral-100 font-medium">무료 티어 리워드 충전</strong>: 15초 스폰서 비디오 시청 완료 시 +50 Cloud AI 토큰 자동 리필.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-brand-blue font-medium">•</span>
|
||||
<span><strong className="text-neutral-100 font-medium">100% 로컬 Whisper 전사 엔진</strong>: 네트워크 연결 없이 실시간 고속 오프라인 음성 텍스트 변환.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-brand-blue font-medium">•</span>
|
||||
<span><strong className="text-neutral-100 font-medium">모바일 TEST-DEMO</strong>: 공식 서명 증거와 스토어 심사가 끝날 때까지 일반 다운로드는 제공하지 않습니다.</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="text-xs text-neutral-400 p-2.5 rounded-lg bg-surface-950 border border-white/[0.04]">
|
||||
{isKo
|
||||
? '이 항목은 변경 이력으로만 보존합니다. 설치 파일, 고정 해시, 용량 정보는 현재 릴리스로 제공하지 않습니다.'
|
||||
: 'This entry is retained only as history. Its installer, fixed hash, and size are not offered as a current release.'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* v0.2.1-alpha */}
|
||||
<div className="p-5 rounded-2xl bg-surface-800/50 border-l-4 border-l-surface-600 border border-white/5 opacity-75">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<span className="text-sm font-medium text-neutral-200">v0.2.1-alpha</span>
|
||||
<span className="px-2 py-0.5 rounded-full text-xs font-normal bg-white/5 text-neutral-400 border border-white/10">PRE-RELEASE</span>
|
||||
<span className="text-xs text-neutral-500 font-mono">2026-08-15</span>
|
||||
</div>
|
||||
<p className="text-xs text-neutral-300 font-normal">
|
||||
Deepgram, AssemblyAI, Groq 멀티 클라우드 STT 드라이버 디스패처 및 암호화 라이선스 키 검증 엔진 탑재.
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue