Flutter Interview Questions and Answers 2026
Flutter is Google's UI toolkit for building natively compiled applications for mobile, web, desktop, and embedded from a single Dart codebase. Candidates...

What changed in 2026 drives
Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.
What I'd actually study for this
- 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
- 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
- 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
- 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken
Where most candidates trip up
The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.
Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.
Flutter is Google's UI toolkit for building natively compiled applications for mobile, web, desktop, and embedded from a single Dart codebase. Candidates report that widget lifecycle, state management (BLoC, Riverpod, Provider), Dart async programming, navigation with GoRouter, platform channels, and performance optimization are the most frequently tested topics in Flutter developer interviews. This guide covers 50 questions from fundamentals to advanced patterns. Confirm the Flutter SDK version and state management library used at your target company on their official careers portal.
Table of Contents
- Flutter and Dart Fundamentals
- Widgets and Layout
- State Management
- Navigation and Routing
- Async Programming
- Platform Integration
- Performance and Testing
- 5-Question Mock Test
- Frequently Asked Questions
Flutter and Dart Fundamentals
Q1. What is Flutter and how does it render UI differently from React Native? Easy
Flutter uses its own rendering engine (Skia/Impeller) to draw every pixel directly to the canvas. It does not use native platform widgets. React Native bridges JavaScript to native platform widgets (UIView on iOS, Android View on Android), relying on the platform's rendering.
| Aspect | Flutter | React Native |
|---|---|---|
| Rendering | Own engine (Skia/Impeller) | Native platform widgets |
| Language | Dart | JavaScript/TypeScript |
| UI consistency | Pixel-perfect across platforms | Platform-specific look |
| Bridge | None (compiled to native ARM) | JS Bridge / JSI |
| Hot reload | Yes | Yes |
| Performance | Near-native | Good (JSI), slower than Flutter |
Q2. What is the difference between StatelessWidget and StatefulWidget? Easy
// StatelessWidget: immutable, build() depends only on config
class GreetingCard extends StatelessWidget {
const GreetingCard({super.key, required this.name});
final String name;
@override
Widget build(BuildContext context) {
return Text('Hello, $name!');
}
}
// StatefulWidget: mutable state, calls setState() to rebuild
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(onPressed: _increment, child: const Text('+')),
],
);
}
}
Q3. Explain the Flutter widget tree, element tree, and render tree. Medium
Flutter maintains three parallel trees:
- Widget tree: immutable descriptions you write. Rebuilt cheaply on every
setState. - Element tree: mutable objects Flutter maintains between rebuilds. Each element holds a reference to its widget and its render object. Flutter reconciles the new widget tree with the existing element tree, reusing elements where the widget type and key match.
- Render tree:
RenderObjectinstances that perform layout, painting, and hit testing. Expensive to create; Flutter reuses them by updating properties when the element is retained.
// Widget tree rebuild is cheap (const constructors)
// Element tree reconciliation: O(n) with key matching
// Render tree update: only when layout/paint properties change
// Key usage ensures element reuse across reorders
ListView(
children: items.map((item) => ItemWidget(key: ValueKey(item.id), item: item)).toList()
)
Q4. What is the difference between hot reload and hot restart in Flutter? Easy
Hot reload injects updated source code into the running Dart VM and rebuilds the widget tree from the current state. State is preserved. Works for most widget/UI changes. Does not re-run main() or initState().
Hot restart restarts the entire app: re-runs main(), rebuilds all state from scratch, and re-executes all initialization logic. Required for: changes in global variables, static fields, initState(), platform channel code.
Q5. What are the key Dart features relevant to Flutter? Medium
// Null safety: compile-time guarantee
String? nullable = null; // nullable
String nonNull = 'required'; // non-nullable
String value = nullable ?? 'default';
// Named and optional parameters
void greet({required String name, int age = 0}) {}
void log(String message, [String? tag]) {}
// Mixins: reuse code across class hierarchies
mixin Serializable {
Map<String, dynamic> toJson();
// Can add state and methods
}
class User with Serializable { ... }
// Extension methods
extension StringUtils on String {
bool get isEmail => contains('@') && contains('.');
String capitalize() => '${this[0].toUpperCase()}${substring(1)}';
}
// Cascade notation
final button = ElevatedButton(onPressed: () {}, child: const Text('Go'))
..onPressed = handlePress; // not realistic, just showing cascade
// Spread operator
final combined = [...list1, ...list2, if (condition) extraItem];
Widgets and Layout
Q6. What is the difference between Row, Column, and Flex? Easy
Row and Column are fixed-axis versions of Flex. Row is Flex(direction: Axis.horizontal) and Column is Flex(direction: Axis.vertical). Use mainAxisAlignment for primary axis, crossAxisAlignment for secondary axis.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.star),
Expanded(child: Text('Title')), // takes remaining space
const Icon(Icons.more_vert),
],
)
// Flexible vs Expanded
// Expanded = Flexible(flex: 1, fit: FlexFit.tight)
// Flexible by default = fit: FlexFit.loose (can be smaller)
Row(
children: [
Flexible(child: Text('Can be smaller')),
Expanded(child: Text('Must fill remaining')),
],
)
Q7. What is the difference between Container and SizedBox? Easy
SizedBox sets a fixed width/height. It is lightweight (a RenderConstrainedBox). Container is a convenience widget that combines decoration (color, border, shadow), constraints, padding, margin, and child alignment. Container is more expensive when decorating; use SizedBox or Padding when you only need one property.
// Prefer SizedBox for spacing
const SizedBox(height: 16) // vertical gap
const SizedBox(width: 8) // horizontal gap
const SizedBox(width: 200, height: 50, child: Text('Fixed'))
// Container for decoration
Container(
width: 200,
height: 100,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 4)],
),
child: const Text('Card'),
)
Q8. What is the widget build lifecycle? Medium
For StatefulWidget, the State class lifecycle:
createState()- creates the State instanceinitState()- called once after State is inserted in tree; safe to call inherited widgets viacontextfor initial setupdidChangeDependencies()- called afterinitStateand when InheritedWidget changesbuild()- called to build UI; called after every setState/didChangeDependenciesdidUpdateWidget(oldWidget)- called when parent rebuilds with same type but new configdeactivate()- called when State is removed from tree (may be re-inserted)dispose()- called once when permanently removed; cancel subscriptions, dispose controllers
class MyWidget extends StatefulWidget { ... }
class _MyWidgetState extends State<MyWidget> {
late ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(_onScroll);
}
@override
void didUpdateWidget(MyWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.userId != oldWidget.userId) {
_fetchUser(widget.userId); // respond to prop change
}
}
@override
void dispose() {
_scrollController.dispose(); // prevent memory leak
super.dispose();
}
}
Q9. What are Keys in Flutter and why are they important? Medium
Keys help Flutter's reconciliation algorithm match old elements with new widgets, especially in lists where elements change position.
// Without keys: Flutter matches by position
// Removing first item → Flutter thinks all items shifted
// With ValueKey or ObjectKey
ListView(
children: users.map((user) =>
UserTile(key: ValueKey(user.id), user: user)
).toList()
)
// Key types
ValueKey('unique-string') // equality by value
ObjectKey(someObject) // equality by identity
UniqueKey() // always different (forces rebuild)
GlobalKey() // access State/context from anywhere
// GlobalKey: access child widget's state
final key = GlobalKey<FormState>();
Form(key: key, ...)
key.currentState?.validate()
Q10. Predict the output: Medium
class Parent extends StatefulWidget {
@override
State<Parent> createState() => _ParentState();
}
class _ParentState extends State<Parent> {
bool showA = true;
@override
Widget build(BuildContext context) {
return Column(
children: [
if (showA) const ColorBox(color: Colors.red)
else const ColorBox(color: Colors.blue),
ElevatedButton(
onPressed: () => setState(() => showA = !showA),
child: const Text('Toggle'),
),
],
);
}
}
class ColorBox extends StatefulWidget {
const ColorBox({super.key, required this.color});
final Color color;
@override
State<ColorBox> createState() => _ColorBoxState();
}
class _ColorBoxState extends State<ColorBox> {
int count = 0;
@override
Widget build(BuildContext context) => Text('$count');
}
What happens when Toggle is pressed?
Without keys: the element at position 0 is reused (type matches: ColorBox). The _ColorBoxState with count = 0 is preserved. The color prop changes to blue but count remains 0 (only widget.color changes, state stays).
With keys (ValueKey('red') vs ValueKey('blue')): Flutter detects a different key, deactivates and disposes the red element, creates a new blue element with a fresh _ColorBoxState (count = 0 again but for a new reason).
State Management
Q11. What is Provider and how does it work? Medium
Provider is a wrapper around InheritedWidget that makes it easier to propagate and consume state down the widget tree.
// 1. Define a ChangeNotifier model
class CartModel extends ChangeNotifier {
List<Item> _items = [];
List<Item> get items => _items;
int get total => _items.fold(0, (sum, item) => sum + item.price);
void add(Item item) {
_items.add(item);
notifyListeners(); // triggers rebuild of consumers
}
void remove(Item item) {
_items.remove(item);
notifyListeners();
}
}
// 2. Provide at the root
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartModel()),
Provider<AuthService>(create: (_) => AuthService()),
],
child: const MyApp(),
)
// 3. Consume
// context.watch: listen (rebuild on change)
final cart = context.watch<CartModel>();
Text('${cart.total}')
// context.read: read without listening (in callbacks)
ElevatedButton(
onPressed: () => context.read<CartModel>().add(item),
child: const Text('Add to cart'),
)
// Consumer widget
Consumer<CartModel>(
builder: (context, cart, child) => Text('${cart.items.length} items'),
)
Q12. What is BLoC pattern and how do you implement it? Medium
BLoC (Business Logic Component) takes events and produces states via streams.
// Events
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
// States
abstract class CounterState {
final int count;
const CounterState(this.count);
}
class CounterInitial extends CounterState { const CounterInitial() : super(0); }
class CounterChanged extends CounterState { const CounterChanged(super.count); }
// BLoC
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(const CounterInitial()) {
on<IncrementEvent>((event, emit) => emit(CounterChanged(state.count + 1)));
on<DecrementEvent>((event, emit) => emit(CounterChanged(state.count - 1)));
}
}
// UI
BlocProvider(
create: (_) => CounterBloc(),
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(children: [
Text('${state.count}'),
ElevatedButton(
onPressed: () => context.read<CounterBloc>().add(IncrementEvent()),
child: const Text('+'),
),
]);
},
),
)
Q13. What is Riverpod and how does it improve on Provider? Advanced
Riverpod fixes Provider's main issues: no BuildContext required, providers can be declared globally, compile-time safety, and better testability.
import 'package:flutter_riverpod/flutter_riverpod.dart';
// Provider (read-only)
final greetingProvider = Provider<String>((ref) => 'Hello World');
// StateProvider (simple mutable state)
final counterProvider = StateProvider<int>((ref) => 0);
// StateNotifierProvider (complex state)
class TodoNotifier extends StateNotifier<List<Todo>> {
TodoNotifier() : super([]);
void add(String text) => state = [...state, Todo(text)];
void toggle(int index) {
state = [
for (int i = 0; i < state.length; i++)
if (i == index) state[i].copyWith(done: !state[i].done)
else state[i]
];
}
}
final todoProvider = StateNotifierProvider<TodoNotifier, List<Todo>>(
(ref) => TodoNotifier()
);
// AsyncNotifierProvider (async state)
final usersProvider = AsyncNotifierProvider<UsersNotifier, List<User>>(
() => UsersNotifier()
);
// Consumer widget
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: Text('$count'),
);
}
}
Navigation and Routing
Q14. What is the difference between Navigator.push and GoRouter? Medium
Navigator.push is imperative: you manually push and pop routes. It does not support deep linking or URL-based routing by default.
GoRouter (the officially recommended package) is declarative, URL-driven, supports deep links, browser history, and named routes.
// Imperative (Navigator)
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const DetailPage(id: '123'))
);
Navigator.pop(context, result);
// GoRouter (declarative)
final router = GoRouter(
routes: [
GoRoute(path: '/', builder: (ctx, state) => const HomePage()),
GoRoute(
path: '/product/:id',
builder: (ctx, state) => ProductPage(id: state.pathParameters['id']!),
),
ShellRoute(
builder: (ctx, state, child) => ScaffoldWithNav(child: child),
routes: [
GoRoute(path: '/home', builder: (ctx, state) => const HomeTab()),
GoRoute(path: '/profile', builder: (ctx, state) => const ProfileTab()),
],
),
],
)
// Navigation
context.go('/product/123') // replace current
context.push('/product/123') // push (can pop back)
context.pop()
Q15. What are route guards / redirects in GoRouter? Advanced
final router = GoRouter(
redirect: (context, state) {
final isLoggedIn = ref.read(authProvider).isLoggedIn;
final isLoginRoute = state.matchedLocation == '/login';
if (!isLoggedIn && !isLoginRoute) return '/login';
if (isLoggedIn && isLoginRoute) return '/home';
return null; // no redirect
},
refreshListenable: ref.read(authProvider), // rebuild on auth change
routes: [ ... ],
)
Async Programming
Q16. What is the difference between Future and Stream in Dart? Medium
| Feature | Future | Stream |
|---|---|---|
| Values | Single value (or error) | Zero or more values over time |
| Subscription | .then() / await | .listen() / await for |
| Cancellation | No built-in | Yes (StreamSubscription.cancel) |
| Use case | One HTTP request, file read | WebSocket, file chunks, events |
// Future
Future<String> fetchUser(int id) async {
final response = await http.get(Uri.parse('/api/users/$id'));
return response.body;
}
// Stream
Stream<int> countUp(int max) async* {
for (int i = 0; i <= max; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
}
// Consuming stream
await for (final value in countUp(5)) {
print(value); // 0, 1, 2, 3, 4, 5 (one per second)
}
// StreamBuilder in Flutter
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('posts').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text('Error: ${snapshot.error}');
if (!snapshot.hasData) return const CircularProgressIndicator();
return ListView(
children: snapshot.data!.docs.map((doc) => PostTile(doc: doc)).toList()
);
},
)
Q17. What is Isolate in Dart and when do you use it? Advanced
Dart is single-threaded per isolate. Isolates are separate memory heaps with their own event loops, communicating only via message passing (no shared memory). Use isolates for CPU-intensive work that would block the UI thread.
import 'dart:isolate';
// Simple compute (Flutter's helper)
import 'package:flutter/foundation.dart';
// compute() runs a function in a new isolate
final result = await compute(parseJson, jsonString);
String parseJson(String json) {
// runs in isolate, won't block UI
return processLargeJson(json);
}
// Manual isolate for bidirectional communication
Future<void> runHeavyTask() async {
final receivePort = ReceivePort();
final isolate = await Isolate.spawn(heavyWork, receivePort.sendPort);
receivePort.listen((message) {
if (message is SendPort) {
message.send('start'); // send task to isolate
} else {
print('Result: $message');
receivePort.close();
isolate.kill();
}
});
}
void heavyWork(SendPort sendPort) {
final port = ReceivePort();
sendPort.send(port.sendPort);
port.listen((message) {
final result = performExpensiveComputation();
sendPort.send(result);
});
}
Platform Integration
Q18. What are Platform Channels and how do you use them? Advanced
Platform Channels allow Flutter to call native iOS (Swift/ObjC) and Android (Kotlin/Java) code.
// Flutter side
class BatteryService {
static const _channel = MethodChannel('com.example.app/battery');
static Future<int> getBatteryLevel() async {
try {
return await _channel.invokeMethod<int>('getBatteryLevel') ?? -1;
} on PlatformException catch (e) {
debugPrint('Failed: ${e.message}');
return -1;
}
}
}
// Android (MainActivity.kt)
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.app/battery"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler { call, result ->
if (call.method == "getBatteryLevel") {
val level = getBatteryLevel()
if (level != -1) result.success(level)
else result.error("UNAVAILABLE", "Battery not available", null)
} else {
result.notImplemented()
}
}
}
private fun getBatteryLevel(): Int {
val bm = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
return bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
}
}
Performance and Testing
Q19. What causes jank in Flutter and how do you prevent it? Advanced
Flutter targets 60fps (16ms per frame) or 120fps (8ms). Jank occurs when the frame budget is exceeded.
Common causes and fixes:
- Expensive builds: use
constconstructors,RepaintBoundary,ListView.builderinstead ofListViewwith all children - Unnecessary rebuilds: use
Consumerwith narrow scope,Selectorto filter Provider rebuilds - Heavy work on UI thread: move JSON parsing, image processing to
compute()/ isolates - Large images: use
Image.networkwithcacheWidth/cacheHeightto resize before decode
// const constructors skip rebuild
const Text('Static text') // never rebuilds
// ListView.builder: lazy creation
ListView.builder(
itemCount: 10000,
itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
)
// RepaintBoundary: isolate repaint
RepaintBoundary(
child: ComplexAnimatedWidget(), // won't trigger repaint of sibling widgets
)
// Use DevTools flame chart to identify long frames
// Use Widget Inspector to find unnecessary rebuilds
Q20. How do you write widget tests in Flutter? Medium
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Counter widget', () {
testWidgets('starts at 0 and increments', (WidgetTester tester) async {
// Build the widget
await tester.pumpWidget(const MaterialApp(home: Counter()));
// Verify initial state
expect(find.text('Count: 0'), findsOneWidget);
expect(find.text('Count: 1'), findsNothing);
// Tap the button
await tester.tap(find.byIcon(Icons.add));
await tester.pump(); // trigger rebuild
// Verify updated state
expect(find.text('Count: 1'), findsOneWidget);
});
testWidgets('shows error on network failure', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
userProvider.overrideWith((ref) => throw Exception('Network error'))
],
child: const MaterialApp(home: UserPage()),
),
);
await tester.pumpAndSettle();
expect(find.text('Network error'), findsOneWidget);
});
});
}
5-Question Mock Test
Q1. What is the difference between setState, Provider, BLoC, and Riverpod? When would you choose each?
Q2. Explain why const constructors matter for Flutter performance.
Q3. What is the widget lifecycle for a StatefulWidget? List the hooks in order and describe when each fires.
Q4. What is the output of this Dart code?
Future<void> main() async {
print('1');
await Future.delayed(Duration.zero);
print('2');
Future.delayed(Duration.zero).then((_) => print('3'));
print('4');
}
Q5. What are Platform Channels and when would you use them over a Flutter package?
Answers:
A1. setState for local, simple UI state. Provider for light DI and simple shared state. BLoC for complex event-driven flows with stream-based audit trail. Riverpod for compile-safe, testable global state without BuildContext. Riverpod is the modern default for most apps.
A2. const widgets are identical object references; Flutter's reconciler can skip rebuilding them entirely. Without const, every parent rebuild creates new widget instances even if nothing changed, triggering unnecessary element/render updates.
A3. createState → initState → didChangeDependencies → build → (didUpdateWidget → build)* → deactivate → dispose.
A4. Output: 1, then 2, then 4, then 3. await Future.delayed(Duration.zero) suspends until after the current microtask queue drains. .then() schedules 3 as a microtask after 4 has already printed synchronously.
A5. Platform Channels call native iOS/Android code from Dart. Use them when no Flutter package exists for a native API, when you need access to hardware features, or when a native library provides better performance than available Dart alternatives.
Frequently Asked Questions
What is the best state management solution for Flutter in 2026?
Riverpod is the most commonly recommended solution for new projects. It addresses Provider's limitations (no BuildContext requirement, compile-time safety, better testability) while being less boilerplate-heavy than BLoC. BLoC remains strong for teams that prefer a strict event-driven architecture. Candidates report both appear in interviews at companies using Flutter in production.
How does Flutter differ from React Native for production apps?
Flutter renders its own UI via Skia/Impeller, guaranteeing pixel-perfect consistency across platforms. React Native uses platform-native widgets, matching the OS look and feel. Flutter generally achieves better performance for animation-heavy UIs; React Native benefits from native component behavior and a larger JavaScript ecosystem. The choice depends on design requirements and team expertise.
What is the Flutter 3 Impeller rendering engine?
Impeller is a new rendering backend replacing Skia in Flutter, designed to eliminate shader compilation jank (a common cause of dropped frames on first render). Impeller pre-compiles a smaller, fixed set of shaders at build time rather than compiling them on the fly during rendering. It became the default on iOS in Flutter 3.10 and on Android in Flutter 3.16.
What is the internal mesh of related topics?
- Dart Interview Questions 2026 - language fundamentals underlying Flutter
- React Native Interview Questions 2026 - compare cross-platform approaches
- Android Interview Questions 2026 - platform channels and native integration
- iOS Swift Interview Questions 2026 - Swift side of platform channels
Methodology applied to this articlelast verified 8 Jun 2026
- No fabricated salary numbers or success rates. If we quote a range, it's sourced.
- No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
- No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
topic cluster
More resources in Interview Questions
Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.
paid contributor programme
Sat this this year? Share your story, earn ₹500.
First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story with byline.
Submit your story →ready to practice?
Take a free timed mock test
Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.