diff --git a/API.txt b/API.txt
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a6589524f38c81d77986e261db16fdbdb6ade388 100644
--- a/API.txt
+++ b/API.txt
@@ -0,0 +1,125 @@
+The API for expanding the panels module comes in two pieces. First there is the
+layout API, which adds to the list of layouts you need. Second is the content
+types API, which lets modules supply content to the panels. Natively, panels
+module supports the content types of 'block', which just renders the output
+of a block, 'node' which simply renders a node_view, 'custom' which allows the
+user to enter custom content with filtering, and finally 'views' because I
+wrote them both.
+
+Where to put your code:
+=======================
+
+With both types, there are two ways to implement a new type. First, you can
+implement the hook in your module and provide the necessary data. Or you
+can create a .inc file in the right format, and drop it into the proper
+directory in the panels module. Both are very similar, and only requires
+a minor naming adjustment.
+
+When using the .inc file, in place of 'hook' in the various hooks, use
+panels_FILENAME.
+
+Creating a new Layout Type:
+===========================
+
+A layout consists of 4 things:
+
+1) A bit of HTML in a theme function. I use heredoc notation to make it
+ extra easy to convert these to .tpl.inc files in case they are to
+ be overridden in php template.
+2) A bit of CSS to describe how the layout should be, well, laid out.
+3) An icon that is 50x75 which gives the user a visual indication of
+ what the layout looks like.
+4) An implementation of hook_panels_layouts() to tell panels the necessary
+ information.
+
+hook_panels_layouts returns an array with the following information:
+
+'module' => The module name providing this. This is necessary because it
+ uses drupal_get_path('module', $module) to get the proper
+ path for included CSS.
+'title' => The title of the layout presented to the user. Use t().
+'icon' => The filename of the icon to use when listing avialable layouts.
+'theme' => The theme function that contains the HTML, without the theme_
+ part.
+'css' => The CSS file.
+'content areas' => an array in the form of 'name' => t('Title') of content
+ areas supported by the layout. For example, the simple
+ 2 column layout uses array('left' => t('Left side'),
+ 'right' => t('Right side')); -- the name is the internal
+ identifier. Your theme function will see it as
+ $content['name'] (so twocol gets $content['left'] and
+ $content['right']).
+
+
+Creating a new Content Type:
+============================
+
+Content types require 1 hook and two callbacks. The hook defines what content
+types are available, the first callback displays the content in a dashboard,
+and the other callback does all of the administrative functions.
+
+hook_panels_content_types returns an array with the following information:
+'callback' => The function to display the content.
+'admin' => The function to administer the content.
+
+The callback function receives one argument: The $configuration array, as
+defined by the administrative callback.
+
+The administrative callback recieves 3 arguments:
+
+$op -- the operation to perform. See below.
+&$arg1 -- The first argument should be a reference and its meaning varies
+ based on the op.
+$arg2 -- The second argument is optional, not a reference, and should
+ default to NULL.
+
+Administrative operations:
+
+'list': $arg1 is the configuration array.
+ This op is called when panels lists what content is in a content
+ area. It generally returns something similar to this:
+ return 'Views: ' . $view->name . ' (' . $view->description . ')';
+
+'add button': arguments not used here.
+ This op is called to display the 'add content type' button; it can also
+ display additional information (such as the list of blocks or the
+ autocomplete to select a node).
+
+ The actual button should look something like this:
+ $form['submit'] = array(
+ '#type' => 'button',
+ '#value' => t('Add view'),
+ );
+
+ And it's a good idea to do this, but it's not required:
+
+ $form['#prefix'] = '
';
+ $form['#suffix'] = '
';
+
+'add': $arg1 == the $configuration array
+ This op is called to see if your add button has been clicked. It *must*
+ start off by checking to see if this is true:
+
+ if ($_POST['op'] != t('Add view')) {
+ return;
+ }
+
+ If it is true, it should process that information and return a $configuration
+ array populated from whatever other form items were presented in 'add button'
+ and whatever defaults make sense.
+
+'edit': $arg1 == the $configuration array
+ This op is called to provide an edit form for a content type. It *must*
+ ensure *all* information from the conf array is available, even if it
+ is just hidden; panels has no way to remember this data between form
+ clicks, so any data not put here will be lost. No buttons need to be
+ added to the form.
+
+'validate': $arg1 == $form_values, $arg2 == $form
+ Called to validate the 'edit' form above.
+
+'save': $arg1 == $form_values
+ Called to convert a $form_values back into a $configuration array. All
+ of the default types just send $form_values back as $configuration,
+ but if you need to do some kind of transformation, this is where it
+ happens.
diff --git a/README.txt b/README.txt
index d41f6697ddb10fc11c6d9c5b4fda0ae70bd4ddbf..131f305015eae7011aa5986cf193d672d75bfce4 100644
--- a/README.txt
+++ b/README.txt
@@ -9,4 +9,10 @@ file without breaking it.
Perhaps most importantly, unlike the dashboard module it requires no fiddling
with PHP code to include the things you want; the interface lets you add blocks,
-nodes and custom content just by selecting and clicking.
\ No newline at end of file
+nodes and custom content just by selecting and clicking.
+
+If you want to override the CSS of a panel, the easiest way is to just copy
+the CSS into your theme directory and tweak; panels will look there before
+including the CSS from the module, and if it exists, will not include the
+module's CSS. If you want to just change a tiny bit but keep the basic
+structure, just add your changes to your style.css instead.
\ No newline at end of file
diff --git a/TODO.txt b/TODO.txt
index 16a7341b4e9db37d11f90501f571df0c67caf412..6022dd147c22cc50bb27f9b5feb0addf148d5aab 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,14 +1,12 @@
TODO:
-? content type: phptemplate
+This is a brief list of the things that may still need to be done. No guarantee
+of them ever getting done.
+
+content type: phptemplate
-content templates:
- 1 x 2 x 1
- 3 col -- even
access control to pages
access control to content types
dashboard node extension
-write help
-document plugin API
diff --git a/layouts/threecol_25_50_25.inc b/layouts/threecol_25_50_25.inc
index 821137ff0cedb545b811ed4185ee1ea19e8fff35..b3c16fd61f02239e3dde82aacbe3153bf7ab1e76 100644
--- a/layouts/threecol_25_50_25.inc
+++ b/layouts/threecol_25_50_25.inc
@@ -5,7 +5,6 @@
function panels_threecol_25_50_25_panels_layouts() {
$items['threecol_25_50_25'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Three column 25/50/25'),
'icon' => 'layouts/threecol_25_50_25.png',
'theme' => 'panels_threecol_25_50_25',
diff --git a/layouts/threecol_25_50_25_stacked.inc b/layouts/threecol_25_50_25_stacked.inc
index f03b0f48be165869a8eab8e5d5474039b0b97a4f..e8ae62c670422e446d89e625de6799003084b5d9 100644
--- a/layouts/threecol_25_50_25_stacked.inc
+++ b/layouts/threecol_25_50_25_stacked.inc
@@ -7,7 +7,6 @@
function panels_threecol_25_50_25_stacked_panels_layouts() {
$items['threecol_25_50_25_stacked'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Three column 25/50/25 stacked'),
'icon' => 'layouts/threecol_25_50_25_stacked.png',
'theme' => 'panels_threecol_25_50_25_stacked',
diff --git a/layouts/threecol_33_34_33.inc b/layouts/threecol_33_34_33.inc
index 429db3868b8572ac629058799ab0e0669875f20c..b732e705fa4657f613ee73dc59eb5cb1443b8ab3 100644
--- a/layouts/threecol_33_34_33.inc
+++ b/layouts/threecol_33_34_33.inc
@@ -6,7 +6,6 @@
function panels_threecol_33_34_33_panels_layouts() {
$items['threecol_33_34_33'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Three column 33/34/33'),
'icon' => 'layouts/threecol_33_34_33.png',
'theme' => 'panels_threecol_33_34_33',
diff --git a/layouts/threecol_33_34_33_stacked.inc b/layouts/threecol_33_34_33_stacked.inc
index 4af9abcb390778e9ba5dd09564202fbf36ca2bca..fd34a34cf94f6b752572581c808623c7c72eb669 100644
--- a/layouts/threecol_33_34_33_stacked.inc
+++ b/layouts/threecol_33_34_33_stacked.inc
@@ -7,7 +7,6 @@
function panels_threecol_33_34_33_stacked_panels_layouts() {
$items['threecol_33_34_33_stacked'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Three column 33/34/33 stacked'),
'icon' => 'layouts/threecol_33_34_33_stacked.png',
'theme' => 'panels_threecol_33_34_33_stacked',
diff --git a/layouts/twocol.inc b/layouts/twocol.inc
index 28e6a5efc18d81dedd1faa7fb2aa6e2572fc0d7c..01f6a3c970b83e0470543e7fbbe8c7b9fdbd13de 100644
--- a/layouts/twocol.inc
+++ b/layouts/twocol.inc
@@ -6,7 +6,6 @@
function panels_twocol_panels_layouts() {
$items['twocol'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Two column'),
'icon' => 'layouts/twocol.png',
'theme' => 'panels_twocol',
diff --git a/layouts/twocol_stacked.inc b/layouts/twocol_stacked.inc
index fc1a2c98b14c7c0be5edf10572bb2cfeda4fb75f..72266c71e715850d0e60beece072bad053f21401 100644
--- a/layouts/twocol_stacked.inc
+++ b/layouts/twocol_stacked.inc
@@ -7,7 +7,6 @@
function panels_twocol_stacked_panels_layouts() {
$items['twocol_stacked'] = array(
'module' => 'panels',
- 'path' => 'layouts',
'title' => t('Two column stacked'),
'icon' => 'layouts/twocol_stacked.png',
'theme' => 'panels_twocol_stacked',