diff --git a/frontend/src/app/lessons/page.tsx b/frontend/src/app/lessons/page.tsx
new file mode 100644
index 00000000..9b5dc5cf
--- /dev/null
+++ b/frontend/src/app/lessons/page.tsx
@@ -0,0 +1,99 @@
+'use client';
+
+import Link from 'next/link';
+import { ArrowLeft } from 'lucide-react';
+import { motion } from 'framer-motion';
+import LessonWorkspace from '@/components/lesson/LessonWorkspace';
+
+/**
+ * /lessons — demonstrates the interactive lesson workspace: lesson content on
+ * the left, a live Monaco code editor side-panel on the right.
+ *
+ * This page wires a sample Soroban lesson into {@link LessonWorkspace}; real
+ * curriculum data can be passed in the same shape from the course pages.
+ */
+
+const SAMPLE_STARTER = `#![no_std]
+use soroban_sdk::{contract, contractimpl, Env, Symbol, symbol_short};
+
+#[contract]
+pub struct Greeter;
+
+#[contractimpl]
+impl Greeter {
+ // TODO: return a greeting Symbol from this function.
+ pub fn greet(env: Env) -> Symbol {
+ symbol_short!("hello")
+ }
+}`;
+
+export default function LessonsPage() {
+ return (
+
+ Follow the lesson and experiment in the live editor beside it.
+
+
+
+
+
+
+ Soroban contracts are written in Rust. Every contract is a struct
+ annotated with #[contract], and its callable
+ methods live in an impl block marked
+ #[contractimpl].
+
+
+ In the editor on the right, the greet function
+ already returns a short symbol. Try editing the returned value, or add a new method
+ that takes a name and returns a personalised greeting.
+
+
+ The editor provides Rust syntax highlighting and basic autocompletion. Use the
+ Reset button in the editor header to restore
+ the starter code at any time.
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/lesson/LessonCodeEditor.tsx b/frontend/src/components/lesson/LessonCodeEditor.tsx
new file mode 100644
index 00000000..76348c0f
--- /dev/null
+++ b/frontend/src/components/lesson/LessonCodeEditor.tsx
@@ -0,0 +1,189 @@
+'use client';
+
+import dynamic from 'next/dynamic';
+import type { OnMount } from '@monaco-editor/react';
+import React, { useCallback, useEffect, useState } from 'react';
+import { RotateCcw } from 'lucide-react';
+import { extendRustLanguage } from '@/lib/editor/SorobanLanguage';
+import { registerSorobanCompletion } from '@/lib/editor/SorobanCompletion';
+
+/**
+ * LessonCodeEditor — a self-contained Monaco editor for the lesson side-panel.
+ *
+ * Design notes:
+ * - **Bundle size**: Monaco is heavy, so `@monaco-editor/react` is pulled in via
+ * `next/dynamic` with `ssr: false`. It is never part of the server bundle and
+ * only downloads on the client when a lesson with an editor is opened.
+ * - **Rust support**: syntax highlighting and basic autocomplete are wired up by
+ * reusing the shared `extendRustLanguage` / `registerSorobanCompletion`
+ * helpers, so the lesson editor stays consistent with the playground without
+ * duplicating the language definition.
+ * - **Decoupled**: unlike the playground editor, this component has no
+ * collaboration/compile coupling. It owns a single string of code, reports
+ * changes via `onChange`, and can reset back to the lesson's starter code.
+ * - **Resilient**: if Monaco fails to load, an accessible