/* ==========================================================================
   VoxLocal — 本地音色克隆合成台
   深色主题，结构参考主流 AI 语音站：粘性导航 / Hero / 双栏工作台 /
   音色卡片网格 / 资源下载区。
   ========================================================================== */

:root {
	/* Palette taken from the Audiofilter site root (../styles.css) so this tool
	   reads as part of the same site. Only the tokens changed — the layout and
	   component CSS below are untouched. */
	--bg:         #090b10;
	--bg-1:       #11141b;
	--bg-2:       #181523;
	--bg-3:       #1f1b2e;
	--line:       #2b303a;
	--line-2:     #3a4150;
	--fg:         #f4f2f8;
	--fg-2:       #9a9daa;
	--fg-3:       #6e7280;
	--acc:        #7a45e8;
	--acc-2:      #9a6df0;
	--acc-glow:   rgba(122, 69, 232, .35);
	--cyan:       #11bfa7;
	--green:      #34d399;
	--amber:      #fbbf24;
	--red:        #f87171;
	--r:          14px;
	--r-sm:       9px;
	--shadow:     0 8px 30px rgba(0, 0, 0, .45);
	--mono:       ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
	margin: 0;
	background: var(--bg);
	color: var(--fg);
	font: 15px/1.65 Inter, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
	-webkit-font-smoothing: antialiased;
}

/* 背景光晕 */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	pointer-events: none;
	z-index: 0;
	background:
		radial-gradient(720px 380px at 12% -8%, rgba(122, 69, 232, .18), transparent 70%),
		radial-gradient(620px 340px at 92% 4%, rgba(17, 191, 167, .10), transparent 70%);
}

.wrap { position: relative; z-index: 1; max-width: 1240px; margin: 0 auto; padding: 0 24px; }

a { color: var(--acc-2); text-decoration: none; }
a:hover { text-decoration: underline; }
code, kbd { font-family: var(--mono); font-size: .9em; }

/* ---------- Hero --------------------------------------------------------- */

.hero { padding: 60px 0 40px; }
.hero h1 {
	margin: 0 0 16px; font-size: clamp(30px, 5vw, 47px); line-height: 1.14;
	font-weight: 800; letter-spacing: -.8px;
}
.hero h1 em {
	font-style: normal;
	background: linear-gradient(100deg, var(--acc-2), var(--cyan));
	-webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero p.lede { margin: 0 0 26px; font-size: 17px; color: var(--fg-2); max-width: 660px; }

.stat-row { display: flex; flex-wrap: wrap; gap: 12px; }
.stat {
	background: var(--bg-1); border: 1px solid var(--line);
	border-radius: var(--r); padding: 13px 18px; min-width: 132px;
}
.stat b { display: block; font-size: 20px; font-family: var(--mono); color: var(--fg); }
.stat span { font-size: 12px; color: var(--fg-3); }

/* ---------- 通用区块 ------------------------------------------------------ */

section { padding: 34px 0; }
.sec-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 20px; flex-wrap: wrap; }
.sec-head h2, .sec-head h3 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -.3px; }
.sec-head p { margin: 0; color: var(--fg-3); font-size: 14px; }

.card {
	background: var(--bg-1); border: 1px solid var(--line);
	border-radius: var(--r); padding: 22px;
}

/* ---------- 加载遮罩 ------------------------------------------------------ */

.loader { margin-bottom: 22px; }
.loader .bar-outer {
	height: 8px; background: var(--bg-3); border-radius: 999px; overflow: hidden; margin: 14px 0 10px;
}
.loader .bar-inner {
	height: 100%; width: 0%; border-radius: 999px;
	background: linear-gradient(90deg, var(--acc), var(--cyan));
	transition: width .25s ease;
}
.loader .row { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--fg-2); }
.loader .row .pct { font-family: var(--mono); color: var(--fg); }
.loader .hint { margin-top: 12px; font-size: 12.5px; color: var(--fg-3); }

.btn-start {
	display: inline-flex; align-items: center; gap: 9px;
	background: linear-gradient(135deg, var(--acc), var(--acc-2));
	color: #fff; border: 0; border-radius: var(--r-sm);
	padding: 12px 22px; font-size: 15px; font-weight: 600; cursor: pointer;
	box-shadow: 0 4px 18px var(--acc-glow); transition: .15s;
}
.btn-start:hover { transform: translateY(-1px); }
.btn-start:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* ---------- 工作台栅格 ---------------------------------------------------- */

.bench { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 20px; align-items: start; }
@media (max-width: 940px) { .bench { grid-template-columns: 1fr; } }

/* ---------- 音色卡片 ------------------------------------------------------ */

