diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,8 +7,8 @@
  */
 return array(
   'names' => array(
-    'conpherence.pkg.css' => 'afbb036b',
-    'core.pkg.css' => '1ca373de',
+    'conpherence.pkg.css' => 'a09bcb32',
+    'core.pkg.css' => 'dc6d08e3',
     'core.pkg.js' => '1d376fa9',
     'darkconsole.pkg.js' => 'e7393ebb',
     'differential.pkg.css' => '3fb7f532',
@@ -19,7 +19,7 @@
     'maniphest.pkg.js' => '949a7498',
     'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
     'rsrc/css/aphront/dark-console.css' => 'f54bf286',
-    'rsrc/css/aphront/dialog-view.css' => '913c172e',
+    'rsrc/css/aphront/dialog-view.css' => '593d3f67',
     'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
     'rsrc/css/aphront/list-filter-view.css' => '5d6f0526',
     'rsrc/css/aphront/multi-column.css' => 'fd18389d',
@@ -46,12 +46,13 @@
     'rsrc/css/application/config/setup-issue.css' => 'f794cfc3',
     'rsrc/css/application/config/unhandled-exception.css' => '4c96257a',
     'rsrc/css/application/conpherence/durable-column.css' => '194ac487',
+    'rsrc/css/application/conpherence/header-pane.css' => 'bdba8a5b',
     'rsrc/css/application/conpherence/menu.css' => '67235d90',
-    'rsrc/css/application/conpherence/message-pane.css' => 'ee0e27be',
+    'rsrc/css/application/conpherence/message-pane.css' => 'c075e8fe',
     'rsrc/css/application/conpherence/notification.css' => '6cdcc253',
-    'rsrc/css/application/conpherence/transaction.css' => '2c71247c',
-    'rsrc/css/application/conpherence/update.css' => 'faf6be09',
-    'rsrc/css/application/conpherence/widget-pane.css' => 'a131d5b6',
+    'rsrc/css/application/conpherence/transaction.css' => '46253e19',
+    'rsrc/css/application/conpherence/update.css' => '53bc527a',
+    'rsrc/css/application/conpherence/widget-pane.css' => '827a21f1',
     'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
     'rsrc/css/application/countdown/timer.css' => '16c52f5c',
     'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a',
@@ -108,7 +109,7 @@
     'rsrc/css/core/core.css' => 'd0801452',
     'rsrc/css/core/remarkup.css' => 'cd912f2c',
     'rsrc/css/core/syntax.css' => '769d3498',
-    'rsrc/css/core/z-index.css' => '2b01a823',
+    'rsrc/css/core/z-index.css' => 'a847e919',
     'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
     'rsrc/css/font/font-aleo.css' => '8bdb2835',
     'rsrc/css/font/font-awesome.css' => '2b7ebbcc',
@@ -437,11 +438,11 @@
     'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '01774ab2',
     'rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js' => 'cf86d16a',
     'rsrc/js/application/conpherence/behavior-durable-column.js' => 'd3506890',
-    'rsrc/js/application/conpherence/behavior-menu.js' => '1d45c74d',
+    'rsrc/js/application/conpherence/behavior-menu.js' => '7a2f5952',
+    'rsrc/js/application/conpherence/behavior-participants-pane.js' => '08872fb7',
     'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861',
     'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
-    'rsrc/js/application/conpherence/behavior-toggle-widget.js' => 'b151bbbc',
-    'rsrc/js/application/conpherence/behavior-widget-pane.js' => '65845387',
+    'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '9bdbbab0',
     'rsrc/js/application/countdown/timer.js' => 'e4cc26b3',
     'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => 'edf8a145',
     'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e',
@@ -601,7 +602,7 @@
     'almanac-css' => 'dbb9b3af',
     'aphront-bars' => '231ac33c',
     'aphront-dark-console-css' => 'f54bf286',
-    'aphront-dialog-view-css' => '913c172e',
+    'aphront-dialog-view-css' => '593d3f67',
     'aphront-list-filter-view-css' => '5d6f0526',
     'aphront-multi-column-view-css' => 'fd18389d',
     'aphront-panel-view-css' => '8427b78d',
@@ -617,13 +618,14 @@
     'config-options-css' => '0ede4c9b',
     'config-page-css' => '8798e14f',
     'conpherence-durable-column-view' => '194ac487',
+    'conpherence-header-pane-css' => 'bdba8a5b',
     'conpherence-menu-css' => '67235d90',
-    'conpherence-message-pane-css' => 'ee0e27be',
+    'conpherence-message-pane-css' => 'c075e8fe',
     'conpherence-notification-css' => '6cdcc253',
     'conpherence-thread-manager' => '01774ab2',
-    'conpherence-transaction-css' => '2c71247c',
-    'conpherence-update-css' => 'faf6be09',
-    'conpherence-widget-pane-css' => 'a131d5b6',
+    'conpherence-transaction-css' => '46253e19',
+    'conpherence-update-css' => '53bc527a',
+    'conpherence-widget-pane-css' => '827a21f1',
     'd3' => 'a11a5ff2',
     'differential-changeset-view-css' => '9ef7d354',
     'differential-core-view-css' => '5b7b8ff4',
@@ -665,9 +667,9 @@
     'javelin-behavior-comment-actions' => '0300eae6',
     'javelin-behavior-config-reorder-fields' => 'b6993408',
     'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a',
-    'javelin-behavior-conpherence-menu' => '1d45c74d',
+    'javelin-behavior-conpherence-menu' => '7a2f5952',
+    'javelin-behavior-conpherence-participants-pane' => '08872fb7',
     'javelin-behavior-conpherence-pontificate' => '21ba5861',
-    'javelin-behavior-conpherence-widget-pane' => '65845387',
     'javelin-behavior-countdown-timer' => 'e4cc26b3',
     'javelin-behavior-dark-console' => 'f411b6ae',
     'javelin-behavior-dashboard-async-panel' => '469c0d9e',
@@ -773,7 +775,7 @@
     'javelin-behavior-test-payment-form' => 'fc91ab6c',
     'javelin-behavior-time-typeahead' => '522431f7',
     'javelin-behavior-toggle-class' => '92b9ec77',
-    'javelin-behavior-toggle-widget' => 'b151bbbc',
+    'javelin-behavior-toggle-widget' => '9bdbbab0',
     'javelin-behavior-typeahead-browse' => '635de1ec',
     'javelin-behavior-typeahead-search' => '93d0c9e3',
     'javelin-behavior-view-placeholder' => '47830651',
@@ -881,7 +883,7 @@
     'phabricator-uiexample-reactor-select' => 'a155550f',
     'phabricator-uiexample-reactor-sendclass' => '1def2711',
     'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee',
-    'phabricator-zindex-css' => '2b01a823',
+    'phabricator-zindex-css' => 'a847e919',
     'phame-css' => '8efb0729',
     'pholio-css' => 'ca89d380',
     'pholio-edit-css' => '07676f51',
@@ -1057,6 +1059,15 @@
       'javelin-stratcom',
       'javelin-vector',
     ),
+    '08872fb7' => array(
+      'javelin-behavior',
+      'javelin-dom',
+      'javelin-stratcom',
+      'javelin-workflow',
+      'javelin-util',
+      'phabricator-notification',
+      'conpherence-thread-manager',
+    ),
     '0a0b10e9' => array(
       'javelin-behavior',
       'javelin-stratcom',
@@ -1135,20 +1146,6 @@
       'javelin-request',
       'javelin-uri',
     ),
-    '1d45c74d' => array(
-      'javelin-behavior',
-      'javelin-dom',
-      'javelin-util',
-      'javelin-stratcom',
-      'javelin-workflow',
-      'javelin-behavior-device',
-      'javelin-history',
-      'javelin-vector',
-      'javelin-scrollbar',
-      'phabricator-title',
-      'phabricator-shaped-request',
-      'conpherence-thread-manager',
-    ),
     '1def2711' => array(
       'javelin-install',
       'javelin-dom',
@@ -1484,19 +1481,6 @@
       'javelin-request',
       'javelin-workflow',
     ),
-    65845387 => array(
-      'javelin-behavior',
-      'javelin-dom',
-      'javelin-stratcom',
-      'javelin-workflow',
-      'javelin-util',
-      'phabricator-notification',
-      'javelin-behavior-device',
-      'phuix-dropdown-menu',
-      'phuix-action-list-view',
-      'phuix-action-view',
-      'conpherence-thread-manager',
-    ),
     '680ea2c8' => array(
       'javelin-install',
       'javelin-dom',
@@ -1587,6 +1571,20 @@
       'javelin-behavior',
       'javelin-quicksand',
     ),
+    '7a2f5952' => array(
+      'javelin-behavior',
+      'javelin-dom',
+      'javelin-util',
+      'javelin-stratcom',
+      'javelin-workflow',
+      'javelin-behavior-device',
+      'javelin-history',
+      'javelin-vector',
+      'javelin-scrollbar',
+      'phabricator-title',
+      'phabricator-shaped-request',
+      'conpherence-thread-manager',
+    ),
     '7a68dda3' => array(
       'owners-path-editor',
       'javelin-behavior',
@@ -1755,6 +1753,13 @@
       'phabricator-phtize',
       'changeset-view-manager',
     ),
+    '9bdbbab0' => array(
+      'javelin-behavior',
+      'javelin-dom',
+      'javelin-util',
+      'javelin-workflow',
+      'javelin-stratcom',
+    ),
     '9ef7d354' => array(
       'phui-inline-comment-view-css',
     ),
@@ -1850,13 +1855,6 @@
       'javelin-util',
       'phabricator-shaped-request',
     ),
