# 🌙 Уютная викторина — Calm Family Quiz Спокойная семейная игра-викторина в стиле «Своей игры», созданная для уютного вечера перед сном. Все смотрят на одно табло, ведущий управляет игрой, команда отвечает вместе — без таймеров, давления и спешки. ## 🚀 Запуск ```bash npm install npm run dev ``` Откройте адрес из консоли (обычно `http://localhost:5173`). ### Прочее ```bash npm run build # production-сборка npm run preview # предпросмотр сборки npm run check # проверка типов (svelte-check) ``` ## 🎮 Как играть 1. **Выбор набора** — выберите тему вопросов. 2. **Табло** — категории и карточки очков (100 / 200 / 300 / 500 / 1000). Чем дороже карточка, тем сложнее вопрос. 3. Ведущий открывает вопрос, затем «Показать ответ», и решает: - **Засчитать +N** — команде идут очки; - **Засчитать частично +N/2** — для «почти правильного» ответа ведущий может дать половину стоимости вопроса; - **Не засчитывать** — без очков, но вопрос закрыт. - Для обычных вопросов штрафов и минусов нет. 4. Иногда вместо обычного вопроса открывается **аукцион** — спецвопрос в стиле «Своей игры». Ведущий назначает ставку и открывает случайный вопрос, затем решает: - **Засчитать +N** — команде идут очки; - **Не засчитать** — с команды **снимается ставка**, но счёт не уходит в минус. Пока аукцион не разрешён, ведущий может его отменить и вернуться к табло без потерь. 5. У некоторых вопросов есть необязательная **подсказка** 💡. Ведущий может показать её по желанию. Если подсказка показана — ответ засчитывается только за половину стоимости: мягкая помощь без давления. 6. Для творческих вопросов (type `creative`) кнопка мягче: «Засчитать творческий ответ +N». 7. Сыгранный вопрос затемняется и больше не выбирается. 8. Когда сыграны все вопросы — экран результата с мягкой финальной фразой. Прогресс сохраняется автоматически — после перезагрузки игра продолжится с того же места. ## 🧩 Добавление нового набора вопросов Архитектура задумана так, чтобы наборы добавлялись без правок UI. **Структура набора:** ровно **5 категорий**, в каждой ровно **5 вопросов** с номиналами **100 / 200 / 300 / 500 / 1000** (от простого к сложному). Вопросы бывают `strict` (однозначный ответ) и `creative` (творческий). У вопроса может быть необязательное поле `optionalHint` — подсказка для ведущего. 1. Создайте файл `src/lib/question-sets/.ts`: ```ts import type { QuestionSet } from '$lib/types'; export const mySet: QuestionSet = { id: 'my-set', // уникальный title: 'Моя тема', description: 'Короткое описание', ageRange: '6+ лет', categories: [ { id: 'cat-1', // уникально в пределах набора title: 'Категория', questions: [ { id: 'q1', points: 100, question: '...', answer: '...', type: 'strict' }, { id: 'q2', points: 200, question: '...', answer: '...', optionalHint: '...', type: 'strict' }, { id: 'q3', points: 300, question: '...', answer: '...', type: 'strict' }, { id: 'q4', points: 500, question: '...', answer: '...', type: 'creative' }, { id: 'q5', points: 1000, question: '...', answer: '...', type: 'strict' } // ровно 5 вопросов с очками 100/200/300/500/1000 ] } // …ещё 4 категории (всего 5) ] }; ``` 2. Зарегистрируйте набор в `src/lib/question-sets/index.ts`: ```ts import { familyKnowledgeJourneySet } from './family-knowledge-journey'; import { mySet } from './my-set'; export const questionSets = [familyKnowledgeJourneySet, mySet]; ``` Готово — набор автоматически появится на экране выбора. ## 🏗️ Архитектура Код аккуратно разделён по слоям: ``` src/ ├─ lib/ │ ├─ types.ts # Доменные типы (Question, Category, QuestionSet, GameState) │ ├─ question-sets/ # ДАННЫЕ (отделены от UI) │ │ ├─ family-knowledge-journey.ts # набор вопросов │ │ └─ index.ts # реестр наборов + хелперы поиска │ ├─ stores/ │ │ └─ game.ts # СОСТОЯНИЕ игры (Svelte store + localStorage) │ └─ components/ # UI-компоненты │ ├─ QuestionSetSelector.svelte │ ├─ GameBoard.svelte │ ├─ QuestionCard.svelte │ ├─ ScorePanel.svelte │ ├─ QuestionModal.svelte │ ├─ HostControls.svelte │ ├─ GameResult.svelte │ └─ ConfirmDialog.svelte └─ routes/ ├─ +layout.svelte # подключение глобальных стилей ├─ +layout.ts # CSR-only (localStorage) └─ +page.svelte # оркестрация экранов ``` **Принципы:** - Данные вопросов полностью отделены от состояния и UI. - Состояние игры живёт в Svelte store с автосохранением в `localStorage` и восстанавливается после перезагрузки. - Очки берутся из данных вопроса — ничего не хардкодится в UI. - Никакого бэкенда, БД, авторизации, мультиплеера или редактора в MVP. ## 🎨 Стек - **SvelteKit + TypeScript** - **Tailwind CSS v4** (через `@tailwindcss/vite`) - Без тяжёлых UI-библиотек — только лёгкие зависимости. Лицензия: личный/семейный проект.