.voice-toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.chip {
	background: var(--bg-2); border: 1px solid var(--line);
	color: var(--fg-2); font-size: 12.5px; padding: 6px 12px;
	border-radius: 999px; cursor: pointer; transition: .15s;
}
.chip:hover { color: var(--fg); border-color: var(--line-2); }
.chip[aria-pressed="true"] { background: var(--acc); border-color: var(--acc); color: #fff; }

.voice-grid {
	display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
	gap: 11px; min-height: 250px; max-height: 470px; overflow-y: auto; padding-right: 5px;
}
.voice-grid::-webkit-scrollbar { width: 9px; }
.voice-grid::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 9px; }

.vcard {
	position: relative; text-align: left;
	background: var(--bg-2); border: 1px solid var(--line);
	border-radius: var(--r-sm); padding: 12px 13px; cursor: pointer;
	transition: .15s; font: inherit; color: inherit;
}
.vcard:hover { border-color: var(--line-2); background: var(--bg-3); }
.vcard[aria-pressed="true"] {
	border-color: var(--acc); background: rgba(108, 92, 231, .13);
	box-shadow: 0 0 0 1px var(--acc) inset;
}
.vcard .vtop { display: flex; align-items: center; gap: 10px; }
.vcard .av {
	width: 34px; height: 34px; border-radius: 50%; flex: none;
	display: grid; place-items: center; font-size: 13px; font-weight: 700; color: #fff;
}
.vcard .vname {
	font-size: 13.5px; font-weight: 600; line-height: 1.3;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vcard .vacc { font-size: 11.5px; color: var(--fg-3); }
.vcard .vfoot { display: flex; align-items: center; gap: 7px; margin-top: 10px; }

.mini {
	background: var(--bg-3); border: 1px solid var(--line-2); color: var(--fg-2);
	width: 26px; height: 26px; border-radius: 50%; cursor: pointer;
	display: grid; place-items: center; padding: 0; flex: none; transition: .15s;
}
.mini:hover { color: var(--fg); border-color: var(--acc); }
.mini svg { width: 11px; height: 11px; }

.lic {
	font-size: 10.5px; font-family: var(--mono); padding: 2px 7px;
	border-radius: 5px; letter-spacing: .2px;
}
.lic.cc0   { background: rgba(52, 211, 153, .13); color: var(--green); }
.lic.ccby  { background: rgba(251, 191, 36, .13); color: var(--amber); }
.lic.mine  { background: rgba(34, 211, 238, .13); color: var(--cyan); }

.mini.del { margin-left: auto; color: var(--fg-3); }
.mini.del:hover { color: var(--red); border-color: rgba(248, 113, 113, .45); }

/* ---------- 上传区 -------------------------------------------------------- */

.drop {
	margin-top: 15px; border: 1.5px dashed var(--line-2); border-radius: var(--r-sm);
	padding: 20px; text-align: center; cursor: pointer; transition: .15s;
	background: var(--bg-2);
}
.drop:hover, .drop.over { border-color: var(--acc); background: rgba(108, 92, 231, .08); }
.drop .di { font-size: 22px; margin-bottom: 6px; }
.drop .dt { font-size: 13.5px; font-weight: 600; }
.drop .dl { font-size: 12px; color: var(--fg-3); margin-top: 5px; line-height: 1.6; }

.limits { margin-top: 12px; }
.limits li { font-size: 12.5px; color: var(--fg-3); margin: 4px 0; }
.limits b { color: var(--fg-2); font-family: var(--mono); }

/* ---------- 样音试听（录制 / 上传后的试听条） ---------- */
.sample { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-top: 12px; }
.sample-name { font-size: 12.5px; color: var(--fg-2); font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sample[hidden] { display: none !important; }

/* ---------- 文本 / 控件 --------------------------------------------------- */

label.fl { display: block; font-size: 13px; color: var(--fg-2); margin-bottom: 8px; font-weight: 600; }

textarea#text {
	width: 100%; min-height: 132px; resize: vertical;
	background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-sm);
	color: var(--fg); padding: 13px 14px; font: inherit; line-height: 1.6;
}
textarea#text:focus { outline: 0; border-color: var(--acc); box-shadow: 0 0 0 3px var(--acc-glow); }

.ta-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 7px; }
.ta-foot .cnt { font-size: 12px; color: var(--fg-3); font-family: var(--mono); }
.ta-foot .cnt.over { color: var(--red); }