-    'b151bbbc' => array(
-      'javelin-behavior',
-      'javelin-dom',
-      'javelin-util',
-      'javelin-workflow',
-      'javelin-stratcom',
-    ),
     'b1f0ccee' => array(
       'javelin-install',
       'javelin-dom',
@@ -2311,6 +2309,7 @@
       'conpherence-transaction-css',
       'conpherence-update-css',
       'conpherence-widget-pane-css',
+      'conpherence-header-pane-css',
     ),
     'core.pkg.css' => array(
       'phabricator-core-css',
diff --git a/resources/celerity/packages.php b/resources/celerity/packages.php
--- a/resources/celerity/packages.php
+++ b/resources/celerity/packages.php
@@ -159,6 +159,7 @@
     'conpherence-transaction-css',
     'conpherence-update-css',
     'conpherence-widget-pane-css',
+    'conpherence-header-pane-css',
   ),
   'differential.pkg.css' => array(
     'differential-core-view-css',
diff --git a/resources/sql/autopatches/20160913.conpherence.topic.1.sql b/resources/sql/autopatches/20160913.conpherence.topic.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160913.conpherence.topic.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread
+  ADD topic VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -300,10 +300,11 @@
     'ConpherenceNewRoomController' => 'applications/conpherence/controller/ConpherenceNewRoomController.php',
     'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php',
     'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
+    'ConpherenceParticipantController' => 'applications/conpherence/controller/ConpherenceParticipantController.php',
     'ConpherenceParticipantCountQuery' => 'applications/conpherence/query/ConpherenceParticipantCountQuery.php',
     'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
+    'ConpherenceParticipantView' => 'applications/conpherence/view/ConpherenceParticipantView.php',
     'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
-    'ConpherencePeopleWidgetView' => 'applications/conpherence/view/ConpherencePeopleWidgetView.php',
     'ConpherencePicCropControl' => 'applications/conpherence/view/ConpherencePicCropControl.php',
     'ConpherenceQueryThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php',
     'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php',
@@ -329,9 +330,6 @@
     'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
     'ConpherenceUpdateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php',
     'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
-    'ConpherenceWidgetConfigConstants' => 'applications/conpherence/constants/ConpherenceWidgetConfigConstants.php',
-    'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
-    'ConpherenceWidgetView' => 'applications/conpherence/view/ConpherenceWidgetView.php',
     'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php',
     'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php',
     'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php',
@@ -4768,10 +4766,11 @@
     'ConpherenceNewRoomController' => 'ConpherenceController',
     'ConpherenceNotificationPanelController' => 'ConpherenceController',
     'ConpherenceParticipant' => 'ConpherenceDAO',
+    'ConpherenceParticipantController' => 'ConpherenceController',
     'ConpherenceParticipantCountQuery' => 'PhabricatorOffsetPagedQuery',
     'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
+    'ConpherenceParticipantView' => 'AphrontView',
     'ConpherenceParticipationStatus' => 'ConpherenceConstants',
-    'ConpherencePeopleWidgetView' => 'ConpherenceWidgetView',
     'ConpherencePicCropControl' => 'AphrontFormControl',
     'ConpherenceQueryThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
@@ -4803,9 +4802,6 @@
     'ConpherenceUpdateController' => 'ConpherenceController',
     'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceViewController' => 'ConpherenceController',
-    'ConpherenceWidgetConfigConstants' => 'ConpherenceConstants',
-    'ConpherenceWidgetController' => 'ConpherenceController',
-    'ConpherenceWidgetView' => 'AphrontView',
     'DarkConsoleController' => 'PhabricatorController',
     'DarkConsoleCore' => 'Phobject',
     'DarkConsoleDataController' => 'PhabricatorController',
diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
--- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
+++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
@@ -42,7 +42,7 @@
         'search/(?:query/(?P<queryKey>[^/]+)/)?'
            => 'ConpherenceRoomListController',
         'panel/'                   => 'ConpherenceNotificationPanelController',
-        'widget/(?P<id>[1-9]\d*)/' => 'ConpherenceWidgetController',
+        'participant/(?P<id>[1-9]\d*)/' => 'ConpherenceParticipantController',
         'update/(?P<id>[1-9]\d*)/' => 'ConpherenceUpdateController',
       ),
     );
diff --git a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php
--- a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php
+++ b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php
@@ -13,8 +13,9 @@
 
   protected function defineParamTypes() {
     return array(
-      'title' => 'optional string',
-      'message' => 'required string',
+      'title' => 'required string',
+      'topic' => 'optional string',
+      'message' => 'optional string',
       'participantPHIDs' => 'required list<phids>',
     );
   }
@@ -27,8 +28,8 @@
     return array(
       'ERR_EMPTY_PARTICIPANT_PHIDS' => pht(
         'You must specify participant phids.'),
-      'ERR_EMPTY_MESSAGE' => pht(
-        'You must specify a message.'),
+      'ERR_EMPTY_TITLE' => pht(
+        'You must specify a title.'),
     );
   }
 
@@ -36,19 +37,21 @@
     $participant_phids = $request->getValue('participantPHIDs', array());
     $message = $request->getValue('message');
     $title = $request->getValue('title');
