This is a common-enough task with the advent of fat clients built on Backbone.JS, Angular, Ember, etc. Clients request data (usually JSON), media, etc. from the server as opposed to pre-rendered HTML, and do rendering and resource management client-side. If you want to go this way so that you can support flexible offline mode the way you specified, you usually need a set of generic loaders and tools in your app cache manifest that will loading the more specific (user-specific, lesson-specific, etc.) resources on page load.
The first time your user opens your app, it should be in online mode, and your app will need to request the specific resources it needs to work well offline and store them in client-side storage (localStorage, indexedDB or what it's trying to replace - WebSQL, and fileSystem. There are many resources on the web on how to use each of these APIs.). This step can also be incremental, rather than a huge download of megabytes of data.
The next time your user opens your page, your app can attempt to load all the resources it needs from client-side storage before even calling the server. It will only need to call the server if it's missing some resources, or if it needs to get a fresher version of a resource, or of course if you need to write to the server. If you did a good job of loading all the resources it needed into client-side storage the first time, it can work decently in offline mode.