.samples { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.samples button {
	background: var(--bg-3); border: 1px solid var(--line); color: var(--fg-3);
	font-size: 12px; padding: 4px 10px; border-radius: 999px; cursor: pointer;
}
.samples button:hover { color: var(--fg); border-color: var(--line-2); }

.ctrl-row { display: flex; align-items: center; gap: 14px; margin-top: 16px; flex-wrap: wrap; }
.slider-box { flex: 1; min-width: 190px; }
.slider-box .sl-top { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--fg-2); }
.slider-box .sl-top b { font-family: var(--mono); color: var(--fg); }
input[type=range] {
	width: 100%; margin-top: 7px; accent-color: var(--acc);
	background: transparent; height: 18px;
}

.btn-go {
	display: inline-flex; align-items: center; justify-content: center; gap: 9px;
	background: linear-gradient(135deg, var(--acc), var(--acc-2));
	color: #fff; border: 0; border-radius: var(--r-sm);
	padding: 13px 30px; font-size: 15.5px; font-weight: 700; cursor: pointer;
	box-shadow: 0 4px 18px var(--acc-glow); transition: .15s; width: 100%; margin-top: 18px;
}
.btn-go:hover:not(:disabled) { transform: translateY(-1px); }
.btn-go:disabled { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-go svg { width: 16px; height: 16px; }

.btn-sub {
	background: var(--bg-3); border: 1px solid var(--line-2); color: var(--fg);
	border-radius: var(--r-sm); padding: 9px 16px; font-size: 13.5px; cursor: pointer;
	display: inline-flex; align-items: center; gap: 7px; transition: .15s;
}
.btn-sub:hover:not(:disabled) { border-color: var(--acc); }
.btn-sub:disabled { opacity: .4; cursor: not-allowed; }

/* ---------- 结果 ---------------------------------------------------------- */

.result { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); }
.result[hidden] { display: none !important; }
.wave {
	height: 62px; background: var(--bg-2); border: 1px solid var(--line);
	border-radius: var(--r-sm); margin-bottom: 12px; overflow: hidden;
}
.wave canvas { width: 100%; height: 100%; display: block; }
.res-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.metrics { margin-left: auto; display: flex; gap: 16px; font-size: 12px; color: var(--fg-3); }
.metrics b { display: block; font-family: var(--mono); font-size: 14px; color: var(--fg); }

.status {
	margin-top: 14px; font-size: 13px; color: var(--fg-2);
	display: flex; align-items: center; gap: 9px; min-height: 20px;
}
.status[hidden] { display: none !important; }
.status.err { color: var(--red); }
.spin {
	width: 13px; height: 13px; flex: none; border-radius: 50%;
	border: 2px solid var(--line-2); border-top-color: var(--acc);
	animation: sp .7s linear infinite;
}
@keyframes sp { to { transform: rotate(360deg); } }

/* ---------- 资源下载 ------------------------------------------------------ */

table.res {
	width: 100%; border-collapse: collapse; font-size: 13.5px;
}
table.res th, table.res td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
table.res th { color: var(--fg-3); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
table.res td.num { font-family: var(--mono); color: var(--fg-2); text-align: right; white-space: nowrap; }
table.res tr:last-child td { border-bottom: 0; }
table.res .fn { font-family: var(--mono); font-size: 12.5px; }
.tbl-scroll { overflow-x: auto; }

.note {
	background: var(--bg-2); border-left: 3px solid var(--amber);
	border-radius: 0 var(--r-sm) var(--r-sm) 0; padding: 13px 16px;
	font-size: 13px; color: var(--fg-2); margin-top: 16px;
}
.note.info { border-left-color: var(--cyan); }
.note b { color: var(--fg); }

/* ==========================================================================
   Demo-flow components (progress-only loading, steps, FAQ)
   ========================================================================== */

/* 步骤序号 */
.sec-head .step {
	display: inline-grid; place-items: center;
	width: 22px; height: 22px; margin-right: 7px; vertical-align: 2px;
	border-radius: 50%; background: var(--acc); color: #fff;
	font-size: 12px; font-weight: 700;
}

/* 进度条：原先只在 .loader 内生效，这里改为通用 */
.bar-outer {
	height: 8px; background: var(--bg-3); border-radius: 999px;
	overflow: hidden; margin: 0 0 9px;
}
.bar-inner {
	height: 100%; width: 0%; border-radius: 999px;
	background: linear-gradient(90deg, var(--acc), var(--cyan));
	transition: width .3s ease;
}

.prog { margin-top: 16px; }
.prog[hidden] { display: none !important; }
.prog-foot { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--fg-2); }
.prog-foot .pct { font-family: var(--mono); color: var(--fg); }
.prog-hint { margin: 8px 0 0; font-size: 12px; color: var(--fg-3); }