+    $topic = $request->getValue('topic');
 
     list($errors, $conpherence) = ConpherenceEditor::createThread(
       $request->getUser(),
       $participant_phids,
       $title,
       $message,
-      $request->newContentSource());
+      $request->newContentSource(),
+      $topic);
 
     if ($errors) {
       foreach ($errors as $error_code) {
         switch ($error_code) {
-          case ConpherenceEditor::ERROR_EMPTY_MESSAGE:
-            throw new ConduitException('ERR_EMPTY_MESSAGE');
+          case ConpherenceEditor::ERROR_EMPTY_TITLE:
+            throw new ConduitException('ERR_EMPTY_TITLE');
             break;
           case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS:
             throw new ConduitException('ERR_EMPTY_PARTICIPANT_PHIDS');
diff --git a/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php b/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php
deleted file mode 100644
--- a/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-final class ConpherenceWidgetConfigConstants extends ConpherenceConstants {
-
-  const UPDATE_URI = '/conpherence/update/';
-
-  public static function getWidgetPaneBehaviorConfig() {
-    return array(
-      'widgetBaseUpdateURI' => self::UPDATE_URI,
-      'widgetRegistry' => self::getWidgetRegistry(),
-    );
-  }
-
-  public static function getWidgetRegistry() {
-    return array(
-      'conpherence-message-pane' => array(
-        'name' => pht('Thread'),
-        'icon' => 'fa-comment',
-        'deviceOnly' => true,
-        'hasCreate' => false,
-      ),
-      'widgets-people' => array(
-        'name' => pht('Participants'),
-        'icon' => 'fa-users',
-        'deviceOnly' => false,
-        'hasCreate' => true,
-        'createData' => array(
-          'refreshFromResponse' => true,
-          'action' => ConpherenceUpdateActions::ADD_PERSON,
-          'customHref' => null,
-        ),
-      ),
-      'widgets-settings' => array(
-        'name' => pht('Notifications'),
-        'icon' => 'fa-wrench',
-        'deviceOnly' => false,
-        'hasCreate' => false,
-      ),
-    );
-  }
-
-}
diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php
--- a/src/applications/conpherence/controller/ConpherenceController.php
+++ b/src/applications/conpherence/controller/ConpherenceController.php
@@ -14,81 +14,78 @@
 
   public function buildApplicationMenu() {
     $nav = new PHUIListView();
+    $conpherence = $this->conpherence;
 
+    // Local Links
+    if ($conpherence) {
+      $nav->addMenuItem(
+        id(new PHUIListItemView())
+        ->setName(pht('Edit Room'))
+        ->setType(PHUIListItemView::TYPE_LINK)
+        ->setHref(
+          $this->getApplicationURI('update/'.$conpherence->getID()).'/')
+        ->setWorkflow(true));
+
+      $nav->addMenuItem(
+        id(new PHUIListItemView())
+        ->setName(pht('Add Participants'))
+        ->setType(PHUIListItemView::TYPE_LINK)
+        ->setHref('#')
+        ->addSigil('conpherence-widget-adder')
+        ->setMetadata(array('widget' => 'widgets-people')));
+    }
+
+    // Global Links
+    $nav->newLabel(pht('Conpherence'));
     $nav->newLink(
       pht('New Room'),
       $this->getApplicationURI('new/'));
-
-    $nav->addMenuItem(
-      id(new PHUIListItemView())
-      ->setName(pht('Add Participants'))
-      ->setType(PHUIListItemView::TYPE_LINK)
-      ->setHref('#')
-      ->addSigil('conpherence-widget-adder')
-      ->setMetadata(array('widget' => 'widgets-people')));
+    $nav->newLink(
+      pht('Search Rooms'),
+      $this->getApplicationURI('search/'));
 
     return $nav;
   }
 
-  protected function buildApplicationCrumbs() {
-    return $this->buildConpherenceApplicationCrumbs();
-  }
-
-  protected function buildConpherenceApplicationCrumbs($is_rooms = false) {
-    $crumbs = parent::buildApplicationCrumbs();
-    $crumbs->setBorder(true);
-
-    if (!$is_rooms) {
-      $crumbs
-        ->addAction(
-          id(new PHUIListItemView())
-          ->setName(pht('Room'))
-          ->setHref('#')
-          ->setIcon('fa-bars')
-          ->setStyle('display: none;')
-          ->addClass('device-widgets-selector')
-          ->addSigil('device-widgets-selector'));
-    }
-    return $crumbs;
-  }
-
   protected function buildHeaderPaneContent(
     ConpherenceThread $conpherence,
     array $policy_objects) {
     assert_instances_of($policy_objects, 'PhabricatorPolicy');
     $viewer = $this->getViewer();
-
-    $crumbs = $this->buildApplicationCrumbs();
+    $header = null;
 
     if ($conpherence->getID()) {
       $data = $conpherence->getDisplayData($this->getViewer());
-      $crumbs->addCrumb(
-        id(new PHUICrumbView())
-        ->setName($data['title'])
-        ->setHref('/'.$conpherence->getMonogram()));
-        $can_edit = PhabricatorPolicyFilter::hasCapability(
+      $header = id(new PHUIHeaderView())
+        ->setHeader($data['title'])
+        ->setSubheader($data['topic'])
+        ->addClass((!$data['topic']) ? 'conpherence-no-topic' : null);
+
+      $can_edit = PhabricatorPolicyFilter::hasCapability(
           $viewer,
           $conpherence,
           PhabricatorPolicyCapability::CAN_EDIT);
 
-      $crumbs
-        ->addAction(
-          id(new PHUIListItemView())
-          ->setName(pht('Edit Room'))
+      $header->addActionItem(
+        id(new PHUIIconCircleView())
           ->setHref(
             $this->getApplicationURI('update/'.$conpherence->getID()).'/')
           ->setIcon('fa-pencil')
-          ->setDisabled(!$can_edit)
+          ->addClass('hide-on-device')
+          ->setWorkflow(true));
+
+      $header->addActionItem(
+        id(new PHUIIconCircleView())
+          ->setHref(
+            $this->getApplicationURI('update/'.$conpherence->getID()).'/'.
+            '?action='.ConpherenceUpdateActions::NOTIFICATIONS)
+          ->setIcon('fa-gear')
+          ->addClass('hide-on-device')
           ->setWorkflow(true));
 
       $widget_key = PhabricatorConpherenceWidgetVisibleSetting::SETTINGKEY;
       $widget_view = (bool)$viewer->getUserSetting($widget_key, false);
 
-      $divider = id(new PHUIListItemView())
-        ->setType(PHUIListItemView::TYPE_DIVIDER)
-        ->addClass('conpherence-header-desktop-item');
-      $crumbs->addAction($divider);
-
       Javelin::initBehavior(
         'toggle-widget',
         array(
@@ -96,24 +93,15 @@
           'settingsURI' => '/settings/adjust/?key='.$widget_key,
         ));
 
-      $crumbs->addAction(
-        id(new PHUIListItemView())
-        ->addSigil('conpherence-widget-toggle')
-        ->setIcon('fa-columns')
-        ->addClass('conpherence-header-desktop-item'));
+      $header->addActionItem(
+        id(new PHUIIconCircleView())
+          ->addSigil('conpherence-widget-toggle')
+          ->setIcon('fa-group')
+          ->setHref('#')
+          ->addClass('conpherence-participant-toggle'));
     }
 
-    return hsprintf(
-      '%s',
-      array(
-        phutil_tag(
-          'div',
-          array(
-            'class' => 'header-loading-mask',
-          ),
-          ''),
-        $crumbs,
-      ));
+    return $header;
   }
 
 }
diff --git a/src/applications/conpherence/controller/ConpherenceNewRoomController.php b/src/applications/conpherence/controller/ConpherenceNewRoomController.php
--- a/src/applications/conpherence/controller/ConpherenceNewRoomController.php
+++ b/src/applications/conpherence/controller/ConpherenceNewRoomController.php
@@ -27,6 +27,9 @@
         ->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
         ->setNewValue($request->getStr('title'));
       $xactions[] = id(new ConpherenceTransaction())
+        ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC)
+        ->setNewValue($request->getStr('topic'));
+      $xactions[] = id(new ConpherenceTransaction())
         ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
         ->setNewValue($request->getStr('viewPolicy'));
       $xactions[] = id(new ConpherenceTransaction())
@@ -94,6 +97,11 @@
         ->setName('title')
         ->setValue($request->getStr('title')))
       ->appendChild(
+        id(new AphrontFormTextControl())
+        ->setLabel(pht('Topic'))
+        ->setName('topic')
+        ->setValue($request->getStr('topic')))
+      ->appendChild(
         id(new AphrontFormTokenizerControl())
         ->setName('participants')
         ->setUser($user)
diff --git a/src/applications/conpherence/controller/ConpherenceParticipantController.php b/src/applications/conpherence/controller/ConpherenceParticipantController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conpherence/controller/ConpherenceParticipantController.php
@@ -0,0 +1,73 @@
+<?php
+
+final class ConpherenceParticipantController extends ConpherenceController {
+
+  public function shouldAllowPublic() {
+    return true;
+  }
+
+  public function handleRequest(AphrontRequest $request) {
+    $viewer = $request->getViewer();
+
+    $conpherence_id = $request->getURIData('id');
+    if (!$conpherence_id) {
+      return new Aphront404Response();
+    }
+    $conpherence = id(new ConpherenceThreadQuery())
+      ->setViewer($viewer)
+      ->withIDs(array($conpherence_id))
+      ->needWidgetData(true)
+      ->executeOne();
+    if (!$conpherence) {
+      return new Aphront404Response();
+    }
+    $this->setConpherence($conpherence);
+    $content = $this->renderParticipantPaneContent();
+
+    return id(new AphrontAjaxResponse())->setContent($content);
+  }
+
+  private function renderParticipantPaneContent() {
+    $conpherence = $this->getConpherence();
+
+    $widgets = array();
+    $new_icon = id(new PHUIIconView())
+      ->setIcon('fa-plus-square')
+      ->setHref($this->getUpdateURI())
+      ->setMetadata(array('widget' => null))
+      ->addSigil('conpherence-widget-adder');
+
+    $content = id(new ConpherenceParticipantView())
+      ->setUser($this->getViewer())
+      ->setConpherence($this->getConpherence())
+      ->setUpdateURI($this->getUpdateURI());
+
+    $widgets[] = phutil_tag(
+      'div',
+      array(
+        'class' => 'widgets-header',
+      ),
+      id(new PHUIHeaderView())
+      ->setHeader(pht('Participants'))
+      ->addActionItem($new_icon));
+
+    $widgets[] = javelin_tag(
+      'div',
+      array(
+        'class' => 'widgets-body',
+        'id' => 'widgets-people',
+        'sigil' => 'widgets-people',
+      ),
+      $content);
+
+    // without this implosion we get "," between each element in our widgets
+    // array
+    return array('widgets' => phutil_implode_html('', $widgets));
+  }
+
+  private function getUpdateURI() {
+    $conpherence = $this->getConpherence();
+    return $this->getApplicationURI('update/'.$conpherence->getID().'/');
+  }
+
+}
diff --git a/src/applications/conpherence/controller/ConpherenceRoomListController.php b/src/applications/conpherence/controller/ConpherenceRoomListController.php
--- a/src/applications/conpherence/controller/ConpherenceRoomListController.php
+++ b/src/applications/conpherence/controller/ConpherenceRoomListController.php
@@ -18,10 +18,6 @@
     return $this->delegateToController($controller);
   }
 
-  protected function buildApplicationCrumbs() {
-    return $this->buildConpherenceApplicationCrumbs($is_rooms = true);
-  }
-
   public function buildApplicationMenu() {
     return $this->buildRoomsSideNavView(true)->getMenu();
   }
diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php
--- a/src/applications/conpherence/controller/ConpherenceUpdateController.php
+++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php
@@ -107,7 +107,7 @@
           break;
         case ConpherenceUpdateActions::REMOVE_PERSON:
           if (!$request->isContinueRequest()) {
-            // do nothing; we'll display a confirmation dialogue instead
+            // do nothing; we'll display a confirmation dialog instead
             break;
           }
           $person_phid = $request->getStr('remove_person');
@@ -127,22 +127,16 @@
           }
           $participant->setSettings(array('notifications' => $notifications));
           $participant->save();
+          return id(new AphrontRedirectResponse())
+            ->setURI('/'.$conpherence->getMonogram());
 
-          $label = PhabricatorConpherenceNotificationsSetting::getSettingLabel(
-            $notifications);
-
-          $result = pht(
-            'Updated notification settings to "%s".',
-            $label);
-
-          return id(new AphrontAjaxResponse())
-            ->setContent($result);
           break;
         case ConpherenceUpdateActions::METADATA:
           $top = $request->getInt('image_y');
           $left = $request->getInt('image_x');
           $file_id = $request->getInt('file_id');
           $title = $request->getStr('title');
+          $topic = $request->getStr('topic');
           if ($file_id) {
             $orig_file = id(new PhabricatorFileQuery())
               ->setViewer($user)
@@ -190,10 +184,14 @@
               ->setNewValue($image_phid);
           }
           $title = $request->getStr('title');
+          $topic = $request->getStr('topic');
           $xactions[] = id(new ConpherenceTransaction())
             ->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
             ->setNewValue($title);
           $xactions[] = id(new ConpherenceTransaction())
+            ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC)
+            ->setNewValue($topic);
+          $xactions[] = id(new ConpherenceTransaction())
             ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
             ->setNewValue($request->getStr('viewPolicy'));
           $xactions[] = id(new ConpherenceTransaction())
@@ -269,29 +267,97 @@
     }
 
     switch ($action) {
+      case ConpherenceUpdateActions::NOTIFICATIONS:
+        $dialog = $this->renderPreferencesDialog($conpherence);
+        break;
       case ConpherenceUpdateActions::ADD_PERSON:
-        $dialogue = $this->renderAddPersonDialogue($conpherence);
+        $dialog = $this->renderAddPersonDialog($conpherence);
         break;
       case ConpherenceUpdateActions::REMOVE_PERSON:
-        $dialogue = $this->renderRemovePersonDialogue($conpherence);
+        $dialog = $this->renderRemovePersonDialog($conpherence);
         break;
       case ConpherenceUpdateActions::METADATA:
       default:
-        $dialogue = $this->renderMetadataDialogue($conpherence, $error_view);
+        $dialog = $this->renderMetadataDialog($conpherence, $error_view);
         break;
     }
 
