diff --git a/docs/framework/angular.md b/docs/framework/angular.md
new file mode 100644
index 0000000000000000000000000000000000000000..2598672a43a33a57cc1865eb1e0f60372591f374
--- /dev/null
+++ b/docs/framework/angular.md
@@ -0,0 +1,99 @@
+# AngularJS: Overview
+
+AngularJS is a client-side framework for development of rich web
+applications.  The core CiviCRM application uses AngularJS for several
+administrative screens, and extensions increasingly use AngularJS for
+"leaps" that add or replace major parts of the application.
+
+This documentation aims to explain how AngularJS works within a CiviCRM
+context.
+
+## Two cultures
+
+CiviCRM is an extensible PHP application (similar to Drupal, Joomla, or
+WordPress).  In this culture, the common expectation is that an
+*administrator* installs the main application.  To customize it, they
+download, evaluate, and configure a set of business-oriented modules.  The
+administrator's workflow is dominated by web-based config screens and CLI
+commands.
+
+AngularJS is a frontend, Javascript development framework.  In this culture,
+the expectation is that a *developer* creates a new application.  To
+customize it, they download, evaluate, and configure a set of
+function-oriented libraries.  The developer's workflow is dominated by CLI's
+and code.
+
+The CiviCRM-AngularJS integration must balance the expectations of these
+two cultures.  The balance works as follows:
+
+ * __JS+HTML__: The general structure of the Javascript and HTML files
+   should meet the frontend developers' expectations.  These files should be
+   grounded in the same notations and concepts as the upstream AngularJS
+   framework.  (This means that AngularJS is not abstracted, wrapped, or
+   mapped by an intermediary like HTML_QuickForm, Symfony Forms or Drupal
+   Form API.)
+ * __Build__: The process of building or activating modules should meet
+   administrators' expectations.  They should be managed by the PHP
+   application.  (This means that you won't see `gulp` or `grunt` managing
+   the final build -- because PHP logic fills that role.)
+ * __Web Services__: The general structure of web-services should meet
+   the backend developers' expectations. These are implemented in PHP
+   (typically with CiviCRM APIv3).
+
+## Basics
+
+AngularJS is a client-side Javascript framework, and it interacts with
+CiviCRM in two major ways.  To see this, let's consider an example AngularJS
+page -- it's an HTML document that looks a lot like this:
+
+```html
+<!-- URL: https://example.org/civicrm/a -->
+ 1: <html>
+ 2: <head>
+ 3:   <script type="text/javascript" src="**all the Javascript files**"></script>
+ 4:   <link rel="stylesheet" href="**all the CSS files**" />
+ 5: </head>
+ 6: <body>
+ 7:   <div>...site wide header...</div>
+ 8:   <div ng-app="crmApp"></div>
+ 9:   <div>...site wide footer...</div>
+10: </body>
+11: </html>
+```
+
+The first interaction comes when CiviCRM generates the initial HTML page:
+
+ * CiviCRM listens for requests to the path `civicrm/a`. (It does this in a
+   way which is compatible with multiple CMSs -- Drupal, Joomla, WordPress, etc.)
+ * CiviCRM builds the list of JS/CSS files in lines 3-4.  (It does this in a
+   way which allows extensions to add new JS/CSS files.)
+ * CiviCRM ensures that the page includes the site-wide elements, such as
+   lines 7 and 9. (It does this in a way which is compatible with multiple CMSs.)
+
+Once the page is loaded, it works just like any AngularJS 1.x application.
+It uses concepts like `ng-app`, "module", "directive", "service", "component", and
+"partial".
+
+!!! seealso "Read more about AngularJS 1.x"
+    A good resource for understanding AngularJS concepts is [the
+    official AngularJS tutorial](https://code.angularjs.org/1.5.11/docs/tutorial).
+
+The second interaction comes when the AngularJS application loads or stores
+data.  This uses the CiviCRM API.  Key concepts in CiviCRM API include
+"entity", "action", "params", the "API Explorer", and the bindings for PHP/Javascript/CLI.
+
+!!! seealso "Read more about CiviCRM API"
+    A good resource for understanding CiviCRM API concepts is the [APIv3:
+    Intro](/api/general.md).
+
+In the remainder of this document, we'll try to avoid in-depth discussion
+about the internals of AngularJS 1.x or APIv3.  You should be able to follow
+the discussion if you have a beginner-level understanding of both.
+
+
+## Additional pages
+
+ * [Quick Start](angular/quickstart.md): How to create a new screen in the CiviCRM-Angular UI
+ * [File Names](angular/files.md): How AngularJS files are named in `civicrm-core` and `civix`
+ * [Loader](angular/loader.md): How JS/CSS files are loaded
+ * [Modifications](angular/modify.md): How a third-party can modify the content of a CiviCRM-Angular UI
diff --git a/docs/framework/angular/files.md b/docs/framework/angular/files.md
new file mode 100644
index 0000000000000000000000000000000000000000..0fc28b31aad85fad34383643a5eab1d293c3d4b4
--- /dev/null
+++ b/docs/framework/angular/files.md
@@ -0,0 +1,70 @@
+# AngularJS: File names
+
+As a developer working with CiviCRM-Angular, you write *Angular modules* --
+these modules are composed of various JS/CSS/HTML files which define the
+*services*, *directives*, *controllers*, and *HTML partials*.
+
+For sake of predictability, these files follow a naming convention.  All
+major Angular files are placed in the `ang/` folder.
+
+!!! note "How does this work with `civix`?"
+    When you generate Angular code via `civix`, the files are
+    named according to convention.
+
+    One of the files, `ang/{mymodule}.ang.php` provides instructions for the
+    file-loader.
+
+!!! note "What if my code doesn't follow the naming convention? What if I don't use `civix`?"
+    The file-loader needs some information about the name and location of
+    your AngularJS code, but you don't need to follow the convention.  You
+    can configure it via hook.  See: [AngularJS: Loading](/framework/angular/loader.md).
+
+## Abridged convention
+
+Some Angular modules have a very narrow purpose -- such as defining a
+singular `service` or `directive`. These modules only have 2 or 3 files.
+
+   * `ang/{mymodule}.ang.php` - General metadata about the module (per [hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md)).
+   * `ang/{mymodule}.js` - All Javascript for the module
+   * `ang/{mymodule}.css` - All CSS for the module (if applicable)
+
+## Full convention
+
+Some Angular modules have broader purpose -- such as defining a new screen
+with a series of related `directive`s, `controller`s, and `service`s.  Each
+of these elements may have multiple aspects (JS/HTML/CSS).
+
+__Module Files__
+
+   * `ang/{mymodule}.ang.php` - General metadata about the module (per [hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md)).
+   * `ang/{mymodule}.js` - General metadata about the module.
+   * `ang/{mymodule}.css` - General CSS that applies throughout the module.
+
+__Directive Files__
+
+   * `ang/{mymodule}/{FooBar}.js` - The declaration and logic for a directive named `mymoduleFooBar` or `<div mymodule-foo-bar>`.
+   * `ang/{mymodule}/{FooBar}.html` - The main/default template for the directive (if applicable).
+   * `ang/{mymodule}/{FooBar}/{Extra}.html` - If you have multiple templates used by the same directive (e.g. via `ng-include` or conditional logic), then put them in a subdir.
+   * `ang/{mymodule}/{FooBar}.css` - Any CSS specifically intended for `mymoduleFooBar` (if applicable).
+
+__Controller Files__ (These follow the same convention as directives, but they have the suffix `Ctrl`.)
+
+   * `ang/{mymodule}/{FooBar}Ctrl.js` - The declaration and logic for a controller named `MymoduleFooBarCtrl`.
+   * `ang/{mymodule}/{FooBar}Ctrl.html` - The main/default template for the controller (if applicable).
+   * `ang/{mymodule}/{FooBar}Ctrl/{Extra}.html` - If you have multiple templates used with the same controller (e.g. via `ng-include` or conditional logic), then put them in a subdir.
+   * `ang/{mymodule}/{FooBar}Ctrl.css` - Any CSS specifically intended for `MymoduleFooBarCtrl` (if applicable).
+
+__Service Files__
+
+   * `ang/{mymodule}/{FooBar}.js` - The declaration and logic for a service named `mymoduleFooBar`.
+
+!!! tip "Use tilde (`~`) to load HTML templates"
+    When writing code for Angular, you might use an expression like
+    `{templateUrl: 'https://example.org/FooBar.html'}`.  However,
+    constructing a full URL that works in every Civi deployment would be
+    complex.  Instead, use the tilde prefix.  For example, `{templateUrl: '~/mymodule/FooBar.html'}`.
+		
+<!--
+ Proposed Amendment
+ Put documentation and examples for each directive or controller in a `*.md` file, adjacent to the `*.js` file. The format is handy for reading/writing/code-snippets, and it won't bloat the final `*.js` output.
+-->
diff --git a/docs/framework/angular/loader.md b/docs/framework/angular/loader.md
new file mode 100644
index 0000000000000000000000000000000000000000..05bf34151818aa266f6bb6e74fcd60e083fdc6e0
--- /dev/null
+++ b/docs/framework/angular/loader.md
@@ -0,0 +1,94 @@
+# AngularJS: Loader
+
+What happens when a user visits a CiviCR-Angular page, such as
+`https://example.org/civicrm/a/#/mailing/new`? Broadly speaking, two steps:
+
+ 1. (Server-side) CiviCRM processes the request for `civicrm/a`. It
+    displays a web-page with all your Angular modules.
+ 2. (Client-side) AngularJS processes the request for `mailing/new`.
+    It uses an HTML template to setup the UI.
+
+The client-side behavior is well-defined by Angular
+[ngRoute](https://docs.angularjs.org/api/ngRoute).  We'll explore the
+server-side in greater depth because that is unique to the CiviCRM-Angular
+integration.
+
+## The default base page (`civicrm/a`)
+
+CiviCRM includes a default base-page -- any module can add new routes on
+this page.  For example, the `crmMailing` module defines a route
+`mailing/new`. You can view this at:
+
+ * `https://example.org/civicrm/a/#/mailing/new`
+
+The default base-page is special because *all registered Angular modules
+will be included by default*.  You can expect the markup to look roughly
+like this:
+
+```html
+<html>
+<head>
+<script type="text/javascript" src="https://example.org/.../angular.js"></script>
+<script type="text/javascript" src="https://example.org/.../angular-route.js"></script>
+<script type="text/javascript" src="https://example.org/.../crmApp.js"></script>
+<script type="text/javascript" src="https://example.org/.../crmCaseType.js"></script>
+<script type="text/javascript" src="https://example.org/.../crmMailing.js"></script>
+<script type="text/javascript" src="https://example.org/.../crmUi.js"></script>
+...
+<link rel="stylesheet" href="https://example.org/.../crmUi.css" />
+...
+</head>
+<body>
+  <div ng-app="crmApp"></div>
+</body>
+</html>
+```
+
+The PHP application instantiates `AngularLoader`
+
+```php
+$loader = new \Civi\Angular\AngularLoader();
+$loader->setPageName('civicrm/a');
+$loader->setModules(array('crmApp'));
+$loader->load();
+```
+
+The `load()` function determines the necessary JS/CSS/HTML/JSON resources
+and loads them on the page. Roughly speaking, it outputs:
+
+
+
+More specifically, the `load()` function gets a list of all available
+Angular modules (including their JS/CSS/HTTML files). Then it loads the
+files for `crmApp` as well as any dependencies (like `crmUi`).
+
+The most important thing to understand is how it *gets the list of Angular
+modules*.  A few Angular modules are bundled with core (eg `crmUi` or
+`crmUtil`), but most new Angular modules should be loaded via
+[hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md)
+
+For example, if you created an extension `org.example.foobar` with an
+Angular module named `myBigAngularModule`, then the hook might look like:
+
+```php
+/**
+ * Implements hook_civicrm_angularModules.
+ */
+function foobar_civicrm_angularModules(&$angularModules) {
+  $angularModules['myBigAngularModule'] = array(
+    'ext' => 'org.example.foobar',
+    'basePages' => array('civicrm/a'),
+    'requires' => array('crmUi', 'crmUtils', 'ngRoute'),
+    'js' => array('ang/myBigangularModule/*.js'),
+    'css' => array('ang/myBigangularModule/*.css'),
+    'partials' => array('ang/myBigangularModule'),
+  );
+}
+```
+
+!!! tip "`civix` code-generator"
+    In practice, you usually don't need to implement.  The `civix`
+    code-generator creates a file named `ang/{mymodule}.ang.php` and
+    automatically loads as part of `hook_civicrm_angularModules`.
+
+
diff --git a/docs/framework/angular/modify.md b/docs/framework/angular/modify.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc0ca5f4385364077b4147d32e6bd650668284fb
--- /dev/null
+++ b/docs/framework/angular/modify.md
@@ -0,0 +1,14 @@
+# AngularJS: Alteration
+
+```php
+function example_civicrm_alterAngular($angular) {
+  $angular->add(\Civi\Angular\ChangeSet::create('mychanges')
+    ->alterHtml('~/crmMailing/EditMailingCtrl/2step.html', function(phpQueryObject $doc) {
+      $doc->find('[ng-form="crmMailingSubform"]')->attr('cat-stevens', 'ts(\'wild world\')');
+    })
+  );
+}
+```
+
+
+cv ang:html:show
\ No newline at end of file
diff --git a/docs/framework/angular/quickstart.md b/docs/framework/angular/quickstart.md
new file mode 100644
index 0000000000000000000000000000000000000000..7c1fde4b323407a67139e596faf48349226cfd21
--- /dev/null
+++ b/docs/framework/angular/quickstart.md
@@ -0,0 +1,120 @@
+# AngularJS: Quick Start
+
+Let's create a new CiviCRM extension with an AngularJS page. It will present
+a small "About Me" screen.
+
+## Create a CiviCRM extension
+
+First, we'll need a skeletal CiviCRM extension:
+
+```
+$ civix generate:module org.example.aboutme
+Initalize module org.example.aboutme
+Write org.example.aboutme/info.xml
+Write org.example.aboutme/aboutme.php
+Write org.example.aboutme/aboutme.civix.php
+Write org.example.aboutme/LICENSE.txt
+```
+
+## Create an Angular module
+
+Of course, AngularJS also has its own module system -- any Angular routes,
+directives, or services need to live within an Angular `module`.  Let's
+create one.
+
+```
+$ cd org.example.aboutme
+$ civix generate:angular-module
+Initialize Angular module "aboutme"
+Write ang/aboutme.ang.php
+Write ang/aboutme.js
+Write ang/aboutme.css
+```
+
+!!! tip "Tip: Angular module names"
+    By default, `civix` assumes that your Angular module name matches your
+    extension name.  In this case, both are named `aboutme`.  However, this
+    is not required -- the option `--am` can specify a different name.  This
+    can be useful if you want to organize your code into multiple modules.
+
+
+The first file, `ang/aboutme.ang.php`, configures the file-loader:
+
+```php
+return array(
+  'requires' => array('crmUi', 'crmUtil', 'ngRoute'),
+  'js' => array(
+    'ang/aboutme.js',
+    'ang/aboutme/*.js',
+    'ang/aboutme/*/*.js',
+  ),
+  'css' => array ('ang/aboutme.css'),
+  'partials' => array('ang/aboutme'),
+  'settings' => array(),
+);
+```
+
+And the second file, `ang/aboutme.js`, declares the Angular module's dependencies.
+
+```js
+  angular.module('aboutme', [
+    'crmUi', 'crmUtil', 'ngRoute'
+  ]);
+```
+
+!!! tip "Tip: angular.module() and angular.crmDepends()"
+    The list of dependencies is declared once in PHP and once in JS.  To
+    remove this duplication, change `angular.module('aboutme',...)` to
+    `angular.crmDepends('aboutme');`
+
+!!! note "Note: `ang/` folder"
+    By convention, AngularJS source code is stored in the `ang/` folder.
+    The convention is discussed in more detail in [AngularJS: File
+    Names](/framework/angular/files.md)
+
+## Add an Angular route, etal
+
+Now let's add a new Angular-based page.  This page will require a `route`
+with a `controller` and an HTML template.  The command `civix
+generate:angular-page` will create each of these:
+
+```
+$ civix generate:angular-page EditCtrl about/me
+Initialize Angular page "AboutmeEditCtrl" (civicrm/a/#/about/me)
+Write ang/aboutme/EditCtrl.js
+Write ang/aboutme/EditCtrl.html
+```
+
+If you inspect the code, you'll find a basic AngularJS app which uses
+`$routeProvider`, `angular.module(...).controller(...)`, and so on.
+
+The generated code will display a small "About Me" screen with the current
+user's first-name and last-name.
+
+!!! tip "Tip: Flush caches _or_ enable debug mode"
+    By default, CiviCRM aggregates AngularJS files and caches them.  You can
+    flush this cache manually (`cv flush`).  However, it may be easier to
+    disable some of the aggregation/caching features by [enabling debug
+    mode](/dev-tools/debugging.md).
+
+## Open the page
+
+Finally, we'd like to take a look at this page in the web-browser.
+
+By default, CiviCRM combines all Angular modules into one page, `civicrm/a`.
+The URL of this page depends on your system configuration.  Here are a few
+examples:
+
+```
+# Example: Lookup the URL on Drupal 7
+$ cv url 'civicrm/a/#/about/me'
+"http://dmaster.l/civicrm/a/#/about/me"
+
+# Example: Lookup the URL on WordPress
+$ cv url 'civicrm/a/#/about/me'
+"http://wpmaster.l/wp-admin/admin.php?page=CiviCRM&q=civicrm/a/#/about/me"
+```
+
+!!! tip "Tip: Open the browser from the command-line"
+    If you're developing locally on a Linux/OSX workstation, pass the
+    option `--open` to automatically open the page in a web browser.