feat(theme): a studyset's colour on all its screens, Vaia's deeper shades

Every screen of a studyset now washes its colour (its own or the nearest
above it), as Vaia does: studying it, its cards, writing a card, its
notes, its paths and steps, its dictionary. The router hands the colour
down from where it resolves the studyset (ScreenColor), so a screen's
TopGradient without a colour of its own takes it.

The dark tone is now a deep shade of the colour, 42 % of it over black
(cerise a maroon like Vaia's #4e0b23, cobalt a navy), instead of a mix
into the background; light mode keeps its tint. The wash reaches about
as far as the header (160 dp; a studyset 180, Home 360). From medium
windows on, the frame fades into the background 60 % of the way down,
and the wash inside its panel is half as strong, as the frame carries
the colour; screens over the tabs (studying, the card browser and
composer, Settings and Connect Claude) sit in the same frame and panel,
without the rail (TintFrame, FramedScreen). The study session's header
lies on the colour with an edge below it, its status bar styled to suit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-10 14:01:12 +02:00
commit 5f8fade41c
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -5,7 +5,11 @@ import 'package:halkyon_learn_flutter/src/core/dependencies/person_scope.dart';
import 'package:halkyon_learn_flutter/src/core/router/app_shell.dart';
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
import 'package:halkyon_learn_flutter/src/core/router/tab_visibility.dart';
import 'package:halkyon_learn_flutter/src/core/theme/brand.dart';
import 'package:halkyon_learn_flutter/src/core/theme/palette_color.dart';
import 'package:halkyon_learn_flutter/src/core/widget/found_by_id.dart';
import 'package:halkyon_learn_flutter/src/core/widget/screen_tint.dart';
import 'package:halkyon_learn_flutter/src/core/widget/tinted_frame.dart';
import 'package:halkyon_learn_flutter/src/feature/assistant/widget/connect_claude_screen.dart';
import 'package:halkyon_learn_flutter/src/feature/auth/widget/profile_screen.dart';
import 'package:halkyon_learn_flutter/src/feature/card/bloc/card_composer_bloc.dart';
@ -30,6 +34,7 @@ import 'package:halkyon_learn_flutter/src/feature/study/bloc/study_session_bloc.
import 'package:halkyon_learn_flutter/src/feature/study/model/study_focus.dart';
import 'package:halkyon_learn_flutter/src/feature/study/widget/study_screen.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_tree.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/library_screen.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_language_scope.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_screen.dart';
@ -168,20 +173,22 @@ GoRouter buildRouter({String initialLocation = RoutePaths.home}) => GoRouter(
return _inStudyset(
context,
studysetId,
(studyset, _) => BlocProvider(
create: (context) => StudySessionBloc(
person.studysets,
person.cards,
person.cardDeletions,
person.reviews,
person.tags,
person.settings,
studysetId,
focus: StudyFocus.fromQuery(state.uri.queryParameters),
)..add(const StudySessionEventStarted()),
child: StudyScreen(
studysetId: studysetId,
title: studyset.content.title,
(studyset, _) => FramedScreen(
child: BlocProvider(
create: (context) => StudySessionBloc(
person.studysets,
person.cards,
person.cardDeletions,
person.reviews,
person.tags,
person.settings,
studysetId,
focus: StudyFocus.fromQuery(state.uri.queryParameters),
)..add(const StudySessionEventStarted()),
child: StudyScreen(
studysetId: studysetId,
title: studyset.content.title,
),
),
),
);
@ -194,10 +201,12 @@ GoRouter buildRouter({String initialLocation = RoutePaths.home}) => GoRouter(
builder: (context, state) => _inStudyset(
context,
state.pathParameters['studysetId']!,
(studyset, all) => CardBrowserScreen(
studyset: studyset,
all: all,
subtree: state.uri.queryParameters['subtree'] == '1',
(studyset, all) => FramedScreen(
child: CardBrowserScreen(
studyset: studyset,
all: all,
subtree: state.uri.queryParameters['subtree'] == '1',
),
),
),
),
@ -231,11 +240,12 @@ GoRouter buildRouter({String initialLocation = RoutePaths.home}) => GoRouter(
),
GoRoute(
path: RoutePaths.settings,
builder: (context, state) => const SettingsScreen(),
builder: (context, state) => const FramedScreen(child: SettingsScreen()),
routes: [
GoRoute(
path: 'assistant',
builder: (context, state) => const ConnectClaudeScreen(),
builder: (context, state) =>
const FramedScreen(child: ConnectClaudeScreen()),
),
],
),
@ -325,7 +335,14 @@ Widget _inStudyset(
builder: (studyset, all) => StudysetLanguageScope(
studyset: studyset,
all: all,
child: builder(studyset, all),
// Every screen of a studyset washes its colour, its own or the nearest
// above it.
child: ScreenColor(
color:
PaletteColor.byName(colorNameOf(studyset.id, all))?.background ??
Brand.primary,
child: builder(studyset, all),
),
),
);
@ -353,13 +370,15 @@ Widget _composer(BuildContext context, String studysetId, {String? cardId}) {
return _inStudyset(
context,
studysetId,
(studyset, _) => BlocProvider(
create: (context) =>
CardComposerBloc(person.cards, person.tags, studysetId)
..add(const CardComposerEventStarted()),
child: CardComposerScreen(
studysetTitle: studyset.content.title,
initialCardId: cardId,
(studyset, _) => FramedScreen(
child: BlocProvider(
create: (context) =>
CardComposerBloc(person.cards, person.tags, studysetId)
..add(const CardComposerEventStarted()),
child: CardComposerScreen(
studysetTitle: studyset.content.title,
initialCardId: cardId,
),
),
),
);