-    return id(new AphrontDialogResponse())
-      ->setDialog($dialogue
+    return
+      $dialog
         ->setUser($user)
         ->setWidth(AphrontDialogView::WIDTH_FORM)
         ->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/'))
         ->addSubmitButton()
-        ->addCancelButton($this->getApplicationURI($conpherence->getID().'/')));
+        ->addCancelButton($this->getApplicationURI($conpherence->getID().'/'));
 
   }
 
-  private function renderAddPersonDialogue(
+  private function renderPreferencesDialog(
+    ConpherenceThread $conpherence) {
+
+    $request = $this->getRequest();
+    $user = $request->getUser();
+
+    $participant = $conpherence->getParticipantIfExists($user->getPHID());
+    if (!$participant) {
+      $can_join = PhabricatorPolicyFilter::hasCapability(
+        $user,
+        $conpherence,
+        PhabricatorPolicyCapability::CAN_JOIN);
+      if ($can_join) {
+        $text = pht(
+          'Notification settings are available after joining the room.');
+      } else if ($user->isLoggedIn()) {
+        $text = pht(
+          'Notification settings not applicable to rooms you can not join.');
+      } else {
+        $text = pht(
+          'Notification settings are available after logging in and joining '.
+          'the room.');
+      }
+      return id(new AphrontDialogView())
+        ->setTitle(pht('Room Preferences'))
+        ->appendParagraph($text);
+    }
+
+    $notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY;
+    $notification_default = $user->getUserSetting($notification_key);
+
+    $settings = $participant->getSettings();
+    $notifications = idx(
+      $settings,
+      'notifications',
+      $notification_default);
+
+    $form = id(new AphrontFormView())
+      ->setUser($user)
+      ->setFullWidth(true)
+      ->appendControl(
+      id(new AphrontFormRadioButtonControl())
+        ->addButton(
+          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL,
+          PhabricatorConpherenceNotificationsSetting::getSettingLabel(
+          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL),
+          '')
+        ->addButton(
+          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY,
+          PhabricatorConpherenceNotificationsSetting::getSettingLabel(
+          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY),
+          '')
+        ->setName('notifications')
+        ->setValue($notifications));
+
+    return id(new AphrontDialogView())
+      ->setTitle(pht('Room Preferences'))
+      ->addHiddenInput('action', 'notifications')
+      ->addHiddenInput(
+        'latest_transaction_id',
+        $request->getInt('latest_transaction_id'))
+      ->appendForm($form);
+
+  }
+
+  private function renderAddPersonDialog(
     ConpherenceThread $conpherence) {
 
     $request = $this->getRequest();
@@ -322,7 +388,7 @@
     return $view;
   }
 
-  private function renderRemovePersonDialogue(
+  private function renderRemovePersonDialog(
     ConpherenceThread $conpherence) {
 
     $request = $this->getRequest();
@@ -405,7 +471,7 @@
     return $dialog;
   }
 
-  private function renderMetadataDialogue(
+  private function renderMetadataDialog(
     ConpherenceThread $conpherence,
     $error_view) {
 
@@ -419,7 +485,12 @@
         id(new AphrontFormTextControl())
         ->setLabel(pht('Title'))
         ->setName('title')
-        ->setValue($conpherence->getTitle()));
+        ->setValue($conpherence->getTitle()))
+      ->appendChild(
+        id(new AphrontFormTextControl())
+        ->setLabel(pht('Topic'))
+        ->setName('topic')
+        ->setValue($conpherence->getTopic()));
 
     $nopic = $this->getRequest()->getExists('nopic');
     $image = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG);
@@ -548,11 +619,10 @@
     $rendered_transactions = idx($data, 'transactions');
     $new_latest_transaction_id = idx($data, 'latest_transaction_id');
 
-    $widget_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
+    $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
     $nav_item = null;
     $header = null;
     $people_widget = null;
-    $file_widget = null;
     if (!$minimal_display) {
       switch ($action) {
         case ConpherenceUpdateActions::METADATA:
@@ -571,10 +641,10 @@
           $nav_item = hsprintf('%s', $nav_item);
           break;
         case ConpherenceUpdateActions::ADD_PERSON:
-          $people_widget = id(new ConpherencePeopleWidgetView())
+          $people_widget = id(new ConpherenceParticipantView())
             ->setUser($user)
             ->setConpherence($conpherence)
-            ->setUpdateURI($widget_uri);
+            ->setUpdateURI($update_uri);
           $people_widget = hsprintf('%s', $people_widget->render());
           break;
         case ConpherenceUpdateActions::REMOVE_PERSON:
@@ -595,7 +665,6 @@
       'nav_item' => $nav_item,
       'conpherence_phid' => $conpherence->getPHID(),
       'header' => $header,
-      'file_widget' => $file_widget,
       'people_widget' => $people_widget,
       'aphlictDropdownData' => array(
         $dropdown_query->getNotificationData(),
diff --git a/src/applications/conpherence/controller/ConpherenceWidgetController.php b/src/applications/conpherence/controller/ConpherenceWidgetController.php
deleted file mode 100644
--- a/src/applications/conpherence/controller/ConpherenceWidgetController.php
+++ /dev/null
@@ -1,181 +0,0 @@
-<?php
-
-final class ConpherenceWidgetController extends ConpherenceController {
-
-  public function shouldAllowPublic() {
-    return true;
-  }
-
-  public function handleRequest(AphrontRequest $request) {
-    $request = $this->getRequest();
-    $user = $request->getUser();
-
-    $conpherence_id = $request->getURIData('id');
-    if (!$conpherence_id) {
-      return new Aphront404Response();
-    }
-    $conpherence = id(new ConpherenceThreadQuery())
-      ->setViewer($user)
-      ->withIDs(array($conpherence_id))
-      ->needWidgetData(true)
-      ->executeOne();
-    if (!$conpherence) {
-      return new Aphront404Response();
-    }
-    $this->setConpherence($conpherence);
-
-    switch ($request->getStr('widget')) {
-      case 'widgets-people':
-        $content = $this->renderPeopleWidgetPaneContent();
-        break;
-      case 'widgets-settings':
-        $content = $this->renderSettingsWidgetPaneContent();
-        break;
-      default:
-        $widgets = $this->renderWidgetPaneContent();
-        $content = $widgets;
-        break;
-    }
-    return id(new AphrontAjaxResponse())->setContent($content);
-  }
-
-  private function renderWidgetPaneContent() {
-    $conpherence = $this->getConpherence();
-
-    $widgets = array();
-    $new_icon = id(new PHUIIconView())
-      ->setIcon('fa-plus')
-      ->setHref($this->getWidgetURI())
-      ->setMetadata(array('widget' => null))
-      ->addSigil('conpherence-widget-adder');
-    $header = javelin_tag(
-      'a',
-      array(
-        'href' => '#',
-        'sigil' => 'widgets-selector',
-      ),
-      pht('Participants'));
-
-    $widgets[] = phutil_tag(
-      'div',
-      array(
-        'class' => 'widgets-header',
-      ),
-      id(new PHUIHeaderView())
-      ->setHeader($header)
-      ->addActionItem($new_icon));
-    $user = $this->getRequest()->getUser();
-    // now the widget bodies
-    $widgets[] = javelin_tag(
-      'div',
-      array(
-        'class' => 'widgets-body',
-        'id' => 'widgets-people',
-        'sigil' => 'widgets-people',
-      ),
-      $this->renderPeopleWidgetPaneContent());
-    $widgets[] = phutil_tag(
-      'div',
-      array(
-        'class' => 'widgets-body',
-        'id' => 'widgets-settings',
-        'style' => 'display: none',
-      ),
-      $this->renderSettingsWidgetPaneContent());
-
-    // without this implosion we get "," between each element in our widgets
-    // array
-    return array('widgets' => phutil_implode_html('', $widgets));
-  }
-
-  private function renderPeopleWidgetPaneContent() {
-    return id(new ConpherencePeopleWidgetView())
-      ->setUser($this->getViewer())
-      ->setConpherence($this->getConpherence())
-      ->setUpdateURI($this->getWidgetURI());
-  }
-
-
-  private function renderSettingsWidgetPaneContent() {
-    $viewer = $this->getViewer();
-    $conpherence = $this->getConpherence();
-    $participant = $conpherence->getParticipantIfExists($viewer->getPHID());
-    if (!$participant) {
-      $can_join = PhabricatorPolicyFilter::hasCapability(
-        $viewer,
-        $conpherence,
-        PhabricatorPolicyCapability::CAN_JOIN);
-      if ($can_join) {
-        $text = pht(
-          'Notification settings are available after joining the room.');
-      } else if ($viewer->isLoggedIn()) {
-        $text = pht(
-          'Notification settings not applicable to rooms you can not join.');
-      } else {
-        $text = pht(
-          'Notification settings are available after logging in and joining '.
-          'the room.');
-      }
-      return phutil_tag(
-        'div',
-        array(
-          'class' => 'no-settings',
-        ),
-        $text);
-    }
-    $notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY;
-    $notification_default = $viewer->getUserSetting($notification_key);
-
-    $settings = $participant->getSettings();
-    $notifications = idx(
-      $settings,
-      'notifications',
-      $notification_default);
-    $options = id(new AphrontFormRadioButtonControl())
-      ->addButton(
-        PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL,
-        PhabricatorConpherenceNotificationsSetting::getSettingLabel(
-          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL),
-        '')
-      ->addButton(
-        PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY,
-        PhabricatorConpherenceNotificationsSetting::getSettingLabel(
-          PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY),
-        '')
-      ->setName('notifications')
-      ->setValue($notifications);
-
-    $layout = array(
-      $options,
-      phutil_tag(
-        'input',
-        array(
-          'type' => 'hidden',
-          'name' => 'action',
-          'value' => 'notifications',
-        )),
-      phutil_tag(
-        'button',
-        array(
-          'type' => 'submit',
-          'class' => 'notifications-update',
-        ),
-        pht('Save')),
-    );
-
-    return phabricator_form(
-      $viewer,
-      array(
-        'method' => 'POST',
-        'action' => $this->getWidgetURI(),
-        'sigil' => 'notifications-update',
-      ),
-      $layout);
-  }
-
-  private function getWidgetURI() {
-    $conpherence = $this->getConpherence();
-    return $this->getApplicationURI('update/'.$conpherence->getID().'/');
-  }
-
-}
diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php
--- a/src/applications/conpherence/editor/ConpherenceEditor.php
+++ b/src/applications/conpherence/editor/ConpherenceEditor.php
@@ -18,7 +18,8 @@
     array $participant_phids,
     $title,
     $message,
-    PhabricatorContentSource $source) {
+    PhabricatorContentSource $source,
+    $topic) {
 
     $conpherence = ConpherenceThread::initializeNewRoom($creator);
     $files = array();
@@ -59,6 +60,11 @@
           ->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
           ->setNewValue($title);
       }
+      if (strlen($topic)) {
+        $xactions[] = id(new ConpherenceTransaction())
+          ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC)
+          ->setNewValue($topic);
+      }
 
       $xactions[] = id(new ConpherenceTransaction())
         ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
@@ -118,6 +124,7 @@
     $types[] = PhabricatorTransactions::TYPE_COMMENT;
 
     $types[] = ConpherenceTransaction::TYPE_TITLE;
+    $types[] = ConpherenceTransaction::TYPE_TOPIC;
     $types[] = ConpherenceTransaction::TYPE_PARTICIPANTS;
     $types[] = ConpherenceTransaction::TYPE_FILES;
     $types[] = ConpherenceTransaction::TYPE_PICTURE;
@@ -136,6 +143,8 @@
     switch ($xaction->getTransactionType()) {
       case ConpherenceTransaction::TYPE_TITLE:
         return $object->getTitle();
+      case ConpherenceTransaction::TYPE_TOPIC:
+        return $object->getTopic();
       case ConpherenceTransaction::TYPE_PICTURE:
         return $object->getImagePHID(ConpherenceImageData::SIZE_ORIG);
       case ConpherenceTransaction::TYPE_PICTURE_CROP:
@@ -156,6 +165,7 @@
 
     switch ($xaction->getTransactionType()) {
       case ConpherenceTransaction::TYPE_TITLE:
+      case ConpherenceTransaction::TYPE_TOPIC:
       case ConpherenceTransaction::TYPE_PICTURE_CROP:
         return $xaction->getNewValue();
       case ConpherenceTransaction::TYPE_PICTURE:
@@ -250,6 +260,9 @@
       case ConpherenceTransaction::TYPE_TITLE:
         $object->setTitle($xaction->getNewValue());
         break;
+      case ConpherenceTransaction::TYPE_TOPIC:
+        $object->setTopic($xaction->getNewValue());
+        break;
       case ConpherenceTransaction::TYPE_PICTURE:
         $object->setImagePHID(
           $xaction->getNewValue(),
@@ -484,6 +497,7 @@
           PhabricatorPolicyCapability::CAN_VIEW);
         break;
       case ConpherenceTransaction::TYPE_TITLE:
+      case ConpherenceTransaction::TYPE_TOPIC:
         PhabricatorPolicyFilter::requireCapability(
           $this->requireActor(),
           $object,
diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php
--- a/src/applications/conpherence/storage/ConpherenceThread.php
+++ b/src/applications/conpherence/storage/ConpherenceThread.php
@@ -8,6 +8,7 @@
     PhabricatorDestructibleInterface {
 
   protected $title;
+  protected $topic;
   protected $imagePHIDs = array();
   protected $messageCount;
   protected $recentParticipantPHIDs = array();
@@ -29,6 +30,7 @@
     return id(new ConpherenceThread())
       ->setMessageCount(0)
       ->setTitle('')
+      ->setTopic('')
       ->attachParticipants(array())
       ->attachFilePHIDs(array())
       ->attachImages(array())
@@ -46,6 +48,7 @@
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'title' => 'text255?',
+        'topic' => 'text255',
         'messageCount' => 'uint64',
         'mailKey' => 'text20',
         'joinPolicy' => 'policy',
@@ -342,9 +345,11 @@
     $unread_count = $this->getMessageCount() - $user_seen_count;
 
     $title = $this->getDisplayTitle($viewer);
+    $topic = $this->getTopic();
 
     return array(
       'title' => $title,
+      'topic' => $topic,
       'subtitle' => $subtitle,
       'unread_count' => $unread_count,
       'epoch' => $this->getDateModified(),
diff --git a/src/applications/conpherence/storage/ConpherenceTransaction.php b/src/applications/conpherence/storage/ConpherenceTransaction.php
--- a/src/applications/conpherence/storage/ConpherenceTransaction.php
+++ b/src/applications/conpherence/storage/ConpherenceTransaction.php
@@ -4,6 +4,7 @@
 
   const TYPE_FILES           = 'files';
   const TYPE_TITLE           = 'title';
+  const TYPE_TOPIC           = 'topic';
   const TYPE_PARTICIPANTS    = 'participants';
   const TYPE_DATE_MARKER     = 'date-marker';
   const TYPE_PICTURE         = 'picture';
@@ -39,6 +40,7 @@
       case self::TYPE_PARTICIPANTS:
         return ($old === null);
       case self::TYPE_TITLE:
+      case self::TYPE_TOPIC:
       case self::TYPE_PICTURE:
       case self::TYPE_DATE_MARKER:
         return false;
@@ -59,6 +61,7 @@
 
     switch ($this->getTransactionType()) {
       case self::TYPE_TITLE:
+      case self::TYPE_TOPIC:
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
@@ -147,6 +150,20 @@
         }
         return $title;
         break;
+      case self::TYPE_TOPIC:
+        if ($new) {
+          $title = pht(
+            '%s set the topic of this room to "%s".',
+            $this->renderHandleLink($author_phid),
+            $new);
+        } else if ($old) {
+          $title = pht(
+            '%s deleted the room topic "%s"',
+            $this->renderHandleLink($author_phid),
+            $old);
+        }
+        return $title;
+        break;
       case self::TYPE_PICTURE:
         return pht(
           '%s updated the room image.',
diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php
--- a/src/applications/conpherence/view/ConpherenceLayoutView.php
+++ b/src/applications/conpherence/view/ConpherenceLayoutView.php
@@ -105,9 +105,7 @@
       $classes[] = 'hide-widgets';
     }
 
-    $this->initBehavior(
-      'conpherence-widget-pane',
-      ConpherenceWidgetConfigConstants::getWidgetPaneBehaviorConfig());
+    $this->initBehavior('conpherence-participants-pane');
 
     return javelin_tag(
       'div',
diff --git a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php b/src/applications/conpherence/view/ConpherenceParticipantView.php
rename from src/applications/conpherence/view/ConpherencePeopleWidgetView.php
rename to src/applications/conpherence/view/ConpherenceParticipantView.php
--- a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php
+++ b/src/applications/conpherence/view/ConpherenceParticipantView.php
@@ -1,6 +1,25 @@
 <?php
 
-final class ConpherencePeopleWidgetView extends ConpherenceWidgetView {
+final class ConpherenceParticipantView extends AphrontView {
+
+  private $conpherence;
+  private $updateURI;
+
+  public function setUpdateURI($update_uri) {
+    $this->updateURI = $update_uri;
+    return $this;
+  }
+  public function getUpdateURI() {
+    return $this->updateURI;
+  }
+
+  public function setConpherence(ConpherenceThread $conpherence) {
+    $this->conpherence = $conpherence;
+    return $this;
+  }
+  public function getConpherence() {
+    return $this->conpherence;
+  }
 
   public function render() {
     $conpherence = $this->getConpherence();
@@ -14,6 +33,7 @@
     natcasesort($handle_list);
     $handles = mpull($handles, null, 'getName');
     $handles = array_select_keys($handles, $handle_list);
+
     $head_handles = mpull($head_handles, null, 'getName');
     $handles = $head_handles + $handles;
 
@@ -28,7 +48,8 @@
 
       if (($user_phid == $viewer->getPHID()) || $can_edit) {
         $icon = id(new PHUIIconView())
-          ->setIcon('fa-times lightbluetext');
+          ->setIcon('fa-times')
+          ->addClass('lightbluetext');
         $remove_html = javelin_tag(
           'a',
           array(
diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php
--- a/src/applications/conpherence/view/ConpherenceTransactionView.php
+++ b/src/applications/conpherence/view/ConpherenceTransactionView.php
@@ -231,6 +231,7 @@
         $content = $transaction->getTitle();
         break;
       case ConpherenceTransaction::TYPE_TITLE:
+      case ConpherenceTransaction::TYPE_TOPIC:
       case ConpherenceTransaction::TYPE_PICTURE:
       case ConpherenceTransaction::TYPE_PICTURE_CROP:
       case ConpherenceTransaction::TYPE_PARTICIPANTS:
diff --git a/src/applications/conpherence/view/ConpherenceWidgetView.php b/src/applications/conpherence/view/ConpherenceWidgetView.php
deleted file mode 100644
--- a/src/applications/conpherence/view/ConpherenceWidgetView.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-abstract class ConpherenceWidgetView extends AphrontView {
-
-  private $conpherence;
-  private $updateURI;
-
-  public function setUpdateURI($update_uri) {
-    $this->updateURI = $update_uri;
-    return $this;
-  }
-  public function getUpdateURI() {
-    return $this->updateURI;
-  }
-
-  public function setConpherence(ConpherenceThread $conpherence) {
-    $this->conpherence = $conpherence;
-    return $this;
-  }
-  public function getConpherence() {
-    return $this->conpherence;
-  }
-
-}
diff --git a/webroot/rsrc/css/aphront/dialog-view.css b/webroot/rsrc/css/aphront/dialog-view.css
--- a/webroot/rsrc/css/aphront/dialog-view.css
+++ b/webroot/rsrc/css/aphront/dialog-view.css
@@ -46,6 +46,10 @@
   border: none;
 }
 
+.device-phone .aphront-dialog-body {
+  padding: 8px;
+}
+
 .aphront-dialog-tail {
   border: none;
   position: relative;
diff --git a/webroot/rsrc/css/application/conpherence/header-pane.css b/webroot/rsrc/css/application/conpherence/header-pane.css
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/css/application/conpherence/header-pane.css
@@ -0,0 +1,68 @@
+/**
+ * @provides conpherence-header-pane-css
+ */
+
+.conpherence-header-pane {
+}
+
+.conpherence-header-pane .phui-header-shell {
+  padding: 8px 16px 10px;
+  min-height: 38px;
+}
+
+.conpherence-header-pane .phui-header-header {
+  font-size: 16px;
+  font-family: 'Aleo', {$fontfamily};
+  color: #000;
+}
+
+.conpherence-header-pane .phui-header-subheader {
+  color: {$lightgreyborder};
+  padding: 0;
+  font-size: 12px;
+  margin: 0;
+}
+
+.conpherence-header-pane .phui-header-shell.conpherence-no-topic {
+  padding: 15px 16px 5px;
+}
+
+.conpherence-header-pane .phui-header-action-list .phui-header-action-item
+  .phui-icon-view {
+  height: 18px;
+  width: 24px;
+  font-size: 14px;
+  line-height: 23px;
+  display: block;
+}
+
+.device .hide-on-device {
+  display: none;
+}
+
+.device-phone .conpherence-header-pane .phui-header-col3 {
+  vertical-align: middle;
+}
+
+.conpherence-header-pane .conpherence-participant-toggle.phui-icon-circle {
+  text-decoration: none;
+  border-color: {$sky};
+  cursor: pointer;
+}
+
+.conpherence-header-pane .conpherence-participant-toggle.phui-icon-circle
+  .phui-icon-view {
+    color: {$sky};
+}
+
+.hide-widgets .conpherence-header-pane
+  .conpherence-participant-toggle.phui-icon-circle {
+  text-decoration: none;
+  border-color: {$lightblueborder};
+  cursor: pointer;
+}
+
+.hide-widgets .conpherence-header-pane
+  .conpherence-participant-toggle.phui-icon-circle .phui-icon-view {
+    color: {$lightblueborder};
+}
diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css
--- a/webroot/rsrc/css/application/conpherence/message-pane.css
+++ b/webroot/rsrc/css/application/conpherence/message-pane.css
@@ -9,7 +9,7 @@
   position: fixed;
   left: 240px;
   right: 240px;
-  top: 76px;
+  top: 102px;
   bottom: 0px;
   min-width: 300px;
   width: auto;
@@ -32,11 +32,6 @@
   margin: 16px 0px 16px 0px;
 }
 
-.conpherence-layout .phui-crumbs-view {
-  padding: 0 0 0 8px;
-  background: #f7f7f7;
-}
-
 .conpherence-show-more-messages {
   display: block;
   background: #e0e3ec;
@@ -54,7 +49,7 @@
   position: fixed;
   left: 240px;
   right: 240px;
-  top: 78px;
+  top: 103px;
   bottom: 148px;
   overflow-x: hidden;
   overflow-y: auto;
@@ -103,13 +98,17 @@
 .conpherence-message-pane .phui-form-view {
   border-width: 0;
   height: 140px;
-  padding: 0 8px 8px;
+  padding: 0 20px 12px;
   position: fixed;
   bottom: 0;
   left: 240px;
   right: 241px;
 }
 
+.device .conpherence-message-pane .phui-form-view {
+  padding: 8px 8px;
+}
+
 .conpherence-message-pane .phui-form-view.login-to-participate {
   height: 26px;
 }
@@ -123,6 +122,11 @@
   margin-top: 6px;
 }
 
+.device .conpherence-message-pane .aphront-form-control-submit button,
+.device .conpherence-message-pane .aphront-form-control-submit a.button {
+  margin-top: 13px;
+}
+
 /**
  * When entering "Fullscreen Mode" in the remarkup control, we need to drop
  * all of the "position: fixed" on parent elements or Chrome doesn't put the
@@ -162,7 +166,7 @@
 
 .conpherence-message-pane .conpherence-transaction-view {
   padding: 2px 0px;
-  margin: 4px 12px;
+  margin: 4px 20px;
   background-size: 100%;
   min-height: auto;
 }
@@ -182,7 +186,9 @@
 }
 
 .device-phone .conpherence-message-pane .conpherence-transaction-image {
-  display: none;
+  height: 25px;
+  width: 25px;
+  background-size: 25px;
 }
 
 .conpherence-message-pane .conpherence-comment.anchor-target,
@@ -206,12 +212,12 @@
 }
 
 .device-phone .conpherence-message-pane .conpherence-transaction-detail {
-  margin: 0;
+  margin-left: 32px;
 }
 
 .conpherence-message-pane .conpherence-transaction-view.date-marker {
   padding: 0;
-  margin: 20px 12px 4px;
+  margin: 20px 20px 4px;
   min-height: auto;
 }
 
@@ -234,7 +240,6 @@
 
 .device .conpherence-message-pane .conpherence-transaction-view.date-marker
   .date {
-    color: {$lightbluetext};
     left: 4px;
 }
 
@@ -351,10 +356,3 @@
   max-height: 200px;
 }
 
-.device .conpherence-header-desktop-item {
-  display: none;
-}
-
-.device .conpherence-header-pane .phui-crumb-action-divider {
-  display: none;
-}
diff --git a/webroot/rsrc/css/application/conpherence/transaction.css b/webroot/rsrc/css/application/conpherence/transaction.css
--- a/webroot/rsrc/css/application/conpherence/transaction.css
+++ b/webroot/rsrc/css/application/conpherence/transaction.css
@@ -17,14 +17,14 @@
 }
 
 .conpherence-transaction-view.date-marker {
-  border-top: 1px solid {$thinblueborder};
+  border-top: 1px solid {$sh-violetborder};
 }
 
 .conpherence-transaction-view.date-marker .date {
   position: relative;
   top: -11px;
   background-color: #fff;
-  color: #000;
+  color: {$sh-violettext};
   font-weight: bold;
 }
 
diff --git a/webroot/rsrc/css/application/conpherence/update.css b/webroot/rsrc/css/application/conpherence/update.css
--- a/webroot/rsrc/css/application/conpherence/update.css
+++ b/webroot/rsrc/css/application/conpherence/update.css
@@ -2,10 +2,6 @@
  * @provides conpherence-update-css
  */
 
-.phabricator-standard-page-body .aphront-dialog-view {
-  margin: 20px auto 0px auto;
-}
-
 .aphront-dialog-view .conpherence-dialogue-drag-photo {
   border: 1px dashed #bfbfbf;
   padding: 10px 0px 10px 10px;
diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css
--- a/webroot/rsrc/css/application/conpherence/widget-pane.css
+++ b/webroot/rsrc/css/application/conpherence/widget-pane.css
@@ -2,11 +2,10 @@
  * @provides conpherence-widget-pane-css
  */
 
-.conpherence-widget-pane,
-.loading .widgets-loading-mask {
+.conpherence-widget-pane {
   position: fixed;
   right: 0px;
-  top: 79px;
+  top: 103px;
   bottom: 0;
   width: 240px;
   border-width: 0 0 0 1px;
@@ -15,20 +14,9 @@
   overflow-y: auto;
   -webkit-overflow-scrolling: touch;
 }
-.device .conpherence-widget-pane,
-.device .loading .widgets-loading-mask {
-  top: 44px;
-  width: 100%;
-}
-
-.conpherence-widget-pane .widgets-loading-mask {
-  opacity: .6;
-  background: #fff;
-  display: none;
-}
 
-.loading .widgets-loading-mask {
-  display: block;
+.device .conpherence-widget-pane {
+  background-color: {$page.background};
 }
 
 .conpherence-widget-pane .aphront-form-input {
@@ -48,84 +36,20 @@
   font-size: {$biggerfontsize};
 }
 
-.device .conpherence-widget-pane .widgets-header {
-  display: none;
-}
-
-.conpherence-widget-pane .widgets-header .caret {
-  float: none;
-  height: 0px;
-  width: 0px;
-  margin: 10px 0 0 4px;
-  border-top-color: #000;
-}
-
 .conpherence-widget-pane .widgets-header .phui-icon-view.disabled {
   color: {$lightgreytext};
 }
 
-.device-desktop .conpherence-layout .device-widgets-selector {
-  display: none;
-}
-
 .conpherence-widget-pane .widgets-body {
   position: fixed;
   overflow-y: auto;
   bottom: 0;
-  top: 76px;
-  width: 100%;
-}
-
-#widgets-settings {
-  padding: 3px 6px;
-}
-
-.device-desktop .conpherence-widget-pane .widgets-body {
-  top: 115px;
+  top: 144px;
   width: 240px;
 }
 
-.conpherence-widget-pane .widget-icon {
-  display: block;
-  height: 14px;
-  width: 14px;
-}
-
-.conpherence-widget-pane .phabricator-remarkup-embed-layout-link {
-  padding-bottom: 1px;
-}
-
-/* people widget */
-.conpherence-widget-pane .people-widget-header .add-people-widget {
-  padding: 10px 0 5px 0;
-  overflow: hidden;
-}
-
-.conpherence-widget-pane .people-widget-header .add-people-widget
-.aphront-form-control-tokenizer {
-  float: left;
-  width: 150px;
-  padding: 0px 0px 0px 10px
-}
-
-.device .conpherence-widget-pane .people-widget-header .add-people-widget
-.aphront-form-control-tokenizer {
-  width: 70%;
-}
-
-.conpherence-widget-pane .people-widget-header .add-people-widget
-.people-add-button {
-  float: right;
-  margin: 2px 8px 0px 0px;
-  padding: 3px 16px 4px 16px;
-}
-
-#widgets-people {
-  margin-top: 4px;
-}
-
 .conpherence-widget-pane .person-entry {
-  padding: 4px 8px;
+  padding: 4px 4px 4px 8px;
 }
 
 .conpherence-widget-pane .person-entry:hover {
@@ -173,35 +97,17 @@
   color: #000;
 }
 
-/* settings widget */
-.conpherence-widget-pane .title-update,
-.conpherence-widget-pane .notifications-update {
-  margin: 3px 0px 0px 4px;
-}
-
-.conpherence-widget-pane .no-settings {
-  width: 200px;
-  padding: 20px;
-  text-align: center;
-  color: {$greytext};
-}
-
-.device .conpherence-widget-pane .no-settings {
-  width: 60px;
-  margin: 0 auto 0 auto;
-}
-
 /****** Hide Widgets **********************************************************/
 
-.device-desktop .hide-widgets .conpherence-widget-pane {
+.hide-widgets .conpherence-widget-pane {
   display: none;
 }
 
-.device-desktop .hide-widgets .conpherence-message-pane,
-.device-desktop .hide-widgets .loading .messages-loading-mask,
-.device-desktop .hide-widgets .loading .messages-loading-icon,
-.device-desktop .hide-widgets .conpherence-no-threads,
-.device-desktop .hide-widgets .conpherence-message-pane .conpherence-messages,
-.device-desktop .hide-widgets .conpherence-message-pane .phui-form-view {
+.hide-widgets .conpherence-message-pane,
+.hide-widgets .loading .messages-loading-mask,
+.hide-widgets .loading .messages-loading-icon,
+.hide-widgets .conpherence-no-threads,
+.hide-widgets .conpherence-message-pane .conpherence-messages,
+.hide-widgets .conpherence-message-pane .phui-form-view {
   right: 0;
 }
diff --git a/webroot/rsrc/css/core/z-index.css b/webroot/rsrc/css/core/z-index.css
--- a/webroot/rsrc/css/core/z-index.css
+++ b/webroot/rsrc/css/core/z-index.css
@@ -150,6 +150,10 @@
   z-index: 21;
 }
 
+.conpherence-widget-pane {
+  z-index: 25;
+}
+
 .phuix-dropdown-menu {
   z-index: 32;
 }
diff --git a/webroot/rsrc/js/application/conpherence/behavior-menu.js b/webroot/rsrc/js/application/conpherence/behavior-menu.js
--- a/webroot/rsrc/js/application/conpherence/behavior-menu.js
+++ b/webroot/rsrc/js/application/conpherence/behavior-menu.js
@@ -241,7 +241,7 @@
     if (!data.widget) {
       data.widget = getDefaultWidget();
     }
-    var widget_uri = config.baseURI + 'widget/' + data.threadID + '/';
+    var widget_uri = config.baseURI + 'participant/' + data.threadID + '/';
     new JX.Workflow(widget_uri, {})
       .setHandler(JX.bind(null, onWidgetResponse, data.threadID, data.widget))
       .start();
diff --git a/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js b/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js
@@ -0,0 +1,112 @@
+/**
+ * @requires javelin-behavior
+ *           javelin-dom
+ *           javelin-stratcom
+ *           javelin-workflow
+ *           javelin-util
+ *           phabricator-notification
+ *           conpherence-thread-manager
+ * @provides javelin-behavior-conpherence-participants-pane
+ */
+
+JX.behavior('conpherence-participants-pane', function() {
+
+  /**
+   * Generified adding new stuff to widgets technology!
+   */
+  JX.Stratcom.listen(
+    ['click'],
+    'conpherence-widget-adder',
+    function (e) {
+      e.kill();
+
+      var threadManager = JX.ConpherenceThreadManager.getInstance();
+      var href = threadManager._getUpdateURI();
+      var latest_transaction_id = threadManager.getLatestTransactionID();
+      var data = {
+        latest_transaction_id : latest_transaction_id,
+        action : 'add_person'
+      };
+
+      var workflow = new JX.Workflow(href, data)
+        .setHandler(function (r) {
+          var threadManager = JX.ConpherenceThreadManager.getInstance();
+          threadManager.setLatestTransactionID(r.latest_transaction_id);
+          var root = JX.DOM.find(document, 'div', 'conpherence-layout');
+          var messages = null;
+          try {
+            messages = JX.DOM.find(root, 'div', 'conpherence-messages');
+          } catch (ex) {
+          }
+          if (messages) {
+            JX.DOM.appendContent(messages, JX.$H(r.transactions));
+            JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
+          }
+
+          try {
+            var people_root = JX.DOM.find(root, 'div', 'widgets-people');
+            // update the people widget
+            JX.DOM.setContent(
+              people_root,
+              JX.$H(r.people_widget));
+          } catch (ex) {
+          }
+
+        });
+
+      threadManager.syncWorkflow(workflow, 'submit');
+    }
+  );
+
+  JX.Stratcom.listen(
+    ['touchstart', 'mousedown'],
+    'remove-person',
+    function (e) {
+      var threadManager = JX.ConpherenceThreadManager.getInstance();
+      var href = threadManager._getUpdateURI();
+      var data = e.getNodeData('remove-person');
+
+      // While the user is removing themselves, disable the notification
+      // update behavior. If we don't do this, the user can get an error
+      // when they remove themselves about permissions as the notification
+      // code tries to load what jist happened.
+      var loadedPhid = threadManager.getLoadedThreadPHID();
+      threadManager.setLoadedThreadPHID(null);
+
+      new JX.Workflow(href, data)
+        .setCloseHandler(function() {
+          threadManager.setLoadedThreadPHID(loadedPhid);
+        })
+        // we re-direct to conpherence home so the thread manager will
+        // fix itself there
+        .setHandler(function(r) {
+          JX.$U(r.href).go();
+        })
+        .start();
+    }
+  );
+
+  /* settings widget */
+  var onsubmitSettings = function (e) {
+    e.kill();
+    var form = e.getNode('tag:form');
+    var button = JX.DOM.find(form, 'button');
+    JX.Workflow.newFromForm(form)
+    .setHandler(JX.bind(this, function (r) {
+      new JX.Notification()
+      .setDuration(6000)
+      .setContent(r)
+      .show();
+      button.disabled = '';
+      JX.DOM.alterClass(button, 'disabled', false);
+    }))
+    .start();
+  };
+
+  JX.Stratcom.listen(
+    ['submit', 'didSyntheticSubmit'],
+    'notifications-update',
+    onsubmitSettings
+  );
+
+});
diff --git a/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js b/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js
--- a/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js
+++ b/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js
@@ -14,6 +14,7 @@
     var node = JX.$('conpherence-main-layout');
     config.show = !config.show;
     JX.DOM.alterClass(node, 'hide-widgets', !config.show);
+    JX.Stratcom.invoke('resize');
 
     new JX.Request(config.settingsURI)
       .setData({value: (config.show ? 1 : 0)})
diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
deleted file mode 100644
--- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
+++ /dev/null
@@ -1,382 +0,0 @@
-/**
- * @requires javelin-behavior
- *           javelin-dom
- *           javelin-stratcom
- *           javelin-workflow
- *           javelin-util
- *           phabricator-notification
- *           javelin-behavior-device
- *           phuix-dropdown-menu
- *           phuix-action-list-view
- *           phuix-action-view
- *           conpherence-thread-manager
- * @provides javelin-behavior-conpherence-widget-pane
- */
-
-JX.behavior('conpherence-widget-pane', function(config) {
-
-  /**
-   * There can be race conditions around loading the messages or the widgets
-   * first. Keep track of what widgets we've loaded with this variable.
-   */
-  var _loadedWidgetsID = null;
-
-  /**
-   * At any given time there can be only one selected widget. Keep track of
-   * which one it is by the user-facing name for ease of use with
-   * PhabricatorDropdownMenuItems.
-   */
-  var _selectedWidgetName = null;
-
-  /**
-   * This is potentially built each time the user switches conpherence threads
-   * or when the result JX.Device.getDevice() changes from desktop to some
-   * other value.
-   */
-  var buildDeviceWidgetSelector = function (data) {
-    var device_header = _getDeviceWidgetHeader();
-    if (!device_header) {
-      return;
-    }
-    JX.DOM.show(device_header);
-    var device_menu = new JX.PHUIXDropdownMenu(device_header);
-    data.deviceMenu = true;
-    _buildWidgetSelector(device_menu, data);
-  };
-
-  /**
-   * This is potentially built each time the user switches conpherence threads
-   * or when the result JX.Device.getDevice() changes from mobile or tablet to
-   * desktop.
-   */
-  var buildDesktopWidgetSelector = function (data) {
-    var root = JX.DOM.find(document, 'div', 'conpherence-layout');
-    var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
-    var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector');
-
-    var menu = new JX.PHUIXDropdownMenu(widget_header);
-    menu
-      .setAlign('left')
-      .setOffsetY(4);
-
-    data.deviceMenu = false;
-    _buildWidgetSelector(menu, data);
-  };
-
-  /**
-   * Workhorse that actually builds the widget selector. Note some fancy bits
-   * where we listen for the "open" event and enable / disable widgets as
-   * appropos.
-   */
-  var _buildWidgetSelector = function (menu, data) {
-    _loadedWidgetsID = data.threadID;
-
-    var list = new JX.PHUIXActionListView();
-    var map = {};
-
-    var widgets = config.widgetRegistry;
-    for (var widget in widgets) {
-      var widget_data = widgets[widget];
-      if (widget_data.deviceOnly && data.deviceMenu === false) {
-        continue;
-      }
-
-      var handler;
-      var href;
-      handler = JX.bind(null, function(widget, e) {
-        toggleWidget({widget: widget});
-        e.prevent();
-        menu.close();
-      }, widget);
-      var item = new JX.PHUIXActionView()
-        .setIcon(widget_data.icon || 'none')
-        .setName(widget_data.name)
-        .setHref(href)
-        .setHandler(handler);
-      map[widget_data.name] = item;
-      list.addItem(item);
-    }
-
-    menu
-      .setWidth(200)
-      .setContent(list.getNode());
-
-    menu.listen('open', function() {
-      for (var k in map) {
-        map[k].setDisabled((k == _selectedWidgetName));
-      }
-    });
-  };
-
-  /**
-   * Since this is not always on the page, avoid having a repeat
-   * try / catch block and consolidate into this helper function.
-   */
-  var _getDeviceWidgetHeader = function () {
-    var root = JX.DOM.find(document, 'div', 'conpherence-layout');
-    var device_header = null;
-    try {
-      device_header = JX.DOM.find(
-        root,
-        'a',
-        'device-widgets-selector');
-    } catch (ex) {
-      // is okay - no deviceWidgetHeader yet... but bail time
-    }
-    return device_header;
-  };
-
-  /**
-   * Responder to the 'conpherence-did-redraw-thread' event, this bad boy
-   * hides or shows the device widget selector as appropros.
-   */
-  var _didRedrawThread = function (data) {
-    if (_loadedWidgetsID === null || _loadedWidgetsID != data.threadID) {
-      return;
-    }
-    var device = JX.Device.getDevice();
-    var device_selector = _getDeviceWidgetHeader();
-    if (device == 'desktop') {
-      JX.DOM.hide(device_selector);
-    } else {
-      JX.DOM.show(device_selector);
-    }
-    if (data.buildDeviceWidgetSelector) {
-      buildDeviceWidgetSelector(data);
-    }
-    toggleWidget(data);
-  };
-  JX.Stratcom.listen(
-    'conpherence-did-redraw-thread',
-    null,
-    function (e) {
-      _didRedrawThread(e.getData());
-    }
-  );
-
-  /**
-   * Toggling a widget involves showing / hiding the appropriate widget
-   * bodies as well as updating the selectors to have the label on the
-   * newly selected widget.
-   */
-  var toggleWidget = function (data) {
-    var widgets = config.widgetRegistry;
-    var widget_data = widgets[data.widget];
-    var device = JX.Device.getDevice();
-    var is_desktop = device == 'desktop';
-
-    if (widget_data.deviceOnly && is_desktop) {
-      return;
-    }
-    _selectedWidgetName = widget_data.name;
-
-    var device_header = _getDeviceWidgetHeader();
-    if (device_header) {
-      // this is fragile but adding a sigil to this element is awkward
-      var device_header_spans = JX.DOM.scry(device_header, 'span');
-      var device_header_span = device_header_spans[1];
-      JX.DOM.setContent(
-        device_header_span,
-        widget_data.name);
-    }
-
-    // don't update the non-device selector with device only widget stuff
-    if (!widget_data.deviceOnly) {
-      var root = JX.DOM.find(document, 'div', 'conpherence-layout');
-      var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
-      var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector');
-      var adder = JX.DOM.find(widget_pane, 'a', 'conpherence-widget-adder');
-      var threadManager = JX.ConpherenceThreadManager.getInstance();
-      var disabled = !threadManager.getCanEditLoadedThread();
-      JX.DOM.setContent(
-        widget_header,
-        widget_data.name);
-      JX.DOM.appendContent(
-        widget_header,
-        JX.$N('span', { className : 'caret' }));
-      if (widget_data.hasCreate) {
-        JX.DOM.show(adder);
-        JX.DOM.alterClass(
-          adder,
-          'disabled',
-          disabled);
-      } else {
-        JX.DOM.hide(adder);
-      }
-    }
-
-    for (var widget in config.widgetRegistry) {
-      widget_data = widgets[widget];
-      if (widget_data.deviceOnly && is_desktop) {
-        // some one off code for conpherence messages which are device-only
-        // as a widget, but shown always on the desktop
-        if (widget == 'conpherence-message-pane') {
-          JX.$(widget).style.display = 'block';
-        }
-        continue;
-      }
-      if (widget == data.widget) {
-        JX.$(widget).style.display = 'block';
-        // some one off code for conpherence messages - fancier refresh tech
-        if (widget == 'conpherence-message-pane') {
-          JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
-          JX.Stratcom.invoke('conpherence-update-page-data', null, {});
-        }
-      } else {
-        JX.$(widget).style.display = 'none';
-      }
-    }
-  };
-
-  JX.Stratcom.listen(
-    'conpherence-update-widgets',
-    null,
-    function (e) {
-      var data = e.getData();
-      if (data.buildSelectors) {
-        buildDesktopWidgetSelector(data);
-        buildDeviceWidgetSelector(data);
-      }
-      if (data.toggleWidget) {
-        toggleWidget(data);
-      }
-    });
-
-  /**
-   * Generified adding new stuff to widgets technology!
-   */
-  JX.Stratcom.listen(
-    ['click'],
-    'conpherence-widget-adder',
-    function (e) {
-      e.kill();
-
-      var widgets = config.widgetRegistry;
-      // the widget key might be in node data, but otherwise use the
-      // selected widget
-      var event_data = e.getNodeData('conpherence-widget-adder');
-      var widget_key = _selectedWidgetName;
-      if (event_data.widget) {
-        widget_key = widgets[event_data.widget].name;
-      }
-
-      var widget_to_update = null;
-      var create_data = null;
-      for (var widget in widgets) {
-        if (widgets[widget].name == widget_key) {
-          create_data = widgets[widget].createData;
-          widget_to_update = widget;
-          break;
-        }
-      }
-      // this should be impossible, but hey
-      if (!widget_to_update) {
-        return;
-      }
-      var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/';
-      if (create_data.customHref) {
-        href = create_data.customHref;
-      }
-
-      var threadManager = JX.ConpherenceThreadManager.getInstance();
-      var latest_transaction_id = threadManager.getLatestTransactionID();
-      var data = {
-        latest_transaction_id : latest_transaction_id,
-        action : create_data.action
-      };
-
-      var workflow = new JX.Workflow(href, data)
-        .setHandler(function (r) {
-          var threadManager = JX.ConpherenceThreadManager.getInstance();
-          threadManager.setLatestTransactionID(r.latest_transaction_id);
-          var root = JX.DOM.find(document, 'div', 'conpherence-layout');
-          if (create_data.refreshFromResponse) {
-            var messages = null;
-            try {
-              messages = JX.DOM.find(root, 'div', 'conpherence-messages');
-            } catch (ex) {
-            }
-            if (messages) {
-              JX.DOM.appendContent(messages, JX.$H(r.transactions));
-              JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
-            }
-
-            if (r.people_widget) {
-              try {
-                var people_root = JX.DOM.find(root, 'div', 'widgets-people');
-                // update the people widget
-                JX.DOM.setContent(
-                  people_root,
-                  JX.$H(r.people_widget));
-              } catch (ex) {
-              }
-            }
-
-          // otherwise let's redraw the widget somewhat lazily
-          } else {
-            JX.Stratcom.invoke(
-              'conpherence-reload-widget',
-              null,
-              {
-                threadID : _loadedWidgetsID,
-                widget : widget_to_update
-              });
-          }
-        });
-
-      threadManager.syncWorkflow(workflow, 'submit');
-    }
-  );
-
-  JX.Stratcom.listen(
-    ['touchstart', 'mousedown'],
-    'remove-person',
-    function (e) {
-      var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/';
-      var data = e.getNodeData('remove-person');
-
-      // While the user is removing themselves, disable the notification
-      // update behavior. If we don't do this, the user can get an error
-      // when they remove themselves about permissions as the notification
-      // code tries to load what jist happened.
-      var threadManager = JX.ConpherenceThreadManager.getInstance();
-      var loadedPhid = threadManager.getLoadedThreadPHID();
-      threadManager.setLoadedThreadPHID(null);
-
-      new JX.Workflow(href, data)
-        .setCloseHandler(function() {
-          threadManager.setLoadedThreadPHID(loadedPhid);
-        })
-        // we re-direct to conpherence home so the thread manager will
-        // fix itself there
-        .setHandler(function(r) {
-          JX.$U(r.href).go();
-        })
-        .start();
-    }
-  );
-
-  /* settings widget */
-  var onsubmitSettings = function (e) {
-    e.kill();
-    var form = e.getNode('tag:form');
-    var button = JX.DOM.find(form, 'button');
-    JX.Workflow.newFromForm(form)
-    .setHandler(JX.bind(this, function (r) {
-      new JX.Notification()
-      .setDuration(6000)
-      .setContent(r)
-      .show();
-      button.disabled = '';
-      JX.DOM.alterClass(button, 'disabled', false);
-    }))
-    .start();
-  };
-
-  JX.Stratcom.listen(
-    ['submit', 'didSyntheticSubmit'],
-    'notifications-update',
-    onsubmitSettings
-  );
-
-});