Sfoglia il codice sorgente

Manual: Implemented docs styling.

Mr.doob 3 anni fa
parent
commit
4519858cf3
4 ha cambiato i file con 621 aggiunte e 639 eliminazioni
  1. 68 78
      manual/index.html
  2. 343 355
      manual/list.json
  3. 81 8
      manual/resources/lang.css
  4. 129 198
      manual/resources/lesson.css

+ 68 - 78
manual/index.html

@@ -7,23 +7,6 @@
 		<link rel="shortcut icon" href="../files/favicon_white.ico" media="(prefers-color-scheme: dark)"/>
 		<link rel="shortcut icon" href="../files/favicon.ico" media="(prefers-color-scheme: light)" />
 		<link rel="stylesheet" type="text/css" href="../files/main.css">
-		<style>
-			/*
-				note: I don't know why the docs page is the way it is but it would
-				seem to make sense for the iframe to be the size you want the content
-				rather then every piece of content be responsible for knowing how to 
-				adjust itself to handle the left panel?
-			*/
-			iframe {
-				padding-left: var(--panel-width);
-			}
-			@media all and ( max-width: 640px ) {
-				iframe {
-					padding-left: 0;
-				}
-			}
-
-		</style>
 		<!-- console sandbox -->
 		<script src="../build/three.min.js" async defer></script>
 	</head>
@@ -33,6 +16,10 @@
 			<div id="header">
 				<h1><a href="https://threejs.org">three.js</a></h1>
 
+				<div id="sections">
+					<span class="selected">manual</span>
+				</div>
+
 				<div id="expandButton"></div>
 			</div>
 
@@ -51,6 +38,7 @@
 						<option value="ja">日本語</option>
 					</select>
 				</div>
+				<br/>
 				<div id="content"></div>
 			</div>
 
@@ -189,7 +177,7 @@
 		function createLink( pageName, pageURL ) {
 
 			const link = document.createElement( 'a' );
-			const url = new URL(pageURL, window.location.href);
+			const url = new URL( pageURL, window.location.href );
 			url.pathname += '.html';
 			link.href = url.href;
 			link.textContent = pageName;
@@ -235,77 +223,64 @@
 
 			}
 
-			const localList = list[ language ];
+			const categories = list[ language ];
 			const selectedPage = window.location.hash.substring( 1 );
 
