diff --git a/docs/plan-redesign.md b/docs/plan-redesign.md
index 90a139c..1110bb6 100644
--- a/docs/plan-redesign.md
+++ b/docs/plan-redesign.md
@@ -330,7 +330,7 @@ src/routes/preview/tools/[id]/+page.svelte
`CATEGORIES`, `ToolCard`). Ссылки пока `#` (реальные `/preview/tools/[id]`
подключим на C12).
- [x] **[C11]** `/preview/demo` — зеркало воркспейса (4 шага + панель превью), статичный приёмочный стенд.
-- [ ] **[C12]** `/preview/tools/[id]` — раскладка gradient (settings-panel + preview-panel).
+- [x] **[C12]** `/preview/tools/[id]` — data-driven settings-panel + preview-panel (gradient live, остальные — плейсхолдер); `NumberField`, `entries()` для prerender, ToolCard-ссылки подключены.
- [ ] **[C13]** `/preview/tools/[id]` — раскладка background-remover (comparison-grid).
- [ ] **[C14]** step-cards для chain в tool-page.
diff --git a/web/eslint.config.js b/web/eslint.config.js
index 7982c99..26cf310 100644
--- a/web/eslint.config.js
+++ b/web/eslint.config.js
@@ -10,6 +10,20 @@ import tseslint from "typescript-eslint";
// включается на весь код (см. план-redesign §10, шаг 6).
const newCode = ["**/src/lib/components/kit/**", "**/src/routes/preview/**"];
+// Полные recommended-наборы — только на новый код (см. ниже, блок перед prettier).
+const jsRecommended = Array.isArray(js.configs.recommended)
+ ? js.configs.recommended
+ : [js.configs.recommended];
+const svelteRecommended = Array.isArray(svelte.configs["flat/recommended"])
+ ? svelte.configs["flat/recommended"]
+ : [svelte.configs["flat/recommended"]];
+// Svelte-рекомендации применяем только к .svelte-файлам нового кода, иначе
+// svelte-eslint-parser "съедает" обычные .ts в тех же папках (напр. +page.ts).
+const svelteFiles = [
+ "**/src/lib/components/kit/**/*.svelte",
+ "**/src/routes/preview/**/*.svelte",
+];
+
export default tseslint.config(
{
ignores: [
@@ -68,15 +82,10 @@ export default tseslint.config(
},
// Полные recommended-наборы — только на новый код.
...[
- ...(Array.isArray(js.configs.recommended)
- ? js.configs.recommended
- : [js.configs.recommended]),
- ...tseslint.configs.recommended,
- ...svelte.configs["flat/recommended"],
- ].map((cfg) => ({
- ...cfg,
- files: newCode,
- })),
+ ...jsRecommended.map((cfg) => ({ ...cfg, files: newCode })),
+ ...tseslint.configs.recommended.map((cfg) => ({ ...cfg, files: newCode })),
+ ...svelteRecommended.map((cfg) => ({ ...cfg, files: svelteFiles })),
+ ],
// В Svelte 5 пропсы деструктурируются через `let` (конвенция документации и
// наш AGENTS.md), поэтому prefer-const на них — ложноположительный.
diff --git a/web/src/lib/components/kit/NumberField.svelte b/web/src/lib/components/kit/NumberField.svelte
new file mode 100644
index 0000000..424e47d
--- /dev/null
+++ b/web/src/lib/components/kit/NumberField.svelte
@@ -0,0 +1,47 @@
+
+
+
{tool.description}
+