Repository navigation
Feat 2026 Rebrand - #244
Open
NewtonMutugi wants to merge 47 commits into
Open
NewtonMutugi wants to merge 47 commits into
NewtonMutugi wants to merge 47 commits into
Conversation
…button to sign-in screen
…logos for app bar and sign-in screen
…heme dependencies
Android Studio now bundles JDK 25, which Gradle 8.14 cannot run (it failed with 'Error resolving plugin dev.flutter.flutter-plugin-loader > 25.0.3'). Gradle 9.1+ supports Java 25; pinned to 9.5.1 because AGP 8.13.0 relies on a Gradle internal API removed in 9.6.0. Verified: flutter build apk --flavor development succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
chore(android): upgrade Gradle wrapper to 9.5.1 for JDK 25 support
…le 3.3.2 - flutter upgrade: 3.44.6 -> 3.47.3 (Dart 3.12.2 -> 3.13.3) - Moved isar_community/isar_community_flutter_libs/isar_community_generator off the 3.3.0-dev.3 prerelease pin onto stable 3.3.2. That prerelease transitively capped analyzer at <9.0.0, which crashed 'dart run build_runner build' on Dart 3.13's dot-shorthand syntax (Exception: Missing implementation of visitDotShorthandPropertyAccess). Stable 3.3.2 allows analyzer <11.0.0, letting freezed resolve to 3.2.5 and analyzer to 10.2.0, which understands the new syntax. This is the actual fix for the pr-check/release-apk 'build_runner' CI failures. - Regenerated pubspec.lock, analysis_options.yaml, and macos/Flutter/GeneratedPluginRegistrant.swift via flutter pub get / code generation under the new SDK. Verified: - dart run build_runner build --delete-conflicting-outputs: succeeds (was crashing before) - dart format --set-exit-if-changed lib test: clean - flutter analyze lib: 1 pre-existing warning, no errors - flutter build apk --flavor development --debug: succeeds Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
chore: upgrade Flutter SDK to 3.47.3, fix build_runner CI crash
- AGP 8.13.0 -> 9.4.0 and Kotlin Gradle plugin 2.2.20 -> 2.4.20, per
Flutter's deprecation warning that support for the old versions will
soon be dropped.
- AGP 9.4.0 requires Gradle >=9.6.0, so the wrapper is bumped
8.13.0-era 9.5.1 -> 9.7.1 to match (9.5.1 was previously the ceiling
because it was the last version AGP 8.13.0 tolerated).
- AGP 9.4.0 also removes support for getDefaultProguardFile('proguard-android.txt')
(it hardcodes -dontoptimize, which blocks R8 optimizations); switched
the release buildType to the '...-optimize.txt' variant it now requires.
Verified:
- flutter build apk --flavor development --debug: succeeds
- dart format --set-exit-if-changed lib test: clean
- flutter analyze lib: 1 pre-existing warning, no errors
Not included: migrating to Flutter's Built-in Kotlin (still warns that
several plugins - firebase_analytics, firebase_auth, firebase_core,
firebase_crashlytics, firebase_remote_config, share_plus - apply their
own Kotlin Gradle Plugin). That depends on upstream plugin releases,
not something this repo controls alone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
chore(android): upgrade AGP to 9.4.0, Kotlin to 2.4.20, Gradle to 9.7.1
flutter analyze treats warnings as fatal by default, so this warning was failing CI. It was previously masked by a build_runner crash (see #251) that aborted the pipeline before the analyze step's exit code mattered; once that crash was fixed, this became the new blocker. signInWithGoogle() returned Future.value(authResult.credential?.accessToken) from inside a try block without awaiting it, tripping unawaited_return_in_try_block. Removing the unneeded Future.value wrapper exposed a real, pre-existing type mismatch: the method's declared return type is Future<String> (non-nullable) but accessToken can be null. Fixed by throwing a Failure in that case, consistent with how the rest of the method already handles invalid auth states. Verified: - flutter analyze lib: no issues found (was 1 fatal warning) - dart format --set-exit-if-changed lib test: clean - No existing tests cover this method; project has no test/ files yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
fix(auth): resolve unawaited_return_in_try_block analyzer warning breaking CI
Initializes Claude Code project guidance (CLAUDE.md) and a docs/ directory aimed at AI coding agents: deeper reference material with file:line citations covering DI/state management, the Isar+Hive data layer and cache-first fetch pattern, per-feature breakdown, routing (including the missing auth guard and a stale globalNavigatorKey getter), the full auth flow (including the reviewer-bypass ghost sign-in), networking/error-mapping/flavor config (including a 60000-second Dio timeout typo and the fact all three flavors hit the same API domain), notifications, and exactly what each GitHub Actions workflow triggers on and does. docs/README.md asks agents to keep these files updated as the code they describe changes, rather than letting them go stale. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs/README.md already asked for this, but CLAUDE.md is the file guaranteed to load into every Claude Code session's context, so the instruction needed to live there too, stated as a requirement rather than a suggestion. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs: add CLAUDE.md and AI-agent architecture docs
Analyzed the flutterconKE web redesign (flutterconKE2024Web#23, and its dev branch design tokens/components) to ground a phased plan for porting the same rebrand to this app. Documents what's already aligned (primary/accent colors, the app-bar logo, bottom-nav accents all already match the web's tokens) versus the real gap (color ramps, rounded-card system, pill badges, stat-card color inversion, the licensed Rauschen B display font, halftone/duotone imagery, pill button language), plus the phase breakdown that will become GitHub sub-issues under #243. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs: add 2026 rebrand migration plan (#243)
…256) Foundation tokens for the 2026 flutterconKE rebrand (docs/design/REBRAND-PLAN.md), ported from the flutterconKE web repo's tailwind.config.js / globals.css on its dev branch. Nothing here is wired into an existing screen yet — this is deliberately inert until Phase 1+ adopts it. - AppColorRamps: full blue50-900/magenta50-900 ramps, matching the web's Figma-export values exactly. - Corners: extended with the rebrand's rounded-card scale (s16/s24/s32/s40) plus a pill/pillBorder/pillRadius trio for pill buttons and badges. - PillBadge: level (magenta) / format (blue) chip widget, matching SessionListCard.tsx's levelPill/formatPill exactly. - AppButtonStyles: primary/accent/outline pill ButtonStyle builders, matching .btn-primary/.btn-accent/.btn-outline. Opt-in — not wired into ThemeData's elevatedButtonTheme/outlinedButtonTheme defaults, since that would restyle every existing button as a side effect. - AppTextStyles.display: Montserrat Black stand-in for the licensed Rauschen B display font, pending the Phase 0b decision (flutterconKEApp#257). - InvertedPanelColors: a ThemeExtension encoding the two documented light/dark color-inversion panels (e.g. the About stat block), registered on both AppTheme.lightTheme()/darkTheme(). Verified: flutter analyze (clean), dart format (clean), full debug APK build succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…kens feat(theme): rebrand Phase 0 — design tokens
…258) (#264) Confirmed the app-bar/sign-in logo assets already pixel-match the web repo's new rebrand mark (rendered both to PNG and compared directly, light and dark variants) and that there are no stray pre-rebrand hardcoded colors anywhere in lib/ — every color reference already goes through ThemeColors. No asset or color-usage changes needed. sign_in.dart's only visible button is the auth_buttons package's GoogleAuthButton, which shouldn't be restyled (Google's own brand guidelines govern its shape); the ghost sign-in path is a hidden long-press gesture, not a visible button. So there was no real apply-pill-styles work available on that screen specifically. Applied Phase 0's pill language where a real opportunity existed instead: - FeedbackButton (app bar, visible on most screens): fixed 10px radius -> Corners.pillBorder - LogOutDialog: confirm button -> Corners.pillBorder (kept red; that's destructive-action semantics, not a rebrand color); cancel button -> AppButtonStyles.outline Left session_filter.dart's SegmentedButton/filter-panel buttons alone — that's session-filtering UI, not global chrome, and belongs with Phase 3's more thorough Sessions pass. Verified: flutter analyze (clean), dart format (clean), full debug APK build succeeds. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…utterconKEApp#257) Checked the droidconKE/private-fonts repo's own README for the actual license terms rather than assuming the web's build-time-fetch pattern would transfer cleanly. It doesn't: the license explicitly permits serving Rauschen B as a web font from droidcon's own infrastructure, and explicitly forbids committing it to a public repo or sharing it externally — but says nothing about bundling the file inside a distributed app binary. A compiled mobile app ships the font file inside every installed APK/IPA, trivially extractable by unzipping — a materially different distribution than serving over HTTPS from a server droidcon controls, and not something covered by the existing grant. Decision (confirmed with the repo owner): don't port this. Montserrat Black (AppTextStyles.display, shipped in Phase 0) is the permanent display font for this app, not a placeholder pending resolution. Revisiting this would need an explicit confirmation from whoever actually holds the Rauschen B license/usage rights (Out of the Dark or droidcon's brand team) that app-binary embedding is covered — not an inference from the web's existing, web-scoped grant. Updated docs/design/REBRAND-PLAN.md and the AppTextStyles doc comment accordingly; no functional code change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ision docs: rebrand Phase 0b — decide against porting Rauschen B
* feat(about): rebrand Phase 2 — home/about stat panel (closes flutterconKEApp#259) Ported the web's About-section 2x2 stat block (components/home/About.tsx on flutterconKE2024Web's dev branch) — same four values (3RD Fluttercon edition, 7th Droidcon edition, 230+ sessions delivered, 3,000+ attendees since 2018), same deliberate light/dark color inversion (black+magenta figures in light, magenta+ white figures in dark). Placement decision: the About screen, not Home. about_screen.dart already had an About headline + description paragraph structurally identical to the web's About section intro, so the stat block reads as a natural continuation of that content rather than a dashboard summary that fits Home. Left Home's hero-style header treatment out of scope — that's a distinct, larger visual question from the web's own Hero component, better handled on its own rather than folded into this stat-panel port. AboutStatsPanel (lib/features/about/widgets/about_stats_panel.dart) reads Phase 0's InvertedPanelColors extension and AppTextStyles.display rather than hardcoding the light/dark swap. Wired into about_screen.dart right after the existing intro text, before Organising Team. Verified visually, not just via analyze/build: ran the app on an emulator, navigated to the About screen, and confirmed both color-inversion states directly (toggled via adb shell cmd uimode night yes/no) — matches the web's design exactly in both modes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat(localization): update aboutFluttercon description for rebranding --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…loses flutterconKEApp#260) Ported the web's SessionListCard.tsx / SpeakerCard.tsx pattern (flutterconKE2024Web, dev branch, from PR #32) to both session card variants and the speaker grid/detail screens. - SessionTimeBadge (lib/features/sessions/ui/widgets/session_time_badge.dart): the rounded time-badge box, shared by both session card variants. - CompactViewCard: rebuilt from a ListTile to a custom layout matching SessionListCard.tsx exactly - rounded-4xl bordered card, SessionTimeBadge, level/format PillBadges (skipped for service sessions, matching the web's !is_serviceSession check), speaker names in primary color. - ScheduleViewCard: same rounded-4xl border + SessionTimeBadge + pill badges, added alongside its existing image banner and speaker- avatar row (kept - the web has no direct equivalent of this image-forward variant). - SpeakerDuotoneAvatar (lib/features/home/widgets/speaker_duotone_avatar.dart): grayscale+contrast ColorFiltered, then a second ColorFiltered with BlendMode.screen against blue (Flutter's equivalent of the web's mix-blend-screen over a bg-blue-600 backdrop), plus a CustomPainter dot overlay. Wired into SpeakerGridTile and SpeakerDetailsPage, NOT into the shared PersonnelWidget (also used for About-screen organisers, which don't get this speaker-specific treatment on the web either). - SpeakerGridTile also picked up the rounded-4xl bordered card shape. Verified: flutter analyze (clean), dart format (clean), full debug build succeeds. The session-card redesign (both view variants, light + dark mode) was confirmed visually on an emulator. The speaker duotone avatar is verified by code review + clean analyze/build only - the emulator's touch input stopped registering taps partway through this phase's verification pass (swipes still worked; recovery attempts didn't resolve it) - flagged in the plan doc as worth a manual look on a real device or fresh emulator. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…speakers feat(sessions,speakers): rebrand Phase 3 — session & speaker cards
…oses flutterconKEApp#261) (#269) Applied Phase 0's rounded-card/pill tokens across the remaining screens so nothing looks pre-rebrand next to the Sessions/Speakers screens from Phase 3. - SponsorsCard/OrganizersCard: outer card radius -> Corners.s24Border, inner logo tiles -> Corners.s16Border, border changed from dark-mode-only (transparent in light, primary in dark) to always-on, matching every other rebrand card. Added missing item spacing to SponsorsCard's horizontal tile list - it previously relied on the light-mode border being invisible to hide the lack of a gap; with an always-on border that would have made adjacent tiles look fused. - feed_screen.dart: each post wrapped in a Corners.s32Border-bordered card (replacing a bare divider-separated list); feed images moved from a Container with a borderRadius that was never actually clipping its child (BoxDecoration.borderRadius doesn't clip content - a pre-existing no-op) to a proper ClipRRect with Corners.s16Border. - feedback_screen.dart: submit button now uses AppButtonStyles.primary instead of a hand-rolled ElevatedButton.styleFrom. Also fixed its label color, previously colorScheme.surface (near-black in dark mode - dark text on a blue button background, a pre-existing low-contrast bug), to plain white matching the button style. - EmojiContainer: radius bumped to Corners.s16Border to match the rest of the card scale. - About/organiser cards: no change needed - organising_team.dart uses the shared PersonnelWidget (deliberately excluded from the speaker-only duotone treatment per Phase 3), and organising_team_details.dart has no card chrome to restyle. Verified: flutter analyze (clean), dart format (clean), full debug build succeeds. SponsorsCard/OrganizersCard confirmed visually on an emulator in both light and dark mode. The feed card restyle could not be visually confirmed - the test event's feed endpoint returned no data on this build, unrelated to this phase. The feedback button swap is verified by code review and clean analyze/build only, since it reuses the already-proven AppButtonStyles.primary. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…flutterconKEApp#262) Ran a full accessibility/contrast pass over every color pairing introduced by the rebrand (WCAG relative-luminance contrast ratio, not eyeballed) rather than just checking it looked fine. Fixed two real findings that were ours to fix without deviating from the web's shipped design: - PillBadge's format variant and SessionTimeBadge's light-mode text used flutterconBlue (blue700) text on blue50 background - 3.2:1, below the 4.5:1 AA threshold for this text size. Neither is a literal copy of one specific shipped web value for this exact pairing (they're independent component choices informed by the same palette), so swapped to blue800 from the same ramp - 5.1:1, passes AA, visually indistinguishable at a glance. Found and documented, but deliberately NOT changed, three contrast findings that are inherited from the shared design system and already shipped identically on the public website: - AppButtonStyles.primary (white on flutterconBlue, 3.4:1) - a direct copy of the web's .btn-primary. - InvertedPanelColors.dark (white on magenta, 3.1:1) - the explicit, documented color-inversion decision from the web. - Bottom-nav selected-item magenta on white (3.1:1) - predates this rebrand entirely. All three clear AA for large text (>=3:1) but not small/normal text. Fixing them would mean diverging from the web or from an explicit design decision, which defeats this migration's purpose - flagged for a design-system-level conversation instead of a unilateral patch. Also: - Dark-mode QA re-confirmed across Phase 2-4 deliverables (About stats inversion, session cards, sponsors/organisers cards) - all correct in both themes. - Responsive check: reasoned AboutStatsPanel's fixed-aspect-ratio grid (the component most likely to be fragile) through a 320dp device width budget - clears with margin even with its longest label wrapping to two lines. Not re-verified on an actual small-width emulator. - Removed ThemeColors.greyDarkThemeBackground (zero usages) and assets/images/flutterconke_logo.png (the pre-rebrand logo bitmap, unreferenced anywhere once the Flutter-blue SVG mark replaced it). Left unrelated pre-existing unused Corners scale entries alone - they predate this rebrand and aren't unused because of anything this migration did. - Checked docs/architecture.md and docs/data-layer.md against the current code - both still accurate, no updates needed. This closes out the 2026 flutterconKE rebrand migration (#243) - all phases shipped. Verified: flutter analyze (clean), dart format (clean), full debug build succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reported by the user: a Flutter debug overflow banner appeared pinned to the right edge of CustomAppBar on their physical device (1080x2400) across Home, Feed, and Sessions. Root cause: the fluttercon wordmark SVG has an intrinsic aspect ratio of ~5.8:1 (87x15 viewBox). At the app bar's fixed height: 32, it renders ~186dp wide - combined with FeedbackButton (127dp) + spacing (15dp) + UserProfileIcon (30dp), the title Row's fixed-width children sum to ~358dp before any padding, which is too tight on a device logical width in the ~400dp range. This was never visible on the large tablet-class emulator used throughout this rebrand's verification passes. Fix: wrap the logo in Flexible + FittedBox(fit: BoxFit.scaleDown), so it shrinks gracefully under space pressure instead of forcing its full intrinsic width and overflowing. No visual change on screens with enough room (which is every device tested so far, including the previous emulator) - this only kicks in when space is actually tight. Verified on the reporting user's own physical device (confirmed by matching screen resolution): rebuilt, reinstalled, and reproduced the fix working on Home, Feed, and Sessions - no overflow banner, logo scales down cleanly, Feedback pill and avatar unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…cally scaling The previous fix (Flexible + FittedBox) stopped the overflow but introduced a new problem, caught by the user: FeedbackButton renders as a zero-size SizedBox() on Home (selectedIndex == 0) but a real 127dp pill everywhere else, so the available width for the logo differed per tab - FittedBox shrank it more on Feed/About/Sessions than on Home, making the brand mark visibly different sizes depending which tab you were on. Replaced with a single fixed height: 24 (down from 32) on every tab. At this size the logo (~140dp wide at its 5.8:1 intrinsic aspect ratio) comfortably fits even the tightest case - Feed/About, with the full Feedback pill (127dp) + spacing (15dp) + avatar (30dp) - on the user's exact device (360dp logical width, confirmed via adb). Verified on the user's own physical device: rebuilt, reinstalled, confirmed the logo is now the same size on Home and Feed (the tightest tab) with no overflow banner on either. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Sessions tab's app bar crowded the logo together with the compact/schedule view-toggle icons and the Filter button, all squeezed into one toolbar-height row with no room to breathe - flagged by the user as looking crowded. - New SessionViewToolbar (lib/features/sessions/ui/widgets/session_view_toolbar.dart): a dedicated secondary toolbar living below the app bar, as the first header sliver in SessionsScreen's NestedScrollView. Holds the view toggle (now a proper pill-shaped segmented control using Corners.pillBorder, matching the rebrand's button language) and the Filter trigger (now an outlined pill button instead of bare grey text+icon). - CustomAppBar: removed the selectedIndex==2 special case entirely (onCompactTapped/onScheduleTapped/selectedScheduleIndex params gone) along with the now-unused SessionFilter/WoltModalSheet wiring that moved to SessionViewToolbar. The app bar is back to just logo + feedback + avatar on every tab, including Sessions - it had been the only tab hiding those to make room for the icons that just moved out, so this also makes all four tabs' app bars consistent with each other. Verified on the user's own device: app bar is no longer crowded, view toggle and filter both still function (confirmed switching to schedule view), no overflow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Feed screen's error state just rendered the raw API error message (e.g. literally 'Not found') as bare bold text pinned to the top-left of the screen, with no icon, heading, context, or way to retry - flagged by the user as a bad experience. The empty-posts state had the same problem, just plain centered text. New FeedStatusView (lib/features/feed/widgets/feed_status_view.dart): a centered icon in a soft brand-blue circle + bold title + muted message, with an optional retry button (AppButtonStyles.primary). Used for both cases: - Empty (no posts): dynamic_feed icon, 'No posts found' / 'Check back later for updates from the team.', no retry (nothing to retry - there's just nothing there yet). - Error: wifi_off icon, 'Couldn't load the feed' as the heading with the actual API error message underneath for context, and a 'Try again' button wired to fetchFeeds(forceRefresh: true). Added noPostsMessage/feedErrorTitle/tryAgain l10n strings. Verified on device: confirmed the error state renders correctly (this test event's feed endpoint genuinely has no data, so the error case was reproducible) and that Try Again correctly re-triggers the fetch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reported by the user with a logcat trace showing a 404 on the sessions schedule endpoint: the Sessions screen's BlocBuilder used state.maybeWhen(orElse: ..., loaded: ...) with no explicit error case, so a failed FetchGroupedSessionsCubit fetch fell into orElse and just showed the loading spinner forever instead of ever surfacing the failure. Audited every maybeWhen a fetch cubit's BlocBuilder uses and found two more instances of the identical bug (no error: branch at all, not even unstyled text) beyond the one reported: - SessionsScreen (full-page spinner, the one reported) - Home's SessionsCard (both the horizontal session-preview list and its small '+N' count badge) - About's OrganisingTeamView (the individual-organisers grid) All three now use the shared StatusView (promoted from Feed's feed_status_view.dart, since Sessions needed the identical icon + title + message + retry pattern - see the previous commit) in their error branch, each wired to that screen's own forceRefresh retry call. The '+N' badge is small/inline enough that a full StatusView would be visually heavy there, so it just hides instead of spinning forever - the main list below it already surfaces the error properly. Added sessionsErrorTitle/organisersErrorTitle l10n strings (feedErrorTitle/tryAgain already existed from the Feed fix). Verified: flutter analyze (clean), dart format (clean), full debug build succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reported by the user as 'No element issues' appearing on Home after
switching the dev event slug to fluttercon-ke-2026-222: that event's
sponsors are tiered platinum/bronze only, and SponsorsCard
unconditionally called sponsors.firstWhere((s) => s.sponsorType ==
SponsorType.gold) with no orElse - a Dart StateError ('Bad state: No
element') whenever no sponsor happens to be tier gold specifically.
Fixed by picking the featured sponsor dynamically: walk a tier
priority list (platinum > gold > silver > bronze > swag > startup >
venue) and feature whichever tier the event's sponsors actually have
the highest-ranking match for, instead of hardcoding 'gold'. Also
guards the now-empty-list edge case (renders nothing rather than
crashing) and renamed the confusingly-named nonPlatinumSponsors
variable (it filtered by gold, not platinum) to remainingSponsors.
Audited the rest of the codebase for the same unguarded
.firstWhere()/.first pattern - this was the only unsafe instance;
the others are either already guarded with orElse or operate on
collections Flutter guarantees are non-empty (e.g. SegmentedButton's
onSelectionChanged).
Verified on an emulator with the real fluttercon-ke-2026-222 event
data: Sponsors section now renders Flutter (platinum) as the
featured sponsor with Typesense below, no crash.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The new event's schedule API returns room ids as strings (e.g. "room-a") instead of numbers, which crashed the fromJson cast with "type 'String' is not a subtype of type 'num'" on both the Room model and its Isar-backed LocalRoom mirror. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace SponsorsCard's single-featured-logo-plus-scroll-row layout with
the web's tiered sections (dashed divider + tier label + logo card per
tier, matching flutterconKE2024Web's SponsorsList.tsx). Replace
OrganizersCard's bordered horizontal scroll strip with the web's pink
"Organised by" banner and white logo tile grid ("Our Community
Partners" on the web). Both now use StatusView for error states
instead of raw error text, for consistency with the rest of the app.
ResolvedImage gains optional height/width so callers can size logos
per-tier instead of relying on its screen-proportional default.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…& Highlights sections
Apply the web's blue-duotone photo treatment (SpeakerDuotoneAvatar) to
the shared PersonnelWidget, which the Home speaker preview and the
About screen's organising team grid both use — previously only the
full speaker list page had it, leaving speakers/organisers elsewhere
with plain photos. Centers and bolds the name/designation labels to
match.
Add two new Home sections mirroring the web homepage
(flutterconKE2024Web `dev` branch): "2026 Conf. Essentials" (a
gradient card with Panels/Workshops/Networking/Exhibitions icons plus
a "More Stacks. All Mobile." tech-logo strip) and "Conf. Highlights"
("Beyond the Sessions" / "Developer Days" cards), built from the SVGs
and images added for this.
Also includes the flutterConBanner asset swap (new 2026 banner image)
that was already staged for this same home_screen.dart/app_assets.dart
area.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Kotlin/Swift/AI/Flutter/DroidCon/React/FlutterCon.svg defined colors
via <defs><style>.cls-N{fill:#...}</style></defs> + class="cls-N",
which flutter_svg doesn't support (it only resolves presentation
attributes, not CSS class selectors) — every shape silently fell back
to black. Inlined each class's fill as a direct attribute and dropped
the now-unused <style> block, so the icons render in their actual
brand colors instead of black silhouettes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
fix(a11y): rebrand Phase 5 — polish, contrast fixes, cleanup
NewtonMutugi
marked this pull request as ready for review
October 13, 2026 22:31
Member
Author
|
@wangerekaharun @KendiJ |
…er layout control
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request introduces a major visual and branding update across the application, shifting the color palette and assets from the previous Droidcon theme to the new Fluttercon branding. It also updates some dependencies and improves navigation and asset handling. Below are the most important changes:
Branding and Visual Redesign:
blueDroidconColor,orangeDroidconColor, etc.) with new Fluttercon colors (flutterconBlue,flutterconMagenta) throughout the codebase, affecting app bars, buttons, icons, backgrounds, and text styles. (lib/core/theme/theme_colors.dart[1]lib/core/theme/theme_data.dart[2] [3]lib/common/widgets/app_bar/app_bar.dart[4] [5] [6]lib/common/widgets/app_bar/feedback_button.dart[7] [8]lib/common/widgets/app_bar/user_profile_icon.dart[9]lib/common/widgets/bottom_nav/bottom_nav_bar.dart[10]lib/common/widgets/personnel_widget.dart[11]lib/features/about/ui/organising_team_details.dart[12]lib/features/home/ui/speaker_details/speaker_details.dart[13]lib/features/home/widgets/search_bar.dart[14] [15]lib/features/home/widgets/sessions_card.dart[16]flutterConKeLogoand replaced with new SVG assetsflutterConLogoLightandflutterConLogoDarkfor light/dark theme support. Updated all logo usages to use these SVGs. (lib/common/utils/constants/app_assets.dart[1]lib/common/widgets/app_bar/app_bar.dart[2]lib/features/auth/ui/sign_in.dart[3]scaffoldBackgroundColorfrom the theme for better consistency. (lib/common/widgets/app_bar/app_bar.dart[1]lib/common/widgets/bottom_nav/bottom_nav_bar.dart[2]lib/features/about/ui/about_screen.dart[3]lib/features/auth/ui/sign_in.dart[4]Navigation Improvements:
pushNamedinstead ofgoNamedfor sign-in routes, ensuring proper navigation stack behavior. (lib/common/widgets/app_bar/feedback_button.dart[1]lib/common/widgets/app_bar/user_profile_icon.dart[2]lib/features/auth/ui/sign_in.dartlib/features/auth/ui/sign_in.dartL48-R60)Dependency and Build System Updates:
android/gradle/wrapper/gradle-wrapper.propertiesandroid/gradle/wrapper/gradle-wrapper.propertiesL6-R6)android.builtInKotlin=false,android.newDsl=false) to the Gradle properties. (android/gradle.propertiesandroid/gradle.propertiesR6-R9)Code and Dependency Injection Maintenance:
generateForDir: ['lib']argument from the@InjectableInitannotation in the dependency injection setup. (lib/core/di/injectable.dartlib/core/di/injectable.dartL9-R9)These changes collectively modernize the app’s appearance and branding, improve navigation, and keep dependencies up to date
Type of Change
Issues
Test Changes on Device
You can download your APK from Firebase App Distribution once this PR builds successfully via the following link: https://appdistribution.firebase.dev/i/c796669942f8a811
Screenshots
Light mode
Dark mode