-			for ( const section in localList ) {
-
-				// Create sections
-
-				const categories = localList[ section ];
+			for ( const category in categories ) {
 
-				const sectionHead = document.createElement( 'h2' );
-				sectionHead.textContent = section;
-				navigation.appendChild( sectionHead );
+				// Create categories
 
-				for ( const category in categories ) {
+				const pages = categories[ category ];
 
-					// Create categories
+				const categoryContainer = document.createElement( 'div' );
+				navigation.appendChild( categoryContainer );
 
-					const pages = categories[ category ];
+				const categoryHead = document.createElement( 'h3' );
+				categoryHead.textContent = category;
+				categoryContainer.appendChild( categoryHead );
 
-					const categoryContainer = document.createElement( 'div' );
-					navigation.appendChild( categoryContainer );
+				const categoryContent = document.createElement( 'ul' );
+				categoryContainer.appendChild( categoryContent );
 
-					const categoryHead = document.createElement( 'h3' );
-					categoryHead.textContent = category;
-					categoryContainer.appendChild( categoryHead );
+				for ( const pageName in pages ) {
 
-					const categoryContent = document.createElement( 'ul' );
-					categoryContainer.appendChild( categoryContent );
+					// Create page links
 
-					for ( const pageName in pages ) {
+					const pageURL = pages[ pageName ];
 
-						// Create page links
+					// Localisation
 
-						const pageURL = pages[ pageName ];
+					const listElement = document.createElement( 'li' );
+					categoryContent.appendChild( listElement );
 
-						// Localisation
+					const linkElement = createLink( pageName, pageURL );
+					listElement.appendChild( linkElement );
 
-						const listElement = document.createElement( 'li' );
-						categoryContent.appendChild( listElement );
+					// select current page
 
-						const linkElement = createLink( pageName, pageURL );
-						listElement.appendChild( linkElement );
+					if ( pageURL === selectedPage ) {
 
-						// select current page
+						linkElement.classList.add( 'selected' );
 
-						if ( pageURL === selectedPage ) {
-
-							linkElement.classList.add( 'selected' );
-
-						}
+					}
 
-						// Gather the main properties for the current subpage
+					// Gather the main properties for the current subpage
 
-						pageProperties[ pageName ] = {
-							section: section,
-							category: category,
-							pageURL: pageURL,
-							linkElement: linkElement
-						};
+					pageProperties[ pageName ] = {
+						category: category,
+						pageURL: pageURL,
+						linkElement: linkElement
+					};
 
-						// Gather the document titles (used for easy access on browser navigation)
+					// Gather the document titles (used for easy access on browser navigation)
 
-						titles[ pageURL ] = pageName;
+					titles[ pageURL ] = pageName;
 
-					}
-
-					// Gather the category elements for easy access on filtering
+				}
 
-					categoryElements.push( categoryContent );
+				// Gather the category elements for easy access on filtering
 
-				}
+				categoryElements.push( categoryContent );
 
 			}
 
@@ -431,33 +406,48 @@
 
 			// yea I know this is hacky.
 			const re = /^(\/(?:manual\/|docs\/#?))(.*?)$/;
-			const url = new URL(href);
-			if (url.origin === window.location.origin) {
-				const hrefNoOrigin = url.href.substr(url.origin.length);
-				const m = re.exec(hrefNoOrigin);
-				const [,base, path] = m;
-				if (base.includes('manual')) {
-					const newHash = `#${path.replace('.html', '')}`;
+			const url = new URL( href );
+
+			if ( url.origin === window.location.origin ) {
+
+				const hrefNoOrigin = url.href.substr( url.origin.length );
+				const m = re.exec( hrefNoOrigin );
+				const [ , base, path ] = m;
+				if ( base.includes( 'manual' ) ) {
+
+ 					const newHash = `#${ path.replace( '.html', '' ) }`;
 					// Only create new iframe if we're actually changing pages.
 					// We could just be going to an anchor on the same page.
-					const newPrefix = newHash.split('#')[1];
-					const oldPrefix = window.location.hash.split('#')[1];
-					if (newPrefix === oldPrefix) {
-						const newUrl = new URL(window.location.href);
+					const newPrefix = newHash.split( '#' )[ 1 ];
+					const oldPrefix = window.location.hash.split( '#' )[ 1 ];
+
+					if ( newPrefix === oldPrefix ) {
+
+						const newUrl = new URL( window.location.href );
 						newUrl.hash = newHash;
-						window.history.pushState({}, '', newUrl.href);
+						window.history.pushState( {}, '', newUrl.href );
+
 					} else {
+
 						window.location.hash = newHash;
 						createNewIframe();
+
 					}
+
 					return;
+
 				}
+
 			}
+
 			window.location.href = href;
+
 		}
 
-		function setTitle(title) { // eslint-disable-line no-undef
+		function setTitle( title ) { // eslint-disable-line no-undef
+
 			document.title = `${title} - three.js manual`;
+
 		}
 
 		function createNewIframe() {

+ 343 - 355
manual/list.json

@@ -1,374 +1,362 @@
 {
 	"en": {
-		"manual": {
-			"Basics": {
-				"Fundamentals": "en/fundamentals",
-				"Responsive Design": "en/responsive",
-				"Prerequisites": "en/prerequisites",
-				"Setup": "en/setup"
-			},
-			"Fundamentals": {
-				"Primitives": "en/primitives",
-				"Scenegraph": "en/scenegraph",
-				"Materials": "en/materials",
-				"Textures": "en/textures",
-				"Lights": "en/lights",
-				"Cameras": "en/cameras",
-				"Shadows": "en/shadows",
-				"Fog": "en/fog",
-				"Render Targets": "en/rendertargets",
-				"Custom BufferGeometry": "en/custom-buffergeometry"
-			},
-			"Tips": {
-				"Rendering On Demand": "en/rendering-on-demand",
-				"Debugging JavaScript": "en/debugging-javascript",
-				"Debugging GLSL": "en/debugging-glsl",
-				"Taking a screenshot": "en/tips#screenshot",
-				"Prevent the Canvas Being Cleared": "en/tips#preservedrawingbuffer",
-				"Get Keyboard Input From a Canvas": "en/tips#tabindex",
-				"Make the Canvas Transparent": "en/tips#transparent-canvas",
-				"Use three.js as Background in HTML": "en/tips#html-background"
-			},
-			"Optimization": {
-				"Optimizing Lots of Objects": "en/optimize-lots-of-objects",
-				"Optimizing Lots of Objects Animated": "en/optimize-lots-of-objects-animated",
-				"Using OffscreenCanvas in a Web Worker": "en/offscreencanvas"
-			},
-			"Solutions": {
-				"Load an .OBJ file": "en/load-obj",
-				"Load a .GLTF file": "en/load-gltf",
-				"Add a Background or Skybox": "en/backgrounds",
-				"How to Draw Transparent Objects": "en/transparency",
-				"Multiple Canvases, Multiple Scenes": "en/multiple-scenes",
-				"Picking Objects with the mouse": "en/picking",
-				"Post Processing": "en/post-processing",
-				"Applying a LUT File for effects": "en/post-processing-3dlut",
-				"Using Shadertoy shaders": "en/shadertoy",
-				"Aligning HTML Elements to 3D": "en/align-html-elements-to-3d",
-				"Using Indexed Textures for Picking and Color": "en/indexed-textures",
-				"Using A Canvas for Dynamic Textures": "en/canvas-textures",
-				"Billboards and Facades": "en/billboards",
-				"Freeing Resources": "en/cleanup",
-				"Making Voxel Geometry (Minecraft)": "en/voxel-geometry",
-				"Start making a Game.": "en/game"
-			},
-			"WebXR": {
-				"VR - Basics": "en/webxr",
-				"VR - Look To Select": "en/webxr-look-to-select",
-				"VR - Point To Select": "en/webxr-point-to-select"
-			},
-			"Reference": {
-				"Material Table": "en/material-table"
-			}
+		"Basics": {
+			"Fundamentals": "en/fundamentals",
+			"Responsive Design": "en/responsive",
+			"Prerequisites": "en/prerequisites",
+			"Setup": "en/setup"
+		},
+		"Fundamentals": {
+			"Primitives": "en/primitives",
+			"Scenegraph": "en/scenegraph",
+			"Materials": "en/materials",
+			"Textures": "en/textures",
+			"Lights": "en/lights",
+			"Cameras": "en/cameras",
+			"Shadows": "en/shadows",
+			"Fog": "en/fog",
+			"Render Targets": "en/rendertargets",
+			"Custom BufferGeometry": "en/custom-buffergeometry"
+		},
+		"Tips": {
+			"Rendering On Demand": "en/rendering-on-demand",
+			"Debugging JavaScript": "en/debugging-javascript",
+			"Debugging GLSL": "en/debugging-glsl",
+			"Taking a screenshot": "en/tips#screenshot",
+			"Prevent the Canvas Being Cleared": "en/tips#preservedrawingbuffer",
+			"Get Keyboard Input From a Canvas": "en/tips#tabindex",
+			"Make the Canvas Transparent": "en/tips#transparent-canvas",
+			"Use three.js as Background in HTML": "en/tips#html-background"
+		},
+		"Optimization": {
+			"Optimizing Lots of Objects": "en/optimize-lots-of-objects",
+			"Optimizing Lots of Objects Animated": "en/optimize-lots-of-objects-animated",
+			"Using OffscreenCanvas in a Web Worker": "en/offscreencanvas"
+		},
+		"Solutions": {
+			"Load an .OBJ file": "en/load-obj",
+			"Load a .GLTF file": "en/load-gltf",
+			"Add a Background or Skybox": "en/backgrounds",
+			"How to Draw Transparent Objects": "en/transparency",
+			"Multiple Canvases, Multiple Scenes": "en/multiple-scenes",
+			"Picking Objects with the mouse": "en/picking",
+			"Post Processing": "en/post-processing",
+			"Applying a LUT File for effects": "en/post-processing-3dlut",
+			"Using Shadertoy shaders": "en/shadertoy",
+			"Aligning HTML Elements to 3D": "en/align-html-elements-to-3d",
+			"Using Indexed Textures for Picking and Color": "en/indexed-textures",
+			"Using A Canvas for Dynamic Textures": "en/canvas-textures",
+			"Billboards and Facades": "en/billboards",
+			"Freeing Resources": "en/cleanup",
+			"Making Voxel Geometry (Minecraft)": "en/voxel-geometry",
+			"Start making a Game.": "en/game"
+		},
+		"WebXR": {
+			"VR - Basics": "en/webxr",
+			"VR - Look To Select": "en/webxr-look-to-select",
+			"VR - Point To Select": "en/webxr-point-to-select"
+		},
+		"Reference": {
+			"Material Table": "en/material-table"
 		}
 	},
 	"fr": {
-		"manual": {
-			"Bases": {
-				"Principes de base": "fr/fundamentals",
-				"Design réactif": "fr/responsive",
-				"Pré-requis": "fr/prerequisites",
-				"Configuration": "fr/setup"
-			},
-			"Principes de base": {
-				"Primitives": "fr/primitives",
-				"Graphique de scène": "fr/scenegraph",
-				"Matériaux": "fr/materials",
-				"Textures": "fr/textures",
-				"Lumières": "fr/lights",
-				"Caméras": "fr/cameras",
-				"Ombres": "fr/shadows",
-				"Brouillard": "fr/fog",
-				"Render Targets": "fr/rendertargets",
-				"Custom BufferGeometry": "fr/custom-buffergeometry"
-			},
-			"Сonseils": {
-				"Rendering On Demand": "fr/rendering-on-demand",
-				"Debugging JavaScript": "fr/debugging-javascript",
-				"Debugging GLSL": "fr/debugging-glsl",
-				"Taking a screenshot": "fr/tips#screenshot",
-				"Prevent the Canvas Being Cleared": "fr/tips#preservedrawingbuffer",
-				"Get Keyboard Input From a Canvas": "fr/tips#tabindex",
-				"Make the Canvas Transparent": "fr/tips#transparent-canvas",
-				"Use three.js as Background in HTML": "fr/tips#html-background"
-			},
-			"Optimisation": {
-				"Optimizing Lots of Objects": "fr/optimize-lots-of-objects",
-				"Optimizing Lots of Objects Animated": "fr/optimize-lots-of-objects-animated",
-				"Using OffscreenCanvas in a Web Worker": "fr/offscreencanvas"
-			},
-			"Solutions": {
-				"Load an .OBJ file": "fr/load-obj",
-				"Load a .GLTF file": "fr/load-gltf",
-				"Add a Background or Skybox": "fr/backgrounds",
-				"How to Draw Transparent Objects": "fr/transparency",
-				"Multiple Canvases, Multiple Scenes": "fr/multiple-scenes",
-				"Picking Objects with the mouse": "fr/picking",
-				"Post Processing": "fr/post-processing",
-				"Applying a LUT File for effects": "fr/post-processing-3dlut",
-				"Using Shadertoy shaders": "fr/shadertoy",
-				"Aligning HTML Elements to 3D": "fr/align-html-elements-to-3d",
-				"Using Indexed Textures for Picking and Color": "fr/indexed-textures",
-				"Using A Canvas for Dynamic Textures": "fr/canvas-textures",
-				"Billboards and Facades": "fr/billboards",
-				"Freeing Resources": "fr/cleanup",
-				"Making Voxel Geometry (Minecraft)": "fr/voxel-geometry",
-				"Start making a Game.": "fr/game"
-			},
-			"WebXR": {
-				"VR - Basics": "fr/webxr",
-				"VR - Look To Select": "fr/webxr-look-to-select",
-				"VR - Point To Select": "fr/webxr-point-to-select"
-			},
-			"Référence": {
-				"Material Table": "fr/material-table"
-			}
+		"Bases": {
+			"Principes de base": "fr/fundamentals",
+			"Design réactif": "fr/responsive",
+			"Pré-requis": "fr/prerequisites",
+			"Configuration": "fr/setup"
+		},
+		"Principes de base": {
+			"Primitives": "fr/primitives",
+			"Graphique de scène": "fr/scenegraph",
+			"Matériaux": "fr/materials",
+			"Textures": "fr/textures",
+			"Lumières": "fr/lights",
+			"Caméras": "fr/cameras",
+			"Ombres": "fr/shadows",
+			"Brouillard": "fr/fog",
+			"Render Targets": "fr/rendertargets",
+			"Custom BufferGeometry": "fr/custom-buffergeometry"
+		},
+		"Сonseils": {
+			"Rendering On Demand": "fr/rendering-on-demand",
+			"Debugging JavaScript": "fr/debugging-javascript",
+			"Debugging GLSL": "fr/debugging-glsl",
+			"Taking a screenshot": "fr/tips#screenshot",
+			"Prevent the Canvas Being Cleared": "fr/tips#preservedrawingbuffer",
+			"Get Keyboard Input From a Canvas": "fr/tips#tabindex",
+			"Make the Canvas Transparent": "fr/tips#transparent-canvas",
+			"Use three.js as Background in HTML": "fr/tips#html-background"
+		},
+		"Optimisation": {
+			"Optimizing Lots of Objects": "fr/optimize-lots-of-objects",
+			"Optimizing Lots of Objects Animated": "fr/optimize-lots-of-objects-animated",
+			"Using OffscreenCanvas in a Web Worker": "fr/offscreencanvas"
+		},
+		"Solutions": {
+			"Load an .OBJ file": "fr/load-obj",
+			"Load a .GLTF file": "fr/load-gltf",
+			"Add a Background or Skybox": "fr/backgrounds",
+			"How to Draw Transparent Objects": "fr/transparency",
+			"Multiple Canvases, Multiple Scenes": "fr/multiple-scenes",
+			"Picking Objects with the mouse": "fr/picking",
+			"Post Processing": "fr/post-processing",
+			"Applying a LUT File for effects": "fr/post-processing-3dlut",
+			"Using Shadertoy shaders": "fr/shadertoy",
+			"Aligning HTML Elements to 3D": "fr/align-html-elements-to-3d",
+			"Using Indexed Textures for Picking and Color": "fr/indexed-textures",
+			"Using A Canvas for Dynamic Textures": "fr/canvas-textures",
+			"Billboards and Facades": "fr/billboards",
+			"Freeing Resources": "fr/cleanup",
+			"Making Voxel Geometry (Minecraft)": "fr/voxel-geometry",
+			"Start making a Game.": "fr/game"
+		},
+		"WebXR": {
+			"VR - Basics": "fr/webxr",
+			"VR - Look To Select": "fr/webxr-look-to-select",
+			"VR - Point To Select": "fr/webxr-point-to-select"
+		},
+		"Référence": {
+			"Material Table": "fr/material-table"
 		}
 	},
 	"ja": {
-		"manual": {
-			"基本": {
-				"基礎知識": "ja/fundamentals",
-				"レスポンシブデザイン": "ja/responsive",
-				"前提条件": "ja/prerequisites",
-				"セットアップ": "ja/setup"
-			},
-			"基礎": {
-				"プリミティブ": "ja/primitives",
-				"シーングラフ": "ja/scenegraph",
-				"マテリアル": "ja/materials",
-				"テクスチャ": "ja/textures",
-				"ライト": "ja/lights",
-				"カメラ": "ja/cameras",
-				"シャドウ": "ja/shadows",
-				"フォグ": "ja/fog",
-				"レンダーターゲット": "ja/rendertargets",
-				"カスタムバッファジオメトリ": "ja/custom-buffergeometry"
-			},
-			"Tips": {
-				"要求されたレンダリング": "ja/rendering-on-demand",
-				"JavaScriptのデバッグ": "ja/debugging-javascript",
-				"GLSLのデバッグ": "ja/debugging-glsl",
-				"スクリーンショットを撮る": "ja/tips#screenshot",
-				"キャンバスがクリアされるのを防ぐ": "ja/tips#preservedrawingbuffer",
-				"キャンバスからキーボード入力を取得する": "ja/tips#tabindex",
-				"キャンバスを透明にする": "ja/tips#transparent-canvas",
-				"HTMLの背景にthree.jsを使う": "ja/tips#html-background"
-			},
-			"最適化": {
-				"多くのオブジェクトを最適化": "ja/optimize-lots-of-objects",
-				"アニメーションする多くのオブジェクトを最適化": "ja/optimize-lots-of-objects-animated",
-				"Web WorkerでOffscreenCanvasを使用する": "ja/offscreencanvas"
-			},
-			"解決策": {
-				"OBJファイルの読み込み": "ja/load-obj",
-				"GLTFファイルの読み込み": "ja/load-gltf",
-				"背景やスカイボックスを追加する": "ja/backgrounds",
-				"透明なオブジェクトの描画方法": "ja/transparency",
-				"複数キャンバスと複数シーン": "ja/multiple-scenes",
-				"マウスでオブジェクトをピッキング": "ja/picking",
-				"ポストプロセス": "ja/post-processing",
-				"エフェクトにLUTファイルを適用する": "ja/post-processing-3dlut",
-				"Shadertoyのシェーダーを使う": "ja/shadertoy",
-				"HTML要素を3Dに揃える": "ja/align-html-elements-to-3d",
-				"圧縮テクスチャのピッキングとカラー": "ja/indexed-textures",
-				"動的なテクスチャのキャンバスを使用する": "ja/canvas-textures",
-				"Billboards and Facades": "ja/billboards",
-				"Freeing Resources": "ja/cleanup",
-				"Making Voxel Geometry (Minecraft)": "ja/voxel-geometry",
-				"Start making a Game.": "ja/game"
-			},
-			"WebXR": {
-				"VR - Basics": "ja/webxr",
-				"VR - Look To Select": "ja/webxr-look-to-select",
-				"VR - Point To Select": "ja/webxr-point-to-select"
-			},
-			"参照": {
-				"Material Table": "ja/material-table"
-			}
+		"基本": {
+			"基礎知識": "ja/fundamentals",
+			"レスポンシブデザイン": "ja/responsive",
+			"前提条件": "ja/prerequisites",
+			"セットアップ": "ja/setup"
+		},
+		"基礎": {
+			"プリミティブ": "ja/primitives",
+			"シーングラフ": "ja/scenegraph",
+			"マテリアル": "ja/materials",
+			"テクスチャ": "ja/textures",
+			"ライト": "ja/lights",
+			"カメラ": "ja/cameras",
+			"シャドウ": "ja/shadows",
+			"フォグ": "ja/fog",
+			"レンダーターゲット": "ja/rendertargets",
+			"カスタムバッファジオメトリ": "ja/custom-buffergeometry"
+		},
+		"Tips": {
+			"要求されたレンダリング": "ja/rendering-on-demand",
+			"JavaScriptのデバッグ": "ja/debugging-javascript",
+			"GLSLのデバッグ": "ja/debugging-glsl",
+			"スクリーンショットを撮る": "ja/tips#screenshot",
+			"キャンバスがクリアされるのを防ぐ": "ja/tips#preservedrawingbuffer",
+			"キャンバスからキーボード入力を取得する": "ja/tips#tabindex",
+			"キャンバスを透明にする": "ja/tips#transparent-canvas",
+			"HTMLの背景にthree.jsを使う": "ja/tips#html-background"
+		},
+		"最適化": {
+			"多くのオブジェクトを最適化": "ja/optimize-lots-of-objects",
+			"アニメーションする多くのオブジェクトを最適化": "ja/optimize-lots-of-objects-animated",
+			"Web WorkerでOffscreenCanvasを使用する": "ja/offscreencanvas"
+		},
+		"解決策": {
+			"OBJファイルの読み込み": "ja/load-obj",
+			"GLTFファイルの読み込み": "ja/load-gltf",
+			"背景やスカイボックスを追加する": "ja/backgrounds",
+			"透明なオブジェクトの描画方法": "ja/transparency",
+			"複数キャンバスと複数シーン": "ja/multiple-scenes",
+			"マウスでオブジェクトをピッキング": "ja/picking",
+			"ポストプロセス": "ja/post-processing",
+			"エフェクトにLUTファイルを適用する": "ja/post-processing-3dlut",
+			"Shadertoyのシェーダーを使う": "ja/shadertoy",
+			"HTML要素を3Dに揃える": "ja/align-html-elements-to-3d",
+			"圧縮テクスチャのピッキングとカラー": "ja/indexed-textures",
+			"動的なテクスチャのキャンバスを使用する": "ja/canvas-textures",
+			"Billboards and Facades": "ja/billboards",
+			"Freeing Resources": "ja/cleanup",
+			"Making Voxel Geometry (Minecraft)": "ja/voxel-geometry",
+			"Start making a Game.": "ja/game"
+		},
+		"WebXR": {
+			"VR - Basics": "ja/webxr",
+			"VR - Look To Select": "ja/webxr-look-to-select",
+			"VR - Point To Select": "ja/webxr-point-to-select"
+		},
+		"参照": {
+			"Material Table": "ja/material-table"
 		}
 	},
 	"ko": {
-		"manual": {
-			"Three.js란?": {
-				"Three.js란?": "ko/fundamentals",
-				"반응형 디자인": "ko/responsive",
-				"먼저 알아야 할 것들": "ko/prerequisites",
-				"개발 환경": "ko/setup"
-			},
-			"기본 구조": {
-				"원시 모델": "ko/primitives",
-				"씬 그래프": "ko/scenegraph",
-				"재질(Materials)": "ko/materials",
-				"텍스처(Textures)": "ko/textures",
-				"조명(Lights)": "ko/lights",
-				"카메라(Cameras)": "ko/cameras",
-				"그림자(Shadows)": "ko/shadows",
-				"안개(Fog)": "ko/fog",
-				"렌더 타겟(Render Targets)": "ko/rendertargets",
-				"사용자 지정 BufferGeometry": "ko/custom-buffergeometry"
-			},
-			"팁": {
-				"불필요한 렌더링 없애기": "ko/rendering-on-demand",
-				"자바스크립트 디버깅": "ko/debugging-javascript",
-				"GLSL 디버깅": "ko/debugging-glsl",
-				"스크린샷 찍기": "ko/tips#screenshot",
-				"캔버스 초기화 방지하기": "ko/tips#preservedrawingbuffer",
-				"캔버스에서 키 입력 받기": "ko/tips#tabindex",
-				"캔버스를 투명하게 만들기": "ko/tips#transparent-canvas",
-				"Three.js를 HTML 요소의 배경으로 사용하기": "ko/tips#html-background"
-			},
-			"최적화하기": {
-				"요소가 많을 때 최적화하는 방법": "ko/optimize-lots-of-objects",
-				"애니메이션 요소가 많을 때 최적화하는 방법": "ko/optimize-lots-of-objects-animated",
-				"웹 워커에서 OffscreenCanvas 사용하기": "ko/offscreencanvas"
-			},
-			"활용하기": {
-				".OBJ 파일 불러오기": "ko/load-obj",
-				".GLTF 파일 불러오기": "ko/load-gltf",
-				"배경, 하늘 상자 추가하기": "ko/backgrounds",
-				"물체의 투명도 설정하기": "ko/transparency",
-				"다중 캔버스, 다중 장면 만들기": "ko/multiple-scenes",
-				"물체를 마우스로 피킹하기": "ko/picking",
-				"후처리": "ko/post-processing",
-				"LUT 파일로 후처리 효과 적용하기": "ko/post-processing-3dlut",
-				"쉐이더토이 쉐이더 활용하기": "ko/shadertoy",
-				"HTML 요소를 3D로 정렬하기": "ko/align-html-elements-to-3d",
-				"피킹과 색상에 인덱스 텍스처 사용하기": "ko/indexed-textures",
-				"캔버스로 동적 텍스처 만들기": "ko/canvas-textures",
-				"빌보드와 파사드": "ko/billboards",
-				"메모리 해제하기": "ko/cleanup",
-				"복셀 Geometry(마인크래프트) 만들기": "ko/voxel-geometry",
-				"게임 만들기": "ko/game"
-			},
-			"웹VR": {
-				"VR - Basics": "ko/webxr",
-				"VR - Look To Select": "ko/webxr-look-to-select",
-				"VR - Point To Select": "ko/webxr-point-to-select"
-			},
-			"레퍼런스": {
-				"재질(Material) 속성표": "ko/material-table"
-			}
+		"Three.js란?": {
+			"Three.js란?": "ko/fundamentals",
+			"반응형 디자인": "ko/responsive",
+			"먼저 알아야 할 것들": "ko/prerequisites",
+			"개발 환경": "ko/setup"
+		},
+		"기본 구조": {
+			"원시 모델": "ko/primitives",
+			"씬 그래프": "ko/scenegraph",
+			"재질(Materials)": "ko/materials",
+			"텍스처(Textures)": "ko/textures",
+			"조명(Lights)": "ko/lights",
+			"카메라(Cameras)": "ko/cameras",
+			"그림자(Shadows)": "ko/shadows",
+			"안개(Fog)": "ko/fog",
+			"렌더 타겟(Render Targets)": "ko/rendertargets",
+			"사용자 지정 BufferGeometry": "ko/custom-buffergeometry"
+		},
+		"팁": {
+			"불필요한 렌더링 없애기": "ko/rendering-on-demand",
+			"자바스크립트 디버깅": "ko/debugging-javascript",
+			"GLSL 디버깅": "ko/debugging-glsl",
+			"스크린샷 찍기": "ko/tips#screenshot",
+			"캔버스 초기화 방지하기": "ko/tips#preservedrawingbuffer",
+			"캔버스에서 키 입력 받기": "ko/tips#tabindex",
+			"캔버스를 투명하게 만들기": "ko/tips#transparent-canvas",
+			"Three.js를 HTML 요소의 배경으로 사용하기": "ko/tips#html-background"
+		},
+		"최적화하기": {
+			"요소가 많을 때 최적화하는 방법": "ko/optimize-lots-of-objects",
+			"애니메이션 요소가 많을 때 최적화하는 방법": "ko/optimize-lots-of-objects-animated",
+			"웹 워커에서 OffscreenCanvas 사용하기": "ko/offscreencanvas"
+		},
+		"활용하기": {
+			".OBJ 파일 불러오기": "ko/load-obj",
+			".GLTF 파일 불러오기": "ko/load-gltf",
+			"배경, 하늘 상자 추가하기": "ko/backgrounds",
+			"물체의 투명도 설정하기": "ko/transparency",
+			"다중 캔버스, 다중 장면 만들기": "ko/multiple-scenes",
+			"물체를 마우스로 피킹하기": "ko/picking",
+			"후처리": "ko/post-processing",
+			"LUT 파일로 후처리 효과 적용하기": "ko/post-processing-3dlut",
+			"쉐이더토이 쉐이더 활용하기": "ko/shadertoy",
+			"HTML 요소를 3D로 정렬하기": "ko/align-html-elements-to-3d",
+			"피킹과 색상에 인덱스 텍스처 사용하기": "ko/indexed-textures",
+			"캔버스로 동적 텍스처 만들기": "ko/canvas-textures",
+			"빌보드와 파사드": "ko/billboards",
+			"메모리 해제하기": "ko/cleanup",
+			"복셀 Geometry(마인크래프트) 만들기": "ko/voxel-geometry",
+			"게임 만들기": "ko/game"
+		},
+		"웹VR": {
+			"VR - Basics": "ko/webxr",
+			"VR - Look To Select": "ko/webxr-look-to-select",
+			"VR - Point To Select": "ko/webxr-point-to-select"
+		},
+		"레퍼런스": {
+			"재질(Material) 속성표": "ko/material-table"
 		}
 	},
 	"ru": {
-		"manual": {
-			"Введение": {
-				"Базовые принципы": "ru/fundamentals",
-				"Адаптивный дизайн": "ru/responsive",
-				"Необходимые условия": "ru/prerequisites",
-				"Настройка": "ru/setup"
-			},
-			"Фунаментальные понятия": {
-				"Примитивы": "ru/primitives",
-				"Граф сцены": "ru/scenegraph",
-				"Материалы": "ru/materials",
-				"Текстуры": "ru/textures",
-				"Освещение": "ru/lights",
-				"Камера": "ru/cameras",
-				"Тени": "ru/shadows",
-				"Туман": "ru/fog",
-				"Цели рендеринга": "ru/rendertargets",
-				"Пользовательская BufferGeometry": "ru/custom-buffergeometry"
-			},
-			"Советы": {
-				"Рендеринг по требованию": "ru/rendering-on-demand",
-				"Отладка JavaScript": "ru/debugging-javascript",
-				"Отладка GLSL": "ru/debugging-glsl",
-				"Делаем скриншот холста": "ru/tips#screenshot",
-				"Предотвращение очистки холста ": "ru/tips#preservedrawingbuffer",
-				"Ввод с клавиатуры": "ru/tips#tabindex",
-				"Делаем холст прозрачным ": "ru/tips#transparent-canvas",
-				"Создание анимированного фона в three.js ": "ru/tips#html-background"
-			},
-			"Оптимизация": {
-				"Оптимизация большого количества объектов": "ru/optimize-lots-of-objects",
-				"Оптимизация множества анимированных объектов": "ru/optimize-lots-of-objects-animated",
-				"Использование OffscreenCanvas в воркере": "ru/offscreencanvas"
-			},
-			"Решения": {
-				"Load an .OBJ file": "ru/load-obj",
-				"Load a .GLTF file": "ru/load-gltf",
-				"Add a Background or Skybox": "ru/backgrounds",
-				"How to Draw Transparent Objects": "ru/transparency",
-				"Несколько холстов, несколько сцен": "ru/multiple-scenes",
-				"Picking Objects with the mouse": "ru/picking",
-				"Post Processing": "ru/post-processing",
-				"Applying a LUT File for effects": "ru/post-processing-3dlut",
-				"Using Shadertoy shaders": "ru/shadertoy",
-				"Aligning HTML Elements to 3D": "ru/align-html-elements-to-3d",
-				"Using Indexed Textures for Picking and Color": "ru/indexed-textures",
-				"Using A Canvas for Dynamic Textures": "ru/canvas-textures",
-				"Billboards and Facades": "ru/billboards",
-				"Freeing Resources": "ru/cleanup",
-				"Making Voxel Geometry (Minecraft)": "ru/voxel-geometry",
-				"Start making a Game.": "ru/game"
-			},
-			"WebXR": {
-				"VR - Basics": "ru/webxr",
-				"VR - Look To Select": "ru/webxr-look-to-select",
-				"VR - Point To Select": "ru/webxr-point-to-select"
-			},
-			"Ссылки": {
-				"Таблица материалов": "ru/material-table"
-			}
+		"Введение": {
+			"Базовые принципы": "ru/fundamentals",
+			"Адаптивный дизайн": "ru/responsive",
+			"Необходимые условия": "ru/prerequisites",
+			"Настройка": "ru/setup"
+		},
+		"Фунаментальные понятия": {
+			"Примитивы": "ru/primitives",
+			"Граф сцены": "ru/scenegraph",
+			"Материалы": "ru/materials",
+			"Текстуры": "ru/textures",
+			"Освещение": "ru/lights",
+			"Камера": "ru/cameras",
+			"Тени": "ru/shadows",
+			"Туман": "ru/fog",
+			"Цели рендеринга": "ru/rendertargets",
+			"Пользовательская BufferGeometry": "ru/custom-buffergeometry"
+		},
+		"Советы": {
+			"Рендеринг по требованию": "ru/rendering-on-demand",
+			"Отладка JavaScript": "ru/debugging-javascript",
+			"Отладка GLSL": "ru/debugging-glsl",
+			"Делаем скриншот холста": "ru/tips#screenshot",
+			"Предотвращение очистки холста ": "ru/tips#preservedrawingbuffer",
+			"Ввод с клавиатуры": "ru/tips#tabindex",
+			"Делаем холст прозрачным ": "ru/tips#transparent-canvas",
+			"Создание анимированного фона в three.js ": "ru/tips#html-background"
+		},
+		"Оптимизация": {
+			"Оптимизация большого количества объектов": "ru/optimize-lots-of-objects",
+			"Оптимизация множества анимированных объектов": "ru/optimize-lots-of-objects-animated",
+			"Использование OffscreenCanvas в воркере": "ru/offscreencanvas"
+		},
+		"Решения": {
+			"Load an .OBJ file": "ru/load-obj",
+			"Load a .GLTF file": "ru/load-gltf",
+			"Add a Background or Skybox": "ru/backgrounds",
+			"How to Draw Transparent Objects": "ru/transparency",
+			"Несколько холстов, несколько сцен": "ru/multiple-scenes",
+			"Picking Objects with the mouse": "ru/picking",
+			"Post Processing": "ru/post-processing",
+			"Applying a LUT File for effects": "ru/post-processing-3dlut",
+			"Using Shadertoy shaders": "ru/shadertoy",
+			"Aligning HTML Elements to 3D": "ru/align-html-elements-to-3d",
+			"Using Indexed Textures for Picking and Color": "ru/indexed-textures",
+			"Using A Canvas for Dynamic Textures": "ru/canvas-textures",
+			"Billboards and Facades": "ru/billboards",
+			"Freeing Resources": "ru/cleanup",
+			"Making Voxel Geometry (Minecraft)": "ru/voxel-geometry",
+			"Start making a Game.": "ru/game"
+		},
+		"WebXR": {
+			"VR - Basics": "ru/webxr",
+			"VR - Look To Select": "ru/webxr-look-to-select",
+			"VR - Point To Select": "ru/webxr-point-to-select"
+		},
+		"Ссылки": {
+			"Таблица материалов": "ru/material-table"
 		}
 	},
 	"zh_cn": {
-		"manual": {
-			"基础": {
-				"图元": "zh_cn/primitives",
-				"场景图": "zh_cn/scenegraph",
-				"材质": "zh_cn/materials",
-				"纹理": "zh_cn/textures",
-				"光照": "zh_cn/lights",
-				"摄像机": "zh_cn/cameras",
-				"阴影": "zh_cn/shadows",
-				"雾": "zh_cn/fog",
-				"渲染目标": "zh_cn/rendertargets",
-				"自定义缓冲几何体": "zh_cn/custom-buffergeometry"
-			},
-			"技巧": {
-				"按需渲染": "zh_cn/rendering-on-demand",
-				"Debugging JavaScript": "zh_cn/debugging-javascript",
-				"调试着色器": "zh_cn/debugging-glsl",
-				"Taking a screenshot": "zh_cn/tips#screenshot",
-				"Prevent the Canvas Being Cleared": "zh_cn/tips#preservedrawingbuffer",
-				"Get Keyboard Input From a Canvas": "zh_cn/tips#tabindex",
-				"Make the Canvas Transparent": "zh_cn/tips#transparent-canvas",
-				"Use three.js as Background in HTML": "zh_cn/tips#html-background"
-			},
-			"优化": {
-				"大量对象的优化": "zh_cn/optimize-lots-of-objects",
-				"优化对象的同时保持动画效果": "zh_cn/optimize-lots-of-objects-animated",
-				"Using OffscreenCanvas in a Web Worker": "zh_cn/offscreencanvas"
-			},
-			"解决方案": {
-				"加载 .OBJ 文件": "zh_cn/load-obj",
-				"Load a .GLTF file": "zh_cn/load-gltf",
-				"Add a Background or Skybox": "zh_cn/backgrounds",
-				"How to Draw Transparent Objects": "zh_cn/transparency",
-				"Multiple Canvases, Multiple Scenes": "zh_cn/multiple-scenes",
-				"鼠标选取对象": "zh_cn/picking",
-				"后期处理": "zh_cn/post-processing",
-				"Applying a LUT File for effects": "zh_cn/post-processing-3dlut",
-				"Using Shadertoy shaders": "zh_cn/shadertoy",
-				"Aligning HTML Elements to 3D": "zh_cn/align-html-elements-to-3d",
-				"Using Indexed Textures for Picking and Color": "zh_cn/indexed-textures",
-				"Using A Canvas for Dynamic Textures": "zh_cn/canvas-textures",
-				"Billboards and Facades": "zh_cn/billboards",
-				"Freeing Resources": "zh_cn/cleanup",
-				"Making Voxel Geometry (Minecraft)": "zh_cn/voxel-geometry",
-				"Start making a Game.": "zh_cn/game"
-			},
-			"WebXR": {
-				"VR - Basics": "zh_cn/webxr",
-				"VR - Look To Select": "zh_cn/webxr-look-to-select",
-				"VR - Point To Select": "zh_cn/webxr-point-to-select"
-			},
-			"参考": {
-				"Material Table": "zh_cn/material-table"
-			}
+		"基础": {
+			"图元": "zh_cn/primitives",
+			"场景图": "zh_cn/scenegraph",
+			"材质": "zh_cn/materials",
+			"纹理": "zh_cn/textures",
+			"光照": "zh_cn/lights",
+			"摄像机": "zh_cn/cameras",
+			"阴影": "zh_cn/shadows",
+			"雾": "zh_cn/fog",
+			"渲染目标": "zh_cn/rendertargets",
+			"自定义缓冲几何体": "zh_cn/custom-buffergeometry"
+		},
+		"技巧": {
+			"按需渲染": "zh_cn/rendering-on-demand",
+			"Debugging JavaScript": "zh_cn/debugging-javascript",
+			"调试着色器": "zh_cn/debugging-glsl",
+			"Taking a screenshot": "zh_cn/tips#screenshot",
+			"Prevent the Canvas Being Cleared": "zh_cn/tips#preservedrawingbuffer",
+			"Get Keyboard Input From a Canvas": "zh_cn/tips#tabindex",
+			"Make the Canvas Transparent": "zh_cn/tips#transparent-canvas",
+			"Use three.js as Background in HTML": "zh_cn/tips#html-background"
+		},
+		"优化": {
+			"大量对象的优化": "zh_cn/optimize-lots-of-objects",
+			"优化对象的同时保持动画效果": "zh_cn/optimize-lots-of-objects-animated",
+			"Using OffscreenCanvas in a Web Worker": "zh_cn/offscreencanvas"
+		},
+		"解决方案": {
+			"加载 .OBJ 文件": "zh_cn/load-obj",
+			"Load a .GLTF file": "zh_cn/load-gltf",
+			"Add a Background or Skybox": "zh_cn/backgrounds",
+			"How to Draw Transparent Objects": "zh_cn/transparency",
+			"Multiple Canvases, Multiple Scenes": "zh_cn/multiple-scenes",
+			"鼠标选取对象": "zh_cn/picking",
+			"后期处理": "zh_cn/post-processing",
+			"Applying a LUT File for effects": "zh_cn/post-processing-3dlut",
+			"Using Shadertoy shaders": "zh_cn/shadertoy",
+			"Aligning HTML Elements to 3D": "zh_cn/align-html-elements-to-3d",
+			"Using Indexed Textures for Picking and Color": "zh_cn/indexed-textures",
+			"Using A Canvas for Dynamic Textures": "zh_cn/canvas-textures",
+			"Billboards and Facades": "zh_cn/billboards",
+			"Freeing Resources": "zh_cn/cleanup",
+			"Making Voxel Geometry (Minecraft)": "zh_cn/voxel-geometry",
+			"Start making a Game.": "zh_cn/game"
+		},
+		"WebXR": {
+			"VR - Basics": "zh_cn/webxr",
+			"VR - Look To Select": "zh_cn/webxr-look-to-select",
+			"VR - Point To Select": "zh_cn/webxr-point-to-select"
+		},
+		"参考": {
+			"Material Table": "zh_cn/material-table"
 		}
 	}
-}
+}

+ 81 - 8
manual/resources/lang.css

@@ -1,8 +1,81 @@
-:root {
-  --article-font-family: Georgia, serif;
-  --headline-font-family: sans-serif;
-  /* a block of code */
-  --code-block-font-family: "Lucida Console", Monaco, monospace;
-  /* a word in a sentence */
-  --code-font-family: monospace;
-}
+/* https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow.css */
+pre.prettyprint .str { color: #718c00; } /* string */
+pre.prettyprint .kwd { color: #8959a8; } /* keyword */
+pre.prettyprint .com { color: #8e908c; } /* comment */
+pre.prettyprint .typ { color: #4271ae; } /* type */
+pre.prettyprint .lit { color: #f5871f; } /* literal */
+pre.prettyprint .pun { color: #4d4d4c; } /* punctuation */
+pre.prettyprint .pln { color: #4d4d4c; } /* plaintext */
+pre.prettyprint .tag { color: #c82829 } /* html tag */
+pre.prettyprint .atn { color: #f5871f } /* attribute name */
+pre.prettyprint .atv { color: #3e999f } /* attribute value */
+pre.prettyprint .dec { color: #f5871f; } /* decimal */
+pre.prettyprint .var { color: #4271ae } /* variable name */
+pre.prettyprint .fun { color: #4271ae } /* function name */
+
+pre.prettyprint ul.modifiedlines {
+    list-style-type: none;
+    padding-left: 0;
+}
+
+pre.prettyprint ul.modifiedlines li.linemodified {
+    list-style-type: none;
+    background-color: #ffffff;
+}
+
+pre.prettyprint ul.modifiedlines li.linedeleted {
+    list-style-type: none;
+    background-color: #ffebe9;
+}
+
+pre.prettyprint ul.modifiedlines li.lineadded {
+    list-style-type: none;
+    background-color: #e6ffec;
+}
+
+pre.prettyprint, code.prettyprint, .dos {
+    background: #f5f5f5;
+    font-family: 'Roboto Mono', monospace;
+    font-size: calc(var(--font-size) - 1px);
+    line-height: calc(var(--line-height) - 1px);
+    margin: 16px calc(-1 * var(--page-padding));
+    padding: calc(var(--page-padding) - 6px) var(--page-padding);
+    overflow: auto;
+    white-space: pre-wrap;
+    box-sizing: border-box;
+}
+
+@media (prefers-color-scheme: dark) {
+
+	/* https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.css */
+	pre.prettyprint .str { color: #b5bd68; } /* string */
+	pre.prettyprint .kwd { color: #b294bb; } /* keyword */
+	pre.prettyprint .com { color: #969896; } /* comment */
+	pre.prettyprint .typ { color: #81a2be; } /* type */
+	pre.prettyprint .lit { color: #de935f; } /* literal */
+	pre.prettyprint .pun { color: #c5c8c6; } /* punctuation */
+	pre.prettyprint .pln { color: #c5c8c6; } /* plaintext */
+	pre.prettyprint .tag { color: #cc6666 } /* html tag */
+	pre.prettyprint .atn { color: #de935f } /* attribute name */
+	pre.prettyprint .atv { color: #8abeb7 } /* attribute value */
+	pre.prettyprint .dec { color: #de935f; } /* decimal */
+	pre.prettyprint .var { color: #cc6666 } /* variable name */
+	pre.prettyprint .fun { color: #81a2be } /* function name */
+
+	pre.prettyprint ul.modifiedlines li.linemodified {
+			background-color: #222222;
+	}
+
+	pre.prettyprint ul.modifiedlines li.linedeleted {
+			background-color: #412e32;
+	}
+
+	pre.prettyprint ul.modifiedlines li.lineadded {
+			background-color: #293832;
+	}
+
+	pre.prettyprint, code.prettyprint, .dos {
+		background: #333333;
+	}
+
+}

+ 129 - 198
manual/resources/lesson.css

@@ -1,27 +1,96 @@
+/* TODO Use ../files/main.css instead */
+
 :root {
+	color-scheme: light dark;
+
+	--color-blue: #049EF4;
+	--text-color: #444;
+
+	--font-size: 16px;
+	--line-height: 26px;
+
+	--border-style: 1px solid #E8E8E8;
+	--panel-width: 300px;
 	--page-padding: 24px;
+	--max-width: 760px;
+	--icon-size: 20px;
+}
 
-  /* these are overridden in manual/<lang>/lang.css */
-  --article-font-family: Georgia, serif;
-  --headline-font-family: sans-serif;
-  /* a block of code */
-  --code-block-font-family: "Lucida Console", Monaco, monospace;
-  /* a word in a sentence */
-  --code-font-family: monospace;
+@media (prefers-color-scheme: dark) {
+
+	:root {
+		--background-color: #222;
+		--secondary-background-color: #2e2e2e;
+
+		--text-color: #bbb;
+		--secondary-text-color: #666;
+
+		--border-style: 1px solid #444;
+	}
 
 }
 
+@font-face {
+	font-family: 'Roboto Mono';
+	src: local('Roboto Mono'), local('RobotoMono-Regular'), url('../../files/RobotoMono-Regular.woff2') format('woff2');
+	font-style: normal;
+	font-weight: 400;
+}
+
+@font-face {
+	font-family: 'Inter';
+	font-style: normal;
+	font-weight: 400;
+	src: local('Inter-Regular'), url("../../files/Inter-Regular.woff2?v=3.6") format("woff2");
+}
+
+@font-face {
+	font-family: 'Inter';
+	font-style: normal;
+	font-weight: 600;
+	src: local('Inter-SemiBold'), url("../../files/Inter-SemiBold.woff2?v=3.6") format("woff2");
+}
+
+html {
+	font-family: 'Inter', sans-serif;
+	font-size: var(--font-size);
+	line-height: var(--line-height);
+}
+
 body {
-  margin: 0;
-  font-family: var(--article-font-family);
-  font-size: 19px;
-  line-height: 150%;
-  padding: var(--page-padding);
+	color: var(--text-color);
+	tab-size: 4;
+	overflow: auto;
+	max-width: var(--max-width);
+	margin: 0 auto;
+	padding-top: var(--page-padding);
+	padding-bottom: var(--page-padding);
+	padding-right: var(--page-padding);
+	padding-left: calc(var(--page-padding) + var(--panel-width));
+	word-break: break-word;
+}
+
+a {
+	color: var(--color-blue);
+	cursor: pointer;
+	text-decoration: none;
 }
 
-p + p {
-  margin-top: 1.5em;
+h1 {
+	font-size: 40px;
+	line-height: 48px;
+	font-weight: normal;
+	margin-left: -2px;
+	margin-top: 16px;
+	margin-bottom: -8px;
 }
+
+p {
+	margin-top: 16px;
+	margin-bottom: 16px;
+	padding-right: 16px;
+}
+
 li > p {
   width: calc(100% - 2em);
 }
@@ -53,23 +122,24 @@ table {
 pre {
   background: rgb(143, 140, 140);
   padding: 1em;
+	position: relative;
 }
 pre>code {
   white-space: inherit;
   background: none;
 }
 pre.prettyprint {
-    margin-top: 2em !important;
-    margin-bottom: 2em !important;
-    position: relative;
+  margin-top: 2em !important;
+  margin-bottom: 2em !important;
+  position: relative;
 }
 pre.prettyprint li {
-    white-space: pre;
+  white-space: pre;
 }
 pre.prettyprint code, .dos {
-    color: #CCC;
-    font-family: var(--code-block-font-family);
-    display: block;
+  color: #CCC;
+  font-family: var(--code-block-font-family);
+  display: block;
 }
 
 /* to handle long words in paragraph */
@@ -118,14 +188,8 @@ div[data-diagram] {
 }
 
 .threejs_navbar>div,
-.lesson-title,
 .lesson-comments,
 .lesson-comment-sep,
-.lesson-main>* {
-    margin: 0 auto 1em;
-    max-width: 700px;
-    width: calc(100% - 40px);
-}
 .lesson-main>h1:not(:first-child),
 .lesson-main>h2:not(:first-child),
 .lesson-main>h3:not(:first-child),
@@ -178,10 +242,6 @@ div[data-diagram] {
     background-color: #DEF;
     padding: 1em;
 }
-.lesson-title {
-    margin-top: 3em;
-    margin-bottom: 2em;
-}
 .lesson-sidebar {
     font-size: small;
     columns: 220px;
@@ -202,19 +262,10 @@ div[data-diagram] {
     padding-left: 1em;
     text-indent: -1em;
 }
-h1, h2, h3, h4 {
-  font-family: var(--headline-font-family);
-  line-height: 1.2;
-}
-h3 {
-  font-size: medium;
-}
 code {
     color: black;
-    font-family: var(--code-font-family);
     background-color: #ddd;
     padding: 0.1em 0.2em 0.1em 0.2em;
-    border-radius: 0.5em;
     white-space: nowrap;
 }
 
@@ -325,10 +376,9 @@ iframe.external_diagram {
 }
 
 div.threejs_bottombar {
-  border: 1px solid #000;
   background-color: #def;
-  padding: 1em;
-  width: calc(100% - 80px);
+  margin-top: var(--page-padding);
+  outline: var(--page-padding) solid #def;
 }
 div.threejs_bottombar>h3 {
   font-size: x-large;
@@ -339,150 +389,12 @@ div.threejs_bottombar code {
     background-color: #ccc;
 }
 
-/* --- Prettify --- */
-pre.prettyprint .nocode { background-color: none; color: #FFF }
-pre.prettyprint .str { color: #b9ca4a } /* string          */
-pre.prettyprint .kwd { color: #c397d8 } /* keyword         */
-pre.prettyprint .com { color: #f3efb2 } /* comment         */
-pre.prettyprint .typ { color: #7aa6da } /* type            */
-pre.prettyprint .lit { color: #45e7a6 } /* literal         */
-pre.prettyprint .pun { color: #7ecce0 } /* punctuation     */
-pre.prettyprint .pln { color: #eaeaea } /* plaintext       */
-pre.prettyprint .tag { color: #d54e53 } /* html/xml tag    */
-pre.prettyprint .atn { color: #e78c45 } /* attribute name  */
-pre.prettyprint .atv { color: #70c0b1 } /* attribute value */
-pre.prettyprint .dec { color: #e78c45 } /* decimal         */
-pre.prettyprint .var { color: #d54e53 } /* variable name   */
-pre.prettyprint .fun { color: #7aa6da } /* function name   */
-foo{ color: #FF8080}
-pre.prettyprint ul.modifiedlines {
-    list-style-type: none;
-    padding-left: 0;
-}
-pre.prettyprint ul.modifiedlines li.linemodified {
-    list-style-type: none;
-    background-color: #324840;
-}
-pre.prettyprint ul.modifiedlines li.linedeleted {
-    list-style-type: none;
-    background-color: #4c1414;
-    text-decoration: line-through;
-}
-
-pre.prettyprint ul.modifiedlines li.lineadded {
-    list-style-type: none;
-    background-color: #3f4463;
-}
-
-
-pre.prettyprint, code.prettyprint, .dos {
-    color: #FFF;
-    background: #222;
-    border: 1px solid #000;
-    box-shadow: 10px 10px 0px #ccc;
-    font-size: 9pt;
-    font-family: var(--code-block-font-family);
-    margin: auto;
-    padding: 1em;
-    text-align: left;           /* override justify on body */
-    /* this was disabled until 2016-08-26 but I don't know why */
-    overflow: auto;             /* allow scroll bar in case of long lines - goes together with white-space: nowrap! */
-    white-space: pre;        /* was nowrap, prevent line wrapping */
-    line-height: 1.5em;
-    width: calc(100% - 80px);
-}
-
 .dos {
+  color: var(--text-color);
   line-height: 1;
 }
 
-pre.prettyprint.lighttheme, code.prettyprint.lighttheme {
-    color: #222;
-    background: #fff;
-    border: 1px solid #888;
-    box-shadow: none;
-}
-
-pre.prettyprint.lighttheme .str { color: #183691; }  /* string content */
-pre.prettyprint.lighttheme .kwd { color: #a71d5d; }  /* keyword */
-pre.prettyprint.lighttheme .com { color: #969896; }  /* comment */
-pre.prettyprint.lighttheme .typ { color: #0086b3; }  /* type name */
-pre.prettyprint.lighttheme .lit { color: #0086b3; }  /* literal value */
-pre.prettyprint.lighttheme .pun { color: #333; }  /* punctuation */
-pre.prettyprint.lighttheme .opn { color: #333; }  /* lisp open bracket */
-pre.prettyprint.lighttheme .clo { color: #333; }  /* lisp close bracket */
-pre.prettyprint.lighttheme .tag { color: #000080; }  /* markup tag name */
-pre.prettyprint.lighttheme .atn { color: #795da3; }  /* markup attribute name */
-pre.prettyprint.lighttheme .atv { color: #183691; }  /* markup attribute value */
-pre.prettyprint.lighttheme .dec { color: #333; }  /* declaration */
-pre.prettyprint.lighttheme .var { color: #008080; }  /* variable name */
-pre.prettyprint.lighttheme .fun { color: #900; }  /* function name */
-
-@media print {
-    pre.prettyprint .str, code.prettyprint .str{color:#060}
-    pre.prettyprint .kwd, code.prettyprint .kwd{color:#006;font-weight:bold}
-    pre.prettyprint .com, code.prettyprint .com{color:#600;font-style:italic}
-    pre.prettyprint .typ, code.prettyprint .typ{color:#404;font-weight:bold}
-    pre.prettyprint .lit, code.prettyprint .lit{color:#044}
-    pre.prettyprint .pun, code.prettyprint .pun{color:#440}
-    pre.prettyprint .pln, code.prettyprint .pln{color:#000}
-    pre.prettyprint .tag, code.prettyprint .tag{color:#006;font-weight:bold}
-    pre.prettyprint .atn, code.prettyprint .atn{color:#404}
-    pre.prettyprint .atv, code.prettyprint .atv{color:#060}
-    pre.prettyprint, code.prettyprint {
-        color: #000;
-        background: #EEE;
-        font-size: 8pt;
-        font-family: var(--code-block-font-family);
-        width: 95%;
-        margin: auto;
-        padding: 1em;
-        text-align: left;           /* override justify on body */
-        overflow: visible;
-        white-space: pre;        /* was nowrap, prevent line wrapping */
-        line-height: 1.5;
-    }
-
-    pre.prettyprint ul.modifiedlines li.linemodified {
-        list-style-type: none;
-        background-color: #DDD;
-    }
-    pre.prettyprint ul.modifiedlines li.linedeleted {
-        list-style-type: none;
-        background-color: #CCC;
-        text-decoration: line-through;
-    }
-
-    pre.prettyprint ul.modifiedlines li.lineadded {
-        list-style-type: none;
-        background-color: #EEE;
-    }
-
-    body {
-        margin: 10mm;
-    }
-    .doubleSpace p {
-        line-height: 2.5;
-        font-size: x-large;
-    }
-    .doubleSpace pre.prettyprint {
-        font-size: 14pt;
-    }
-    .threejs_navbar,
-    .lesson-comment-sep,
-    .lesson-sidebar,
-    .lesson-comments {
-        display: none;
-    }
-}
-
 @media (max-width: 720px) {
-    body {
-        font-size: 16px;
-    }
-    h1 {
-        font-size: 24px;
-    }
     .threejs_example {
         max-height: 400px;
     }
@@ -498,34 +410,51 @@ pre.prettyprint.lighttheme .fun { color: #900; }  /* function name */
 }
 
 @media all and ( min-width: 1700px ) {
-  :root {
-    --page-padding: 28px;
-  }
+
+	:root {
+		--panel-width: 360px;
+		--font-size: 18px;
+		--line-height: 28px;
+		--max-width: 880px;
+		--page-padding: 28px;
+		--icon-size: 24px;
+	}
+
+	h1 {
+		font-size: 42px;
+		line-height: 50px;
+	}
+
 }
 
 @media all and ( max-width: 640px ) {
-  :root {
-    --page-padding: 16px;
-  }
+
+	:root {
+		--page-padding: 16px;
+		--icon-size: 24px;
+	}
+
+	body {
+		padding: var(--page-padding);
+	}
+
+	h1 {
+		font-size: 28px;
+		line-height: 36px;
+		padding-right: 20px;
+		margin-top: 0;
+	}
+
 }
 
 @media (prefers-color-scheme: dark) {
+
   html {
     scrollbar-color: hsl(0, 0%, 35%) hsl(0, 0%, 13%);
   }
-  body {
-    background: #333;
-    color: #CCC;
-  }
-  a {
-    color: #56d3fd;
-  }
   .warning {
     background: darkred;
   }
-  pre.prettyprint, code.prettyprint, .dos {
-    box-shadow: 10px 10px 0px #292929;
-  }
   code {
     background: #666;
     color: #CCC;
@@ -551,6 +480,7 @@ pre.prettyprint.lighttheme .fun { color: #900; }  /* function name */
   }
   div.threejs_bottombar {
     background-color: #1b1b44;
+    outline: var(--page-padding) solid #1b1b44;
   }
   div.threejs_bottombar code {
     background-color: #348;
@@ -564,4 +494,5 @@ pre.prettyprint.lighttheme .fun { color: #900; }  /* function name */
     border: none;
     padding: 3px;
   }
+
 }