diff --git a/cspell.json b/cspell.json
index f0fd2ae..87a4005 100644
--- a/cspell.json
+++ b/cspell.json
@@ -34,6 +34,7 @@
"Filterscript",
"fontsource",
"Frege",
+ "gaugecomponent",
"Genshi",
"GLSL",
"goldens",
diff --git a/src/content/docs/examples/airplane_entertainment_system.mdx b/src/content/docs/examples/airplane_entertainment_system.mdx
index 342b245..1d21407 100644
--- a/src/content/docs/examples/airplane_entertainment_system.mdx
+++ b/src/content/docs/examples/airplane_entertainment_system.mdx
@@ -12,10 +12,10 @@ The Airplane Entertainment System simulates an in-flight entertainment system th
-The source code for this project is available on [GitHub](https://github.com/VGVentures/airplane_entertainment_system). To view the live demo, click [here](https://cuddly-doodle-kgvmnp1.pages.github.io/).
+The source code for this project is available on [GitHub](https://github.com/VGVentures/airplane_entertainment_system). To view the live demo, click [here](https://vgventures.github.io/airplane_entertainment_system/).
## Architecture
diff --git a/src/content/docs/examples/images/gauge.png b/src/content/docs/examples/images/gauge.png
new file mode 100644
index 0000000..96b7ea6
Binary files /dev/null and b/src/content/docs/examples/images/gauge.png differ
diff --git a/src/content/docs/examples/images/gauge_progress.png b/src/content/docs/examples/images/gauge_progress.png
new file mode 100644
index 0000000..569a57f
Binary files /dev/null and b/src/content/docs/examples/images/gauge_progress.png differ
diff --git a/src/content/docs/examples/images/gauge_ring.png b/src/content/docs/examples/images/gauge_ring.png
new file mode 100644
index 0000000..b876c7e
Binary files /dev/null and b/src/content/docs/examples/images/gauge_ring.png differ
diff --git a/src/content/docs/examples/images/gauge_rpm_numbers.png b/src/content/docs/examples/images/gauge_rpm_numbers.png
new file mode 100644
index 0000000..dd03359
Binary files /dev/null and b/src/content/docs/examples/images/gauge_rpm_numbers.png differ
diff --git a/src/content/docs/examples/images/gear.png b/src/content/docs/examples/images/gear.png
new file mode 100644
index 0000000..2cb4005
Binary files /dev/null and b/src/content/docs/examples/images/gear.png differ
diff --git a/src/content/docs/examples/images/speedometer.png b/src/content/docs/examples/images/speedometer.png
new file mode 100644
index 0000000..d82696c
Binary files /dev/null and b/src/content/docs/examples/images/speedometer.png differ
diff --git a/src/content/docs/examples/images/vehicle_cockpit.png b/src/content/docs/examples/images/vehicle_cockpit.png
new file mode 100644
index 0000000..8211a0b
Binary files /dev/null and b/src/content/docs/examples/images/vehicle_cockpit.png differ
diff --git a/src/content/docs/examples/vehicle_cockpit.mdx b/src/content/docs/examples/vehicle_cockpit.mdx
index cbaf383..c758099 100644
--- a/src/content/docs/examples/vehicle_cockpit.mdx
+++ b/src/content/docs/examples/vehicle_cockpit.mdx
@@ -2,3 +2,188 @@
title: Vehicle Cockpit
description: A sample project that simulates a vehicle cockpit.
---
+
+import { Image, Picture } from "astro:assets";
+import vehicleCockpitScreenshot from "./images/vehicle_cockpit.png";
+import gaugeProgress from "./images/gauge_progress.png";
+import gaugeRing from "./images/gauge_ring.png";
+import gaugeRpmNumbers from "./images/gauge_rpm_numbers.png";
+import gauge from "./images/gauge.png";
+import gear from "./images/gear.png";
+import speedometer from "./images/speedometer.png";
+
+The Vehicle Cockpit simulates a realtime speedometer and tachometer as the user accelerates around the track.
+
+
+
+The source code for this project is available on [GitHub](https://github.com/VGVentures/vehicle_cockpit). To view the live demo, click [here](https://vgventures.github.io/vehicle_cockpit/).
+
+## Flame
+
+[Flame](https://pub.dev/packages/flame) is a game engine that is built for Flutter. It is used to render and update our gauge. Let's take a deeper look into how the components that make up the gauge are created and composed together to form a working speedometer and tachometer.
+
+
+
+### GaugeGame
+
+The `GaugeGame` is the [`FlameGame`](https://docs.flame-engine.org/latest/flame/game.html) object. All of the components that make up the gauge are added inside of the `onLoad` method. These components include the [GaugeComponent](#gaugecomponent), [Speedometer](#speedometer), and the [Gear](#gear).
+
+```dart
+ @override
+ Future onLoad() async {
+ await add(
+ gauge = GaugeComponent(
+ size: Vector2.all(340),
+ position: size / 2,
+ maxRpm: (sim.vehicle.engineRpmMaximum / 1000).round(),
+ dangerZone: (sim.vehicle.engineRpmRedline / 1000).round(),
+ appTheme: appTheme,
+ ),
+ );
+
+ await add(
+ speedometer = Speedometer(
+ speed: 0,
+ position: size / 2 - Vector2(0, 40),
+ ),
+ );
+
+ await add(
+ gear = Gear(
+ position: size / 2 + Vector2(0, 30),
+ triangleSize: 60,
+ ),
+ );
+ }
+```
+
+Not only does the `GaugeGame` add the components to be displayed, it also handles the user input to update the game. As you'll see below, the `GaugeGame` can directly call methods on its components, and can also make its variables and methods available to its children.
+
+The `GaugeGame` relies on a [`GameLoop`](https://docs.flame-engine.org/latest/flame/game.html#game-loop) to update the components on the screen. This calls the `update` method where we can update the gauge's progress, speedometer, and current gear.
+
+```dart
+ @override
+ void update(double dt) {
+ sim.simulate(dt * timeScale, hittingGas ? 1.0 : -1.3);
+
+ gauge.setProgress(
+ sim.engineRpm / sim.vehicle.engineRpmMaximum,
+ dt,
+ );
+ speedometer.speed = sim.speed;
+ gear.gearText.text = sim.gear.toString();
+
+ onSpeedChanged(sim.speed);
+
+ super.update(dt);
+ }
+```
+
+#### GaugeComponent
+
+The `GaugeComponent` is a [`PositionComponent`](https://docs.flame-engine.org/latest/other_modules/oxygen/components.html#positioncomponent) that composes `GaugeRing` and the components that are needed to display the vehicle's RPM information: `GaugeProgress` and `GaugeRpmNumbers`. These are added in the `GaugeComponent`'s `onLoad` method:
+
+```dart
+ @override
+ Future onLoad() async {
+ await add(
+ GaugeRing(
+ size: size.clone(),
+ color: appTheme.colorScheme.error,
+ ),
+ );
+
+ const offset = 16.0;
+ final innerRingPosition = Vector2.all(offset / 2);
+ final innerRingSize = size.clone() - Vector2.all(offset);
+ await add(
+ GaugeProgress(
+ position: innerRingPosition,
+ size: innerRingSize,
+ ),
+ );
+ await add(
+ GaugeRpmNumbers(
+ position: innerRingPosition,
+ size: innerRingSize,
+ ),
+ );
+ }
+```
+
+##### Gauge Ring
+
+The `GaugeRing` is a `PositionComponent` that forms the outline of the gauge. This component simply renders the ring.
+
+
+
+##### Gauge Progress
+
+The `GaugeProgress` is another `PositionComponent` object that draws the gradient RPM progress bar that is located just inside of the `GaugeRing`. The `GaugeComponent`'s `progress` value gets set within the `GaugeGame`'s `update` method. The `GaugeProgress` object makes use of the [`ParentIsA`](https://docs.flame-engine.org/latest/flame/components.html#ensuring-a-component-has-a-given-parent) [mixin](https://dart.dev/language/mixins), which gives the component access to the parent component via the `parent` property.
+
+
+
+##### Gauge RPM Numbers
+
+The `GaugeRpmNumbers` is the last `PositionComponent` object that is used for the tachometer. This component consist of the `GaugeRmpPoint` component, that draws the RPM tick marks, and also the `GaugeNumberIndicator` that draws the RPM numbers below the ticks.
+
+
+
+### Speedometer
+
+The `Speedometer` is a [`TextComponent`](https://docs.flame-engine.org/latest/flame/rendering/text_rendering.html#textcomponent) object that renders the current speed and the "MPH" label to the screen. The `Speedometer` object uses the [`HasGameRef`](https://github.com/flame-engine/flame/blob/a5338d0c20d01bbe461c6d7fed5951d11e1c76f0/packages/flame/lib/src/components/mixins/has_game_ref.dart) mixin, which allows it to access variables and methods that are in the `GaugeGame` class. This makes it easier for the `Speedometer` to access the `GaugeGame`'s `appTheme` and `l10n` members.
+
+
+
+### Gear
+
+The `Gear` is a `PositionComponent` that renders the vehicle's current gear inside of a triangle. The `gearText` is set directly in the `GaugeGame`.
+
+```dart
+gear.gearText.text = sim.gear.toString();
+```
+
+
+
+## Adding the Gauge to the Widget Tree
+
+To add the gauge to the `DashboardPage`, we'll use Flame's [`GameWidget`](https://docs.flame-engine.org/latest/flame/game_widget.html). The `GameWidget` requires a `Game` object. In this case, that would be our `GaugeGame`.
+
+```dart
+final game = GaugeGame(
+ sim: VehicleSim(vehicle: Vehicles.compactCrossoverSUV),
+ appTheme: theme,
+ l10n: l10n,
+ onSpeedChanged: onSpeedChanged,
+);
+
+// ...
+
+LayoutBuilder(
+ builder: (context, constraints) {
+ final width = min(400, constraints.maxWidth);
+ return SizedBox.square(
+ dimension: width * .75,
+ child: Transform.scale(
+ scale: width / 500,
+ child: GameWidget(
+ game: game,
+ ),
+ ),
+ );
+ },
+),
+```
+
+The `acceleratorPedalPushed()` and `acceleratorPedalReleased()` can be called on the `game` object to simulate pressing and releasing the accelerator pedal.