/* 折叠的上传区，默认收起，不抢主流程注意力 */
.upload-fold { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.upload-fold > summary {
	cursor: pointer; font-size: 13.5px; color: var(--fg-2);
	list-style: none; display: flex; align-items: center; gap: 7px;
}
.upload-fold > summary::-webkit-details-marker { display: none; }
.upload-fold > summary::before {
	content: "＋"; color: var(--acc-2); font-weight: 700; font-size: 15px;
}
.upload-fold[open] > summary::before { content: "－"; }
.upload-fold > summary:hover { color: var(--fg); }

/* 结果条上的时长 */
.dur { margin-left: auto; font-family: var(--mono); font-size: 13px; color: var(--fg-2); }

/* FAQ */
.faq details { border-bottom: 1px solid var(--line); }
.faq details:last-child { border-bottom: 0; }
.faq summary {
	cursor: pointer; padding: 13px 0; font-size: 14.5px; font-weight: 600;
	list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "＋"; color: var(--acc-2); font-weight: 700; flex: none; }
.faq details[open] summary::after { content: "－"; }
.faq details p { margin: 0 0 15px; color: var(--fg-2); font-size: 13.5px; }

/* 文本域占位符 */
textarea#text::placeholder { color: var(--fg-3); }

/* ==========================================================================
   Audio player: play/pause + seekable waveform
   ========================================================================== */

.player { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }

.btn-play {
	flex: none; width: 42px; height: 42px; border-radius: 50%; border: 0;
	background: linear-gradient(135deg, var(--acc), var(--acc-2));
	color: #fff; cursor: pointer; display: grid; place-items: center;
	box-shadow: 0 3px 14px var(--acc-glow); transition: .15s;
}
.btn-play:hover { transform: scale(1.06); }
.btn-play svg { width: 15px; height: 15px; }
/* 图标切换必须靠 class：SVG 元素没有 hidden 这个 IDL 属性 */
.btn-play #ic-pause { display: none; }
.btn-play.playing #ic-play { display: none; }
.btn-play.playing #ic-pause { display: block; }

/* 波形容器同时是 seek 轨道 */
.player .wave {
	flex: 1; min-width: 0; height: 58px; margin: 0;
	background: var(--bg-2); border: 1px solid var(--line);
	border-radius: var(--r-sm); overflow: hidden;
	cursor: pointer; touch-action: none;   /* 允许拖拽定位而不触发页面滚动 */
}
.player .wave:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.player .wave canvas { width: 100%; height: 100%; display: block; }

.time {
	flex: none; font-family: var(--mono); font-size: 12.5px;
	color: var(--fg-2); min-width: 82px; text-align: right;
}

/* ==========================================================================
   Microphone recorder
   ========================================================================== */

.rec-row { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; }

.btn-rec {
	display: inline-flex; align-items: center; gap: 9px;
	background: var(--bg-3); border: 1px solid var(--line-2); color: var(--fg);
	border-radius: var(--r-sm); padding: 10px 18px; font: inherit; font-size: 13.5px;
	cursor: pointer; transition: .15s;
}
.btn-rec:hover:not(:disabled) { border-color: var(--red); }
.btn-rec:disabled { opacity: .45; cursor: not-allowed; }

.btn-rec .rec-dot {
	width: 9px; height: 9px; border-radius: 50%; flex: none;
	background: var(--red);
}
/* 录制中：按钮转红并让圆点呼吸 */
.btn-rec.recording {
	background: rgba(248, 113, 113, .12);
	border-color: var(--red); color: var(--red);
}
.btn-rec.recording .rec-dot { animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.7); } }

.rec-info { font-size: 12.5px; color: var(--fg-3); font-family: var(--mono); }

/* “or” 分隔线 */
.or-line {
	display: flex; align-items: center; gap: 12px;
	margin: 14px 0 2px; color: var(--fg-3); font-size: 12px;
}
.or-line::before, .or-line::after {
	content: ""; flex: 1; height: 1px; background: var(--line);
}

/* ==========================================================================
   Toggle switch
   ========================================================================== */

.toggle {
	display: flex; align-items: flex-start; gap: 11px;
	margin-top: 14px; cursor: pointer; user-select: none;
}
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }

