import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../models/syncretic_session_model.dart'; import '../models/history_entry_model.dart'; import '../models/word_model.dart'; import '../models/word_of_day_model.dart'; import '../services/ai_oracle_service.dart'; import '../services/day_numerology.dart'; import '../services/settings_repository.dart'; import '../services/word_of_the_day_service.dart'; import '../services/words_repository.dart'; import '../widgets/divination_instruction_modal.dart'; import '../widgets/gradient_star_badge.dart'; import 'symbol_detail_screen.dart'; class WordOfTheDayScreen extends StatefulWidget { final DateTime? initialDate; const WordOfTheDayScreen({super.key, this.initialDate}); @override State createState() => _WordOfTheDayScreenState(); } class _WordOfTheDayScreenState extends State with SingleTickerProviderStateMixin { final _service = WordOfTheDayService(); final _wordsRepo = WordsRepository(); final _aiService = AiOracleService(); final _settingsRepo = SettingsRepository(); late DateTime _selectedDate; late TextEditingController _diaryController; late TabController _tabController; bool _isLoadingAi = false; String? _aiAdvice; bool _isDiarySaved = false; @override void initState() { super.initState(); _selectedDate = widget.initialDate ?? DateTime.now(); _tabController = TabController(length: 3, vsync: this); final rec = _service.getRecord(_selectedDate); _diaryController = TextEditingController(text: rec.diaryNote); } @override void dispose() { _diaryController.dispose(); _tabController.dispose(); super.dispose(); } void _changeDate(DateTime newDate) { setState(() { _selectedDate = newDate; final rec = _service.getRecord(_selectedDate); _diaryController.text = rec.diaryNote; _aiAdvice = null; _isDiarySaved = false; }); } void _previousDay() { HapticFeedback.selectionClick(); _changeDate(_selectedDate.subtract(const Duration(days: 1))); } void _nextDay() { HapticFeedback.selectionClick(); _changeDate(_selectedDate.add(const Duration(days: 1))); } void _jumpToToday() { HapticFeedback.mediumImpact(); _changeDate(DateTime.now()); } Future _pickDate() async { final picked = await showDatePicker( context: context, initialDate: _selectedDate, firstDate: DateTime(2020), lastDate: DateTime(2035), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: const ColorScheme.dark( primary: Color(0xFFFFD54F), onPrimary: Color(0xFF151829), surface: Color(0xFF151829), onSurface: Color(0xFFE8EAF6), ), ), child: child!, ); }, ); if (picked != null) { _changeDate(picked); } } String _formatDateTitle(DateTime d) { final now = DateTime.now(); final isToday = d.year == now.year && d.month == now.month && d.day == now.day; final isYesterday = d.year == now.year && d.month == now.month && d.day == now.day - 1; final isTomorrow = d.year == now.year && d.month == now.month && d.day == now.day + 1; const months = [ 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' ]; final dateStr = '${d.day} ${months[d.month - 1]} ${d.year}'; if (isToday) return 'СЕГОДНЯ • $dateStr'; if (isYesterday) return 'ВЧЕРА • $dateStr'; if (isTomorrow) return 'ЗАВТРА • $dateStr'; return dateStr; } DayCode _dayCode() => DayNumerology.ofDate(_selectedDate); ReadingSignItem _dayCodeSign() { final code = _dayCode(); final linked = code.word.isEmpty ? null : _wordsRepo.getWordByName(code.word); return ReadingSignItem( title: 'Код суток: ${code.value}', subtitle: code.title, symbol: '${code.value}', lore: code.clause, linkedWord: linked, meta: { 'type': 'day_numerology', 'number': code.value, 'formula': code.formula, }, ); } void _openDayCodeWord() { final linked = _wordsRepo.getWordByName(_dayCode().word); if (linked == null) return; HapticFeedback.selectionClick(); Navigator.push( context, MaterialPageRoute(builder: (_) => SymbolDetailScreen(word: linked)), ); } Widget _buildDayCodeCard() { final code = _dayCode(); return Material( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(16), child: InkWell( borderRadius: BorderRadius.circular(16), onTap: _openDayCodeWord, child: Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.35)), ), child: Row( children: [ Container( width: 48, height: 48, alignment: Alignment.center, decoration: BoxDecoration( color: const Color(0xFF2A2412), borderRadius: BorderRadius.circular(12), ), child: Text( '${code.value}', style: const TextStyle( color: Color(0xFFFFD54F), fontSize: 20, fontWeight: FontWeight.w900, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'КОД СУТОК', style: TextStyle( color: Color(0xFFFFD54F), fontSize: 10, fontWeight: FontWeight.w800, letterSpacing: 0.8, ), ), const SizedBox(height: 2), Text( code.word.isEmpty ? code.title : '«${code.word}» · ${code.title}', style: const TextStyle(color: Color(0xFFFFF9C4), fontSize: 13, fontWeight: FontWeight.w700), ), const SizedBox(height: 2), Text( 'день ${code.reducedDay} · месяц ${code.reducedMonth} · год ${code.reducedYear}', style: const TextStyle(color: Color(0xFF8C93B8), fontSize: 11), ), ], ), ), const Icon(Icons.chevron_right_rounded, color: Color(0xFFFFD54F)), ], ), ), ), ); } Future _revealWord({String phase = 'main'}) async { HapticFeedback.heavyImpact(); await _service.revealWord(_selectedDate, phase: phase); setState(() {}); } Future _toggleStep(bool completed, {bool isDayStep = false}) async { HapticFeedback.mediumImpact(); await _service.toggleStepCompleted(_selectedDate, completed, isDayStep: isDayStep); setState(() {}); } Future _saveDiary() async { HapticFeedback.mediumImpact(); await _service.saveDiaryNote(_selectedDate, _diaryController.text); setState(() { _isDiarySaved = true; }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Row( children: [ GradientStar(size: 16), SizedBox(width: 8), Text('Синхронистическая заметка сохранена в летопись'), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } } Future _toggleMode(bool isTriptych) async { HapticFeedback.selectionClick(); await _service.setRecordTriptychMode(_selectedDate, isTriptych); await _service.setGlobalTriptychMode(isTriptych); setState(() {}); } Future _weaveIntoSyncreticSessionSingle(WordItem word) async { HapticFeedback.mediumImpact(); final reading = SyncreticReading( id: 'sod_${DateTime.now().millisecondsSinceEpoch}', systemId: 'word_of_day', systemName: 'Слово Дня', systemIcon: '☀️', timestamp: DateTime.now(), layoutTitle: 'Архетип Дня • ${_formatDateTitle(_selectedDate)}', inputMethod: 'calendar', items: [ ReadingSignItem( title: word.word.toUpperCase(), subtitle: word.category.isNotEmpty ? word.category : 'Слово Дня', symbol: word.emoji.isNotEmpty ? word.emoji : '☀️', lore: word.oracle.isNotEmpty ? word.oracle : word.cleanDescription, linkedWord: word, meta: { 'dateKey': WordOfTheDayService.formatDateKey(_selectedDate), 'core': word.core, 'asks': word.asks, 'step': word.step, }, ), _dayCodeSign(), ], ); await _wordsRepo.addReadingToSyncreticSession(reading); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ const GradientStar(size: 18), const SizedBox(width: 8), Expanded( child: Text('«${word.word.toUpperCase()}» вплетено в Сессию Дня!'), ), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } } Future _weaveTriptychIntoSyncreticSession( WordItem morning, WordItem day, WordItem evening, ) async { HapticFeedback.mediumImpact(); final reading = SyncreticReading( id: 'trip_${DateTime.now().millisecondsSinceEpoch}', systemId: 'word_of_day', systemName: 'Триптих Дня', systemIcon: '⏳', timestamp: DateTime.now(), layoutTitle: 'Триптих Суток (Утро • День • Вечер) • ${_formatDateTitle(_selectedDate)}', inputMethod: 'calendar_triptych', items: [ ReadingSignItem( title: '🌅 УТРО: ${morning.word.toUpperCase()}', subtitle: morning.category, symbol: morning.emoji.isNotEmpty ? morning.emoji : '🌅', lore: morning.core.isNotEmpty ? morning.core : morning.oracle, linkedWord: morning, ), ReadingSignItem( title: '⚡ ДЕНЬ: ${day.word.toUpperCase()}', subtitle: day.category, symbol: day.emoji.isNotEmpty ? day.emoji : '⚡', lore: day.step.isNotEmpty ? day.step : day.oracle, linkedWord: day, ), ReadingSignItem( title: '🌙 ВЕЧЕР: ${evening.word.toUpperCase()}', subtitle: evening.category, symbol: evening.emoji.isNotEmpty ? evening.emoji : '🌙', lore: evening.shadow.isNotEmpty ? evening.shadow : evening.oracle, linkedWord: evening, ), ], ); await _wordsRepo.addReadingToSyncreticSession(reading); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Row( children: [ GradientStar(size: 18), SizedBox(width: 8), Expanded( child: Text('Триптих дня (Утро, День, Вечер) вплетён в Сессию!'), ), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } } Future _consultOracleSingle(WordItem word) async { setState(() => _isLoadingAi = true); HapticFeedback.mediumImpact(); try { final promptQuestion = 'Слово Дня: «${word.word.toUpperCase()}». ${_dayCode().clause} Напутствие на день: как прожить этот архетип осознанно, не упав в тень?'; final advice = await _aiService.interpret( word: word, question: promptQuestion, positionTitle: 'Камертон дня', ); if (mounted) { setState(() { _aiAdvice = advice; _isLoadingAi = false; }); } } catch (e) { if (mounted) { setState(() => _isLoadingAi = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Ошибка связи с Оракулом: $e')), ); } } } Future _consultOracleTriptych( WordItem morning, WordItem day, WordItem evening, ) async { setState(() => _isLoadingAi = true); HapticFeedback.mediumImpact(); try { final promptQuestion = 'Триптих Дня: 🌅 Утро — «${morning.word.toUpperCase()}» (Архетип настройки); ' '⚡ День — «${day.word.toUpperCase()}» (Действие и вызов); ' '🌙 Вечер — «${evening.word.toUpperCase()}» (Тень и интеграция). ' '${_dayCode().clause} Дай синтез сюжета дня: как утреннее намерение воплотить в дневном поступке и осмыслить вечером?'; final advice = await _aiService.interpretSession( words: [ SessionWord.fromWordItem(morning, positionTitle: 'Утро (Камертон)'), SessionWord.fromWordItem(day, positionTitle: 'День (Действие)'), SessionWord.fromWordItem(evening, positionTitle: 'Вечер (Интеграция)'), ], question: promptQuestion, ); if (mounted) { setState(() { _aiAdvice = advice; _isLoadingAi = false; }); } } catch (e) { if (mounted) { setState(() => _isLoadingAi = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Ошибка связи с Оракулом: $e')), ); } } } void _shareSingle(WordItem word, WordOfDayRecord rec) { HapticFeedback.lightImpact(); final buf = StringBuffer(); buf.writeln('☀️ СЛОВО ДНЯ • ${_formatDateTitle(_selectedDate)}'); buf.writeln('🔢 Код суток: ${_dayCode().formula} · ${_dayCode().word}'); buf.writeln('Символ: ${word.emoji} ${word.word.toUpperCase()} (#${word.sessionNumber})'); if (word.category.isNotEmpty) buf.writeln('Категория: ${word.category}'); if (word.core.isNotEmpty) buf.writeln('\n🏛️ Архетип:\n${word.core}'); if (word.oracle.isNotEmpty) buf.writeln('\n🔮 Оракул:\n${word.oracle}'); if (word.asks.isNotEmpty) buf.writeln('\n🧘 Коан для ума:\n«${word.asks}»'); if (word.step.isNotEmpty) { buf.writeln('\n⚡ Практикум дня:\n${word.step}'); buf.writeln('Статус: ${rec.isStepCompleted ? "Выполнено ✓" : "В процессе"}'); } if (word.shadow.isNotEmpty) buf.writeln('\n🌑 Теневая ловушка:\n${word.shadow}'); if (rec.diaryNote.isNotEmpty) { buf.writeln('\n🪶 Дневник синхроний:\n${rec.diaryNote}'); } Clipboard.setData(ClipboardData(text: buf.toString())); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Row( children: [ GradientStar(size: 16), SizedBox(width: 8), Text('Карточка Слова Дня скопирована в буфер обмена'), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } void _shareTriptych( WordItem morning, WordItem day, WordItem evening, WordOfDayRecord rec, ) { HapticFeedback.lightImpact(); final buf = StringBuffer(); buf.writeln('⏳ ТРИПТИХ ДНЯ • ${_formatDateTitle(_selectedDate)}'); buf.writeln('🔢 Код суток: ${_dayCode().formula} · ${_dayCode().word}'); buf.writeln('\n🌅 УТРО — ${morning.emoji} ${morning.word.toUpperCase()} (#${morning.sessionNumber})'); if (morning.core.isNotEmpty) buf.writeln(' Архетип: ${morning.core}'); if (morning.asks.isNotEmpty) buf.writeln(' Коан: «${morning.asks}»'); buf.writeln('\n⚡ ДЕНЬ — ${day.emoji} ${day.word.toUpperCase()} (#${day.sessionNumber})'); if (day.step.isNotEmpty) buf.writeln(' Вызов дня: ${day.step}'); buf.writeln(' Статус: ${rec.isDayStepCompleted ? "Выполнено ✓" : "В процессе"}'); buf.writeln('\n🌙 ВЕЧЕР — ${evening.emoji} ${evening.word.toUpperCase()} (#${evening.sessionNumber})'); if (evening.shadow.isNotEmpty) buf.writeln(' Тень: ${evening.shadow}'); if (rec.diaryNote.isNotEmpty) { buf.writeln(' 🪶 Дневник синхроний: ${rec.diaryNote}'); } Clipboard.setData(ClipboardData(text: buf.toString())); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Row( children: [ GradientStar(size: 16), SizedBox(width: 8), Text('Триптих дня скопирован в буфер обмена'), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } @override Widget build(BuildContext context) { final record = _service.getRecord(_selectedDate); final isTriptych = record.isTriptychMode; final streak = _service.calculateStreak(); final isToday = WordOfTheDayService.formatDateKey(_selectedDate) == WordOfTheDayService.formatDateKey(DateTime.now()); final singleWord = _service.getWordForDate(_selectedDate, phase: 'main'); final triptych = _service.getTriptychWordsForDate(_selectedDate); return Scaffold( backgroundColor: const Color(0xFF0C0E1A), appBar: AppBar( title: Row( children: [ const GradientStar(size: 22), const SizedBox(width: 8), Text( isTriptych ? 'Триптих Дня' : 'Слово Дня', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18), ), ], ), actions: [ IconButton( tooltip: 'Выбрать дату', icon: const Icon(Icons.calendar_month_rounded, color: Color(0xFFFFD54F)), onPressed: _pickDate, ), IconButton( tooltip: 'Поделиться', icon: const Icon(Icons.share_rounded, color: Color(0xFFFFD54F)), onPressed: () { if (isTriptych) { _shareTriptych(triptych.morning, triptych.day, triptych.evening, record); } else { _shareSingle(singleWord, record); } }, ), IconButton( tooltip: 'Инструкция', icon: const Icon(Icons.info_outline_rounded, color: Color(0xFF8C93B8)), onPressed: () => DivinationInstructionModal.show(context, 'word_of_day'), ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(16, 4, 16, 32), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Date Navigation Header _buildDateBar(streak, isToday), const SizedBox(height: 12), _buildDayCodeCard(), const SizedBox(height: 12), // Mode Selector: 1 Word vs 3 Words Triptych _buildModeSelector(isTriptych), const SizedBox(height: 16), // Main Content: Single Word Mode OR Triptych Mode if (!isTriptych) ...[ _buildSingleWordBody(singleWord, record), ] else ...[ _buildTriptychBody(triptych.morning, triptych.day, triptych.evening, record), ], if (_isLoadingAi) ...[ const SizedBox(height: 16), const Center( child: Padding( padding: EdgeInsets.all(16.0), child: CircularProgressIndicator(color: Color(0xFFFFD54F)), ), ), ] else if (_aiAdvice != null) ...[ const SizedBox(height: 16), _buildAiAdviceCard(), ], ], ), ), ); } Widget _buildDateBar(int streak, bool isToday) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF232742)), ), child: Row( children: [ IconButton( icon: const Icon(Icons.chevron_left_rounded, color: Color(0xFFFFD54F)), onPressed: _previousDay, tooltip: 'Предыдущий день', ), Expanded( child: InkWell( onTap: _pickDate, borderRadius: BorderRadius.circular(8), child: Column( children: [ Text( _formatDateTitle(_selectedDate), textAlign: TextAlign.center, style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 13, fontWeight: FontWeight.w900, letterSpacing: 0.5, ), ), if (!isToday) GestureDetector( onTap: _jumpToToday, child: const Padding( padding: EdgeInsets.only(top: 2), child: Text( 'Вернуться к сегодня', style: TextStyle( color: Color(0xFF80DEEA), fontSize: 11, decoration: TextDecoration.underline, ), ), ), ), ], ), ), ), IconButton( icon: const Icon(Icons.chevron_right_rounded, color: Color(0xFFFFD54F)), onPressed: _nextDay, tooltip: 'Следующий день', ), if (streak > 0) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: const Color(0xFF332014), borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xFFFFB74D).withValues(alpha: 0.5)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text('🔥', style: TextStyle(fontSize: 13)), const SizedBox(width: 4), Text( '$streak', style: const TextStyle( color: Color(0xFFFFB74D), fontSize: 11.5, fontWeight: FontWeight.w900, ), ), ], ), ), ], ), ); } Widget _buildModeSelector(bool isTriptych) { return Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFF2A2D4A)), ), child: Row( children: [ Expanded( child: InkWell( onTap: () => _toggleMode(false), borderRadius: BorderRadius.circular(10), child: Container( padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: !isTriptych ? const Color(0xFF2C2248) : Colors.transparent, borderRadius: BorderRadius.circular(10), border: !isTriptych ? Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.6)) : null, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('☀️', style: TextStyle(fontSize: !isTriptych ? 14 : 12)), const SizedBox(width: 6), Text( 'Единый Камертон (1)', style: TextStyle( color: !isTriptych ? const Color(0xFFFFF9C4) : const Color(0xFF8C93B8), fontWeight: FontWeight.bold, fontSize: 12, ), ), ], ), ), ), ), const SizedBox(width: 4), Expanded( child: InkWell( onTap: () => _toggleMode(true), borderRadius: BorderRadius.circular(10), child: Container( padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: isTriptych ? const Color(0xFF2C2248) : Colors.transparent, borderRadius: BorderRadius.circular(10), border: isTriptych ? Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.6)) : null, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('⏳', style: TextStyle(fontSize: isTriptych ? 14 : 12)), const SizedBox(width: 6), Text( 'Триптих Суток (3)', style: TextStyle( color: isTriptych ? const Color(0xFFFFF9C4) : const Color(0xFF8C93B8), fontWeight: FontWeight.bold, fontSize: 12, ), ), ], ), ), ), ), ], ), ); } // ==================== 1-WORD MODE ==================== Widget _buildSingleWordBody(WordItem word, WordOfDayRecord record) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ if (!record.isRevealed) _buildUnrevealedSeal( title: 'ПЕЧАТЬ ДНЯ', desc: 'Время сегодня звучит уникальным архетипом. Слово дня задаёт главный камертон событий, мыслей и внутренних озарений.', buttonText: 'РАСПЕЧАТАТЬ СЛОВО ДНЯ', onTap: () => _revealWord(phase: 'main'), ) else _buildRevealedTalisman(word), if (record.isRevealed) ...[ const SizedBox(height: 20), Container( decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFF2A2D4A)), ), child: TabBar( controller: _tabController, indicatorColor: const Color(0xFFFFD54F), indicatorSize: TabBarIndicatorSize.tab, dividerColor: Colors.transparent, labelColor: const Color(0xFFFFD54F), unselectedLabelColor: const Color(0xFF8C93B8), labelStyle: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12), tabs: const [ Tab(icon: Icon(Icons.wb_twilight_rounded, size: 18), text: '1. Настройка'), Tab(icon: Icon(Icons.flash_on_rounded, size: 18), text: '2. Практикум'), Tab(icon: Icon(Icons.nights_stay_rounded, size: 18), text: '3. Синхронии'), ], ), ), const SizedBox(height: 14), AnimatedBuilder( animation: _tabController, builder: (context, _) { switch (_tabController.index) { case 0: return _buildMorningFocusTab(word); case 1: return _buildDailyPracticeTab(word, record); case 2: return _buildEveningDiaryTab(record); default: return const SizedBox.shrink(); } }, ), const SizedBox(height: 20), _buildActionRowSingle(word), ], ], ); } // ==================== 3-WORDS TRIPTYCH MODE ==================== Widget _buildTriptychBody( WordItem morning, WordItem day, WordItem evening, WordOfDayRecord record, ) { final areAllRevealed = record.areAllTriptychRevealed; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Triptych Header Banner Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration( color: const Color(0xFF1E1733), borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.3)), ), child: Row( children: [ const Icon(Icons.auto_awesome_motion_rounded, size: 18, color: Color(0xFFFFD54F)), const SizedBox(width: 8), const Expanded( child: Text( 'Сюжет суток: Утренний камертон ➔ Дневное действие ➔ Вечерняя интеграция', style: TextStyle(color: Color(0xFFFFF9C4), fontSize: 11.5, height: 1.3), ), ), if (!areAllRevealed) TextButton( style: TextButton.styleFrom( visualDensity: VisualDensity.compact, foregroundColor: const Color(0xFF80DEEA), ), onPressed: () => _revealWord(phase: 'all'), child: const Text('Открыть все', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 11)), ), ], ), ), const SizedBox(height: 14), // Phase 1: Morning _buildPhaseCard( phaseTitle: '1. УТРО • НАСТРОЙКА И АРХЕТИП', phaseIcon: '🌅', accentColor: const Color(0xFFFFD54F), word: morning, isRevealed: record.isMorningRevealed, onReveal: () => _revealWord(phase: 'morning'), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( morning.core.isNotEmpty ? morning.core : morning.description, style: const TextStyle(color: Color(0xFFECEFF1), fontSize: 13, height: 1.4), ), if (morning.asks.isNotEmpty) ...[ const SizedBox(height: 8), Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: const Color(0xFF261D3A), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFFBA68C8).withValues(alpha: 0.4)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.self_improvement_rounded, size: 16, color: Color(0xFFBA68C8)), const SizedBox(width: 8), Expanded( child: Text( 'Коан утра: «${morning.asks}»', style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 12, fontStyle: FontStyle.italic, ), ), ), ], ), ), ], ], ), ), const SizedBox(height: 14), // Phase 2: Day _buildPhaseCard( phaseTitle: '2. ДЕНЬ • ВЫЗОВ И ДЕЙСТВИЕ', phaseIcon: '⚡', accentColor: const Color(0xFF81C784), word: day, isRevealed: record.isDayRevealed, onReveal: () => _revealWord(phase: 'day'), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( day.step.isNotEmpty ? day.step : 'Воплотите импульс слова в конкретном материальном действии или осознанном поступке.', style: const TextStyle(color: Color(0xFFECEFF1), fontSize: 13, height: 1.4), ), const SizedBox(height: 12), SizedBox( width: double.infinity, child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: record.isDayStepCompleted ? const Color(0xFF2E7D32) : const Color(0xFF232A3E), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), icon: Icon( record.isDayStepCompleted ? Icons.check_circle_rounded : Icons.radio_button_unchecked_rounded, size: 18, color: record.isDayStepCompleted ? const Color(0xFFFFF9C4) : const Color(0xFF81C784), ), label: Text( record.isDayStepCompleted ? 'Дневной шаг выполнен ✓' : 'Отметить дневной шаг как выполненный', style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold), ), onPressed: () => _toggleStep(!record.isDayStepCompleted, isDayStep: true), ), ), ], ), ), const SizedBox(height: 14), // Phase 3: Evening _buildPhaseCard( phaseTitle: '3. ВЕЧЕР • ТЕНЬ И ИНТЕГРАЦИЯ', phaseIcon: '🌙', accentColor: const Color(0xFF80DEEA), word: evening, isRevealed: record.isEveningRevealed, onReveal: () => _revealWord(phase: 'evening'), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (evening.shadow.isNotEmpty) ...[ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: const Color(0xFF26191D), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFFFF7043).withValues(alpha: 0.4)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.warning_amber_rounded, size: 16, color: Color(0xFFFF7043)), const SizedBox(width: 8), Expanded( child: Text( 'Теневой капкан вечера: ${evening.shadow}', style: const TextStyle(color: Color(0xFFFFCCBC), fontSize: 12), ), ), ], ), ), const SizedBox(height: 12), ], _buildEveningDiaryTab(record), ], ), ), const SizedBox(height: 20), // Action Buttons for Triptych _buildActionRowTriptych(morning, day, evening), ], ); } Widget _buildPhaseCard({ required String phaseTitle, required String phaseIcon, required Color accentColor, required WordItem word, required bool isRevealed, required VoidCallback onReveal, required Widget content, }) { return Container( decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(18), border: Border.all( color: isRevealed ? accentColor.withValues(alpha: 0.6) : const Color(0xFF2A2D4A), width: isRevealed ? 1.5 : 1.0, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Bar Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration( color: accentColor.withValues(alpha: 0.08), borderRadius: const BorderRadius.vertical(top: Radius.circular(17)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Text(phaseIcon, style: const TextStyle(fontSize: 16)), const SizedBox(width: 8), Text( phaseTitle, style: TextStyle( color: accentColor, fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 0.8, ), ), ], ), if (isRevealed) TextButton.icon( style: TextButton.styleFrom( visualDensity: VisualDensity.compact, foregroundColor: const Color(0xFF80DEEA), padding: EdgeInsets.zero, ), icon: const Icon(Icons.arrow_forward, size: 14), label: const Text('Корень', style: TextStyle(fontSize: 11)), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => SymbolDetailScreen(word: word)), ); }, ), ], ), ), Padding( padding: const EdgeInsets.all(14), child: !isRevealed ? Center( child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: OutlinedButton.icon( style: OutlinedButton.styleFrom( foregroundColor: accentColor, side: BorderSide(color: accentColor.withValues(alpha: 0.6)), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), icon: const Icon(Icons.lock_open_rounded, size: 16), label: Text('Распечатать ($phaseTitle)'.split('•').first.trim(), style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12)), onPressed: onReveal, ), ), ) : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( word.emoji.isNotEmpty ? word.emoji : '✨', style: const TextStyle(fontSize: 26), ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( word.word.toUpperCase(), style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), Text( '#${word.formattedSessionNumber} • ${word.category} • ${word.localizedOperator}', style: const TextStyle(color: Color(0xFF8C93B8), fontSize: 11), ), ], ), ), ], ), const SizedBox(height: 12), content, ], ), ), ], ), ); } // ==================== SHARED WIDGETS ==================== Widget _buildUnrevealedSeal({ required String title, required String desc, required String buttonText, required VoidCallback onTap, }) { return Container( padding: const EdgeInsets.symmetric(vertical: 36, horizontal: 20), decoration: BoxDecoration( gradient: const RadialGradient( center: Alignment(0, -0.2), radius: 1.2, colors: [ Color(0xFF2E2452), Color(0xFF14172B), Color(0xFF0C0E1A), ], ), borderRadius: BorderRadius.circular(24), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.5), width: 1.5), boxShadow: [ BoxShadow( color: const Color(0xFFFFD54F).withValues(alpha: 0.15), blurRadius: 20, spreadRadius: 2, ), ], ), child: Column( children: [ Container( width: 80, height: 80, decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( colors: [Color(0xFFFFD54F), Color(0xFFFF8F00)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( color: const Color(0xFFFFD54F).withValues(alpha: 0.4), blurRadius: 16, spreadRadius: 2, ), ], ), child: const Icon( Icons.auto_awesome_rounded, color: Color(0xFF0C0E1A), size: 40, ), ), const SizedBox(height: 18), Text( title, style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 2.0, ), ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( desc, textAlign: TextAlign.center, style: const TextStyle(color: Color(0xFF8C93B8), fontSize: 13, height: 1.4), ), ), const SizedBox(height: 22), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFFFD54F), foregroundColor: const Color(0xFF0C0E1A), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 13), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), elevation: 6, ), icon: const Icon(Icons.lock_open_rounded, size: 20), label: Text( buttonText, style: const TextStyle(fontWeight: FontWeight.w900, letterSpacing: 0.8, fontSize: 13), ), onPressed: onTap, ), ], ), ); } Widget _buildRevealedTalisman(WordItem word) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF241B42), Color(0xFF14172B)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(24), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.6), width: 1.5), boxShadow: [ BoxShadow( color: const Color(0xFFFFD54F).withValues(alpha: 0.12), blurRadius: 18, spreadRadius: 2, ), ], ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: const Color(0xFF382959), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.4)), ), child: Text( 'ЗНАК #${word.sessionNumber.toString().padLeft(3, '0')}', style: const TextStyle( color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.w900, ), ), ), if (word.category.isNotEmpty) Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: const Color(0xFF1E243D), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFF80DEEA).withValues(alpha: 0.3)), ), child: Text( word.category, style: const TextStyle( color: Color(0xFF80DEEA), fontSize: 11, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 16), if (word.emoji.isNotEmpty) Text(word.emoji, style: const TextStyle(fontSize: 48)), const SizedBox(height: 6), Text( word.word.toUpperCase(), textAlign: TextAlign.center, style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 30, fontWeight: FontWeight.w900, letterSpacing: 2.0, ), ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildPill(word.partOfSpeech, const Color(0xFFB388FF)), const SizedBox(width: 8), _buildPill(word.localizedOperator, const Color(0xFF81C784)), const SizedBox(width: 8), _buildPill(word.localizedValence, const Color(0xFFFFB74D)), ], ), const SizedBox(height: 12), TextButton.icon( style: TextButton.styleFrom( foregroundColor: const Color(0xFF80DEEA), visualDensity: VisualDensity.compact, ), icon: const Icon(Icons.menu_book_rounded, size: 16), label: const Text('Открыть в полном справочнике корней', style: TextStyle(fontSize: 12)), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => SymbolDetailScreen(word: word)), ); }, ), ], ), ); } Widget _buildPill(String text, Color color) { if (text.isEmpty) return const SizedBox.shrink(); return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: color.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(8), border: Border.all(color: color.withValues(alpha: 0.4)), ), child: Text( text, style: TextStyle(color: color, fontSize: 10, fontWeight: FontWeight.bold), ), ); } Widget _buildMorningFocusTab(WordItem word) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildInfoCard( title: 'АРХЕТИП И СУТЬ', icon: Icons.hub_rounded, accentColor: const Color(0xFFFFD54F), content: word.core.isNotEmpty ? word.core : word.description, ), const SizedBox(height: 12), if (word.oracle.isNotEmpty) ...[ _buildInfoCard( title: 'ПОСЛАНИЕ ОРАКУЛА ДНЯ', icon: Icons.auto_awesome_rounded, accentColor: const Color(0xFF80DEEA), content: word.oracle, ), const SizedBox(height: 12), ], if (word.asks.isNotEmpty) ...[ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF252044), Color(0xFF181B30)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFBA68C8).withValues(alpha: 0.6)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(Icons.self_improvement_rounded, size: 18, color: Color(0xFFBA68C8)), SizedBox(width: 8), Text( 'КОАН ДЛЯ УМА (ВОПРОС ДНЯ)', style: TextStyle( color: Color(0xFFBA68C8), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ), const SizedBox(height: 10), Text( '«${word.asks}»', style: const TextStyle( color: Color(0xFFFFF9C4), fontSize: 14.5, fontStyle: FontStyle.italic, height: 1.45, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 8), const Text( 'Держите этот вопрос в фокусе внимания во время ключевых решений дня.', style: TextStyle(color: Color(0xFF8C93B8), fontSize: 11), ), ], ), ), ], ], ); } Widget _buildDailyPracticeTab(WordItem word, WordOfDayRecord rec) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(18), border: Border.all( color: rec.isStepCompleted ? const Color(0xFF81C784) : const Color(0xFFFFD54F).withValues(alpha: 0.5), width: rec.isStepCompleted ? 1.5 : 1.0, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Row( children: [ Icon(Icons.directions_run_rounded, size: 18, color: Color(0xFFFFD54F)), SizedBox(width: 8), Text( 'ВЫЗОВ И ПРАКТИКУМ ДНЯ', style: TextStyle( color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: rec.isStepCompleted ? const Color(0xFF1B3D23) : const Color(0xFF262A44), borderRadius: BorderRadius.circular(8), border: Border.all( color: rec.isStepCompleted ? const Color(0xFF81C784) : const Color(0xFF8C93B8).withValues(alpha: 0.4), ), ), child: Text( rec.isStepCompleted ? 'ВЫПОЛНЕНО ✓' : 'К ВЫПОЛНЕНИЮ', style: TextStyle( color: rec.isStepCompleted ? const Color(0xFF81C784) : const Color(0xFF8C93B8), fontSize: 10, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 12), Text( word.step.isNotEmpty ? word.step : 'Воплотите смысл слова в конкретном материальном поступке или осознанном отказе от автоматизма.', style: const TextStyle( color: Colors.white, fontSize: 14, height: 1.45, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: rec.isStepCompleted ? const Color(0xFF2E7D32) : const Color(0xFF2A2D4A), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), icon: Icon( rec.isStepCompleted ? Icons.check_circle_rounded : Icons.radio_button_unchecked_rounded, color: rec.isStepCompleted ? const Color(0xFFFFF9C4) : const Color(0xFFFFD54F), ), label: Text( rec.isStepCompleted ? 'Практика выполнена (Синхрония закреплена)' : 'Отметить шаг как выполненный', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13), ), onPressed: () => _toggleStep(!rec.isStepCompleted), ), ), ], ), ), const SizedBox(height: 14), if (word.shadow.isNotEmpty) ...[ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF1E1724), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFFF7043).withValues(alpha: 0.5)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(Icons.warning_amber_rounded, size: 18, color: Color(0xFFFF7043)), SizedBox(width: 8), Text( 'ТЕНЕВАЯ ЛОВУШКА ДНЯ', style: TextStyle( color: Color(0xFFFF7043), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ), const SizedBox(height: 8), Text( word.shadow, style: const TextStyle( color: Color(0xFFFFCCBC), fontSize: 13, height: 1.4, ), ), ], ), ), ], ], ); } Widget _buildEveningDiaryTab(WordOfDayRecord rec) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(18), border: Border.all(color: const Color(0xFF2A2D4A)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(Icons.edit_note_rounded, size: 20, color: Color(0xFF80DEEA)), SizedBox(width: 8), Text( 'ДНЕВНИК СИНХРОНИЙ И НАБЛЮДЕНИЙ', style: TextStyle( color: Color(0xFF80DEEA), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ), const SizedBox(height: 8), const Text( 'Зафиксируйте знаки, сны, диалоги или события, через которые слово дня проявилось в вашей жизни:', style: TextStyle(color: Color(0xFF8C93B8), fontSize: 12.5, height: 1.35), ), const SizedBox(height: 12), TextField( controller: _diaryController, maxLines: 4, style: const TextStyle(color: Colors.white, fontSize: 13.5), decoration: InputDecoration( hintText: 'Сегодня я заметил(а), что слово проявилось в...', hintStyle: const TextStyle(color: Color(0xFF636A8A), fontSize: 12.5), filled: true, fillColor: const Color(0xFF1B1E33), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF2C3252)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF2C3252)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF80DEEA)), ), ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (_isDiarySaved) const Row( children: [ Icon(Icons.check_circle_rounded, size: 16, color: Color(0xFF81C784)), SizedBox(width: 6), Text('Сохранено', style: TextStyle(color: Color(0xFF81C784), fontSize: 12)), ], ) else const SizedBox.shrink(), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF80DEEA), foregroundColor: const Color(0xFF0C0E1A), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), icon: const Icon(Icons.save_rounded, size: 16), label: const Text('Сохранить заметку', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12)), onPressed: _saveDiary, ), ], ), ], ), ); } Widget _buildActionRowSingle(WordItem word) { final persona = _settingsRepo.persona; return Row( children: [ Expanded( child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF262042), foregroundColor: const Color(0xFFFFF9C4), padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), side: BorderSide(color: const Color(0xFFFFD54F).withValues(alpha: 0.4)), ), ), icon: const Icon(Icons.psychology_rounded, size: 18, color: Color(0xFFFFD54F)), label: Text( 'Оракул (${persona.title.split(' ').first})', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), onPressed: () => _consultOracleSingle(word), ), ), const SizedBox(width: 10), Expanded( child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF1E283D), foregroundColor: const Color(0xFF80DEEA), padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), side: BorderSide(color: const Color(0xFF80DEEA).withValues(alpha: 0.4)), ), ), icon: const Icon(Icons.merge_rounded, size: 18), label: const Text( 'В Сессию Дня', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), onPressed: () => _weaveIntoSyncreticSessionSingle(word), ), ), ], ); } Widget _buildActionRowTriptych(WordItem morning, WordItem day, WordItem evening) { final persona = _settingsRepo.persona; return Row( children: [ Expanded( child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF262042), foregroundColor: const Color(0xFFFFF9C4), padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), side: BorderSide(color: const Color(0xFFFFD54F).withValues(alpha: 0.4)), ), ), icon: const Icon(Icons.psychology_rounded, size: 18, color: Color(0xFFFFD54F)), label: Text( 'Синтез Триады (${persona.title.split(' ').first})', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), onPressed: () => _consultOracleTriptych(morning, day, evening), ), ), const SizedBox(width: 10), Expanded( child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF1E283D), foregroundColor: const Color(0xFF80DEEA), padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), side: BorderSide(color: const Color(0xFF80DEEA).withValues(alpha: 0.4)), ), ), icon: const Icon(Icons.merge_rounded, size: 18), label: const Text( 'Вплести Триаду', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), onPressed: () => _weaveTriptychIntoSyncreticSession(morning, day, evening), ), ), ], ); } Widget _buildAiAdviceCard() { final persona = _settingsRepo.persona; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF1A1C30), borderRadius: BorderRadius.circular(18), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.5)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const GradientStar(size: 16), const SizedBox(width: 8), Expanded( child: Text( 'НАСТАВЛЕНИЕ: ${persona.title.toUpperCase()}', style: const TextStyle( color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.w900, ), ), ), ], ), const SizedBox(height: 10), Text( _aiAdvice!, style: const TextStyle( color: Color(0xFFECEFF1), fontSize: 13, height: 1.45, ), ), ], ), ); } Widget _buildInfoCard({ required String title, required IconData icon, required Color accentColor, required String content, }) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF2A2D4A)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, size: 16, color: accentColor), const SizedBox(width: 8), Text( title, style: TextStyle( color: accentColor, fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ), const SizedBox(height: 10), Text( content, style: const TextStyle( color: Color(0xFFECEFF1), fontSize: 13.5, height: 1.4, ), ), ], ), ); } }