.toggle .tk {
	flex: none; width: 38px; height: 21px; border-radius: 999px;
	background: var(--bg-3); border: 1px solid var(--line-2);
	position: relative; transition: .18s; margin-top: 1px;
}
.toggle .tk::after {
	content: ""; position: absolute; top: 2px; left: 2px;
	width: 15px; height: 15px; border-radius: 50%;
	background: var(--fg-3); transition: .18s;
}
.toggle input:checked + .tk { background: var(--acc); border-color: var(--acc); }
.toggle input:checked + .tk::after { transform: translateX(17px); background: #fff; }
.toggle input:focus-visible + .tk { outline: 2px solid var(--acc-2); outline-offset: 2px; }

.toggle .tl { font-size: 13.5px; color: var(--fg-2); line-height: 1.45; }
.toggle .tl em {
	display: block; font-style: normal; font-size: 12px; color: var(--fg-3); margin-top: 2px;
}

/* ==========================================================================
   Advanced disclosure + Convert/Stop icon swap
   ========================================================================== */

.adv { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 12px; }
.adv > summary {
	cursor: pointer; font-size: 13px; color: var(--fg-3);
	list-style: none; display: flex; align-items: center; gap: 7px;
}
.adv > summary::-webkit-details-marker { display: none; }
.adv > summary::before { content: "▸"; transition: transform .15s; display: inline-block; }
.adv[open] > summary::before { transform: rotate(90deg); }
.adv > summary:hover { color: var(--fg-2); }
.adv .slider-box { margin-top: 12px; }
.adv-hint { margin: 8px 0 0; font-size: 12px; color: var(--fg-3); line-height: 1.55; }

/* Convert 按钮在合成中变为停止 —— 同样用 class 切换，不用 SVG 的 hidden */
.btn-go .ic-halt { display: none; }
.btn-go.halt .ic-go { display: none; }
.btn-go.halt .ic-halt { display: inline-block; }
.btn-go.halt {
	background: linear-gradient(135deg, #b4443f, #d05a55);
	box-shadow: 0 4px 18px rgba(248, 113, 113, .3);
}

/* 滑杆下的联动说明 */
.sl-note { margin: 7px 0 0; font-size: 11.5px; color: var(--fg-3); line-height: 1.5; min-height: 17px; }

/* ==========================================================================
   Inline "Auto" switch inside a slider label
   ========================================================================== */

.sl-label { display: inline-flex; align-items: center; gap: 10px; }

.mini-toggle {
	display: inline-flex; align-items: center; gap: 5px;
	cursor: pointer; user-select: none;
	font-size: 11px; color: var(--fg-3);
}
.mini-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.mini-toggle .mt {
	width: 26px; height: 15px; border-radius: 999px; flex: none;
	background: var(--bg-3); border: 1px solid var(--line-2);
	position: relative; transition: .16s;
}
.mini-toggle .mt::after {
	content: ""; position: absolute; top: 2px; left: 2px;
	width: 9px; height: 9px; border-radius: 50%;
	background: var(--fg-3); transition: .16s;
}
.mini-toggle input:checked + .mt { background: var(--acc); border-color: var(--acc); }
.mini-toggle input:checked + .mt::after { transform: translateX(11px); background: #fff; }
.mini-toggle input:checked ~ span { color: var(--acc-2); }
.mini-toggle input:focus-visible + .mt { outline: 2px solid var(--acc-2); outline-offset: 2px; }

/* Auto 打开时把滑杆压暗，但仍可拖动 —— 一拖就自动关掉 Auto */
.slider-box.is-auto input[type=range] { opacity: .4; }
.slider-box.is-auto input[type=range]:hover { opacity: .7; }

/* ==========================================================================
   Export format picker
   ========================================================================== */

.fmt-select {
	background: var(--bg-3); border: 1px solid var(--line-2); color: var(--fg);
	border-radius: var(--r-sm); padding: 9px 11px; font: inherit; font-size: 13px;
	cursor: pointer; transition: .15s;
}
.fmt-select:hover:not(:disabled) { border-color: var(--acc); }
.fmt-select:focus-visible { outline: 2px solid var(--acc-2); outline-offset: 2px; }
.fmt-select:disabled { opacity: .45; cursor: not-allowed; }
.fmt-select option { background: var(--bg-2); color: var(--fg); }




/* ==========================================================================
   Content sections: how it works, features, uses

   These exist as much for readers as for crawlers — the tool itself says very
   little in text, and a page that is only an interactive widget has nothing
   for a search engine to rank.
   ========================================================================== */

.skip {
	position: absolute; left: -9999px; top: 0; z-index: 100;
	background: var(--acc); color: #fff; padding: 10px 16px;
	border-radius: 0 0 var(--r-sm) 0; font-size: 14px;
}
.skip:focus { left: 0; text-decoration: none; }

.steps, .feat-grid { display: grid; gap: 16px; }
.steps { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.feat-grid { grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); }

.step-card, .feat {
	background: var(--bg-1); border: 1px solid var(--line);
	border-radius: var(--r); padding: 20px 22px;
}
.step-card h3, .feat h3 {
	margin: 0 0 9px; font-size: 15.5px; font-weight: 700; letter-spacing: -.1px;
	display: flex; align-items: center; gap: 9px;
}
.step-card p, .feat p { margin: 0; font-size: 13.5px; color: var(--fg-2); line-height: 1.72; }

.step-card h3 .n {
	flex: none; display: grid; place-items: center;
	width: 24px; height: 24px; border-radius: 50%;
	background: linear-gradient(135deg, var(--acc), var(--acc-2));
	color: #fff; font-size: 12.5px; font-family: var(--mono);
}
.feat h3::before {
	content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%;
	background: var(--cyan); box-shadow: 0 0 8px var(--cyan);
}

.uses { margin-top: 16px; }
.uses h3 { margin: 0 0 10px; font-size: 14px; font-weight: 700; }
.uses ul {
	margin: 0; padding: 0; list-style: none;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 4px 22px;
}
.uses li { font-size: 13.5px; color: var(--fg-2); padding-left: 17px; position: relative; }
.uses li::before { content: "→"; position: absolute; left: 0; color: var(--acc-2); }

/* ==========================================================================
   Small screens

   Googlebot crawls mobile-first, so the phone layout is the one that gets
   judged. The header is the part that breaks first: five nav links plus the
   badge cannot share one 62px row.
   ========================================================================== */

@media (max-width: 620px) {
	.wrap { padding: 0 16px; }
	.hero { padding: 34px 0 28px; }
	.hero p.lede { font-size: 15.5px; }
	section { padding: 26px 0; }
	.stat { flex: 1 1 calc(50% - 12px); min-width: 0; padding: 11px 14px; }
	.card, .step-card, .feat { padding: 16px; }
	.voice-grid { max-height: 60vh; }
	.player { gap: 9px; }
	.time { font-size: 11.5px; }
}


/* ==========================================================================
   Site chrome — Audiofilter header, tools dropdown and footer

   Lifted verbatim from ../styles.css so this page's header behaves and looks
   exactly like the other tools' (same markup, same nav-menu.js, same
   breakpoints). Only the token bridge below is new: that file names its
   palette differently, so the names are aliased onto the tokens above rather
   than the colours being duplicated.
   ========================================================================== */

:root {
	--surface:   var(--bg-1);
	--surface-2: var(--bg-2);
	--text:      var(--fg);
	--muted:     var(--fg-2);
	/* Audiofilter calls its accent --green (it is purple) and its second
	   accent --coral (it is teal). Kept as-is so the copied rules work. */
	--green:     var(--acc);
	--coral:     var(--cyan);
	--max:       1180px;
}

a.brand { color: inherit; text-decoration: none; }
a.brand:hover { text-decoration: none; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(9, 11, 16, .92);
  border-bottom: 1px solid rgba(255,255,255,.08);
  backdrop-filter: blur(18px);
}
.nav-wrap {
  max-width: var(--max);
  height: 72px;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  align-items: center;
  /* Left-aligned: the nav sits directly beside the brand. `space-between`
     with three children pushed the nav into the middle of the header. */
  justify-content: flex-start;
  gap: 36px;
}
.brand { display: inline-flex; align-items: center; gap: 10px; font-size: 19px; font-weight: 700; }
.brand b { color: var(--green); font-weight: 700; }
.brand-mark { width: 30px; height: 30px; display: flex; gap: 2px; align-items: center; justify-content: center; background: var(--green); border-radius: 50%; }
.brand-mark i { width: 2px; background: #fff; display: block; border-radius: 1px; }
.brand-mark i:nth-child(1), .brand-mark i:nth-child(5) { height: 7px; }
.brand-mark i:nth-child(2), .brand-mark i:nth-child(4) { height: 13px; }
.brand-mark i:nth-child(3) { height: 18px; }
.desktop-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 9px;
  color: #babfbc;
  font-size: 13.5px;
}
.desktop-nav > a, .nav-menu-button {
  display: inline-flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 13px;
  border-radius: 6px;
  font-weight: 600; white-space: nowrap;
  transition: background .16s, color .16s;
}
.desktop-nav > a:hover, .nav-menu-button:hover,
.nav-menu:hover .nav-menu-button,
.nav-menu.open .nav-menu-button { background: var(--surface-2); color: var(--text); }
.nav-icon {
  flex: 0 0 auto; width: 15px; height: 15px; opacity: .75;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.desktop-nav > a:hover .nav-icon, .nav-menu-button:hover .nav-icon,
.nav-menu.open .nav-menu-button .nav-icon { opacity: 1; }
.desktop-nav a:hover { color: var(--text); }
.nav-tools { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.lang-toggle { width: 38px; height: 36px; border: 1px solid var(--line); background: transparent; color: var(--text); border-radius: 5px; cursor: pointer; font-size: 12px; font-weight: 700; }
.lang-toggle:hover { border-color: var(--green); color: var(--green); }
/* nowrap 和 flex:0 0 auto 都是必需的：.nav-action 是 .nav-tools 这个 flex
   容器里的项，默认可以被压到比内容还窄，于是按钮文字折成两行。
   注意这条规则在三份样式表里各有一份副本（根 styles.css、
   ai-noise-reducer/styles.css、ai-text-to-speech/assets/css/style.css）——
   2026-09-20 只改了根目录那份，消噪页和 TTS 页因此还在折行。改一处要改三处。 */
.nav-action {
  padding: 9px 15px; background: var(--green); color: #fff; border-radius: 6px; font-weight: 700; font-size: 14px;
  white-space: nowrap; flex: 0 0 auto;
}

/* ── Tools dropdown ──────────────────────────────────────────────────────── */
.nav-menu { position: relative; }
.nav-menu-button { border: 0; background: none; color: inherit; cursor: pointer;
  font-family: inherit; font-size: inherit; line-height: inherit; }
.nav-menu-button::after { content: ""; width: 6px; height: 6px; border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor; transform: rotate(45deg) translateY(-1px); transition: transform .18s; }
.nav-menu-button:hover, .nav-menu:hover .nav-menu-button { color: var(--text); }
.nav-menu.open .nav-menu-button::after { transform: rotate(225deg) translateY(-2px); }

.nav-menu-panel {
  position: absolute; top: calc(100% + 12px); left: -6px; z-index: 40;
  min-width: 288px; padding: 8px; margin: 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .16s, transform .16s, visibility .16s;
}
/* Hover covers the mouse, :focus-within covers keyboard tabbing, .open is the
   click toggle nav-menu.js adds for touch. */
.nav-menu:hover .nav-menu-panel,
.nav-menu:focus-within .nav-menu-panel,
.nav-menu.open .nav-menu-panel { opacity: 1; visibility: visible; transform: translateY(0); }
/* Keeps the pointer from falling through the gap under the button. */
.nav-menu::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 14px; }

.nav-menu-panel a { display: flex; gap: 12px; align-items: flex-start; padding: 11px 12px; border-radius: 6px; transition: background .15s; }
.nav-menu-panel a:hover { background: var(--surface-2); }
.nav-menu-panel a[aria-current="page"] { background: var(--surface-2); }
/* Fixed brand colours, not palette vars: each tool keeps the same dot colour
   on every page, matching the favicon. */
.nav-menu-dot { flex: 0 0 auto; width: 8px; height: 8px; margin-top: 6px; border-radius: 50%; }
.nav-menu-dot.vocal { background: #8a5cf6; }
.nav-menu-dot.noise { background: #b7f26c; }
.nav-menu-dot.tts { background: #11bfa7; }
.nav-menu-dot.convert { background: #f2a25c; }
.nav-menu-dot.voice { background: #e06c9f; }
.nav-menu-text { min-width: 0; }
.nav-menu-text strong { display: block; font-size: 14px; font-weight: 600; color: var(--text); }
.nav-menu-text > span { display: block; margin-top: 3px; color: var(--muted); font-size: 12.5px; line-height: 1.5; }

@media (max-width: 820px) {
  /* Fixed panel: `top` has to match the header height at this breakpoint
     (72px here, 64px below 640px) or it overlaps or floats away from the bar. */
  .nav-menu-panel { position: fixed; top: 72px; left: 12px; right: 12px; min-width: 0; }
}

@media (max-width: 640px) {
  .nav-menu-panel { top: 64px; }
}


.skip-link { position: absolute; left: 16px; top: -60px; z-index: 60; padding: 10px 16px; background: var(--green); color: var(--text); border-radius: 6px; font-weight: 700; font-size: 14px; transition: top .18s; }
.skip-link:focus { top: 16px; }
a:focus-visible, button:focus-visible, summary:focus-visible, input:focus-visible, label:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }

footer { max-width: var(--max); min-height: 160px; margin: 0 auto; padding: 50px 24px; display: grid; grid-template-columns: 1fr 1fr 1fr; align-items: center; color: var(--muted); font-size: 13px; }
footer p { text-align: center; }
footer > span { text-align: right; }
.footer-nav { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 24px; width: 100%; margin-top: 30px; padding-top: 24px; border-top: 1px solid var(--line); }
.footer-nav a:hover { color: var(--text); }

/* 页脚语言切换器。语言名一律用该语言自己的写法（Español 在任何页面上都是
   Español），所以这里不需要为不同语言留不同宽度。 */
.lang-switch { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 16px; width: 100%; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); font-size: 12.5px; }
.lang-switch a { color: var(--muted); }
.lang-switch a:hover { color: var(--text); }
.lang-switch a[aria-current] { color: var(--text); font-weight: 700; }

/* 页头语言下拉。结构与 Tools 菜单相同，只调面板宽度和按钮的字重 —— 语言名
   比工具名短得多，沿用 320px 的面板会留一大片空白。 */
.lang-menu .nav-menu-panel { min-width: 152px; width: auto; padding: 6px; }
.lang-menu .nav-menu-panel a { padding: 8px 10px; font-weight: 600; }
.lang-menu .nav-menu-panel a[aria-current] { color: var(--green); }
@media (max-width: 1024px) { .lang-menu .nav-menu-button { padding: 0 8px; } }

/* 页脚社交入口。footer 是三列网格，品牌/标语/版权占满第一行，这个 div
   自然落到第二行第一列（左对齐，和 lalal 的位置一致），.footer-nav 用
   grid-column: 1/-1 另起一行，互不干扰。窄屏时 footer 变单列居中，
   这里的 flex 让标签和图标继续并排。 */
.footer-follow { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.footer-follow > span { color: var(--muted); }
.footer-follow a { display: grid; place-items: center; width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 50%; color: var(--muted); transition: color .18s, border-color .18s; }
.footer-follow a:hover { color: var(--text); border-color: var(--text); }
.footer-follow svg { width: 15px; height: 15px; fill: currentColor; }

@media (max-width: 1024px) {
  .desktop-nav { font-size: 13px; }
  .desktop-nav > a, .nav-menu-button { padding: 0 11px; }
}

@media (max-width: 900px) {
  .step-list { grid-template-columns: 1fr; }
  .step-list li { min-height: 0; }
}

@media (max-width: 820px) {
  /* Keep the Tools dropdown reachable on touch. Hiding .desktop-nav wholesale
     also hid the menu button itself, so there was nothing left to tap — the
     panel styles below never got a chance to run. */
  .desktop-nav { display: flex; gap: 4px; }
  .desktop-nav > a { display: none; }
  .nav-menu-button { padding: 0 10px; }
}


/* The tool body below uses .wrap (max 1240px); the chrome uses --max (1180px).
   Align them so the header and the content share one gutter. */
.wrap { max-width: var(--max); }

/* Section kicker above the h1 — same rule as the other tool pages. */
.tool-kicker { margin: 0 0 12px; color: var(--coral); font-size: 12px; font-weight: 700; letter-spacing: 1.4px; }

/* Cross-tool link — same rule as the other tool pages. */

.cross-link { max-width: 820px; margin: 0 auto; padding: 0 24px 90px; display: flex; align-items: center; justify-content: center; gap: 18px; flex-wrap: wrap; text-align: center; }
.cross-link p { margin: 0; color: var(--muted); font-size: 14px; }
.cross-link a { display: inline-flex; align-items: center; gap: 10px; padding: 11px 17px; border: 1px solid var(--line); border-radius: 6px; font-weight: 700; font-size: 14px; }
.cross-link a:hover { border-color: var(--green); color: var(--green); }

@media (max-width: 640px) {
  .cross-link { padding: 0 18px 64px; }
}

/* ==========================================================================
   Centred layout, matching the other tool pages

   This tool's CSS came from a standalone site that laid everything out flush
   left. The rest of Audiofilter centres its page head, section heads and the
   tool shell inside fixed measures, so the same measures are applied here
   rather than inventing new ones:

     .tool-head   820px    page head
     .tool-intro  660px    intro paragraph
     .section-head 720px   section heading + sub-line
     .tool-shell  960px    the tool itself
     .faq-list    820px    FAQ
   ========================================================================== */

/* Page head */
.hero { max-width: 820px; margin: 0 auto; padding: 62px 0 34px; text-align: center; }
.hero p.lede { max-width: 660px; margin: 0 auto 26px; }
.stat-row { justify-content: center; }

/* Section heads — only the section-level ones. The `.sec-head` blocks nested
   inside a .card are the two numbered step labels inside the tool itself, and
   those stay flush left with the controls they belong to. */
section > .sec-head {
	flex-direction: column; align-items: center; gap: 8px;
	max-width: 720px; margin: 0 auto 22px; text-align: center;
}

/* The tool shell and the FAQ get the same measures as the other pages. */
.bench { max-width: 960px; margin: 0 auto; }
#faq .card.faq { max-width: 820px; margin: 0 auto; }

@media (max-width: 620px) {
	.hero { padding: 44px 0 26px; }
}
