diff --git a/web/modals/threads/new-thread-modal.react.js b/web/modals/threads/new-thread-modal.react.js
deleted file mode 100644
--- a/web/modals/threads/new-thread-modal.react.js
+++ /dev/null
@@ -1,318 +0,0 @@
-// @flow
-
-import invariant from 'invariant';
-import * as React from 'react';
-
-import { newThreadActionTypes, newThread } from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import {
-  generateRandomColor,
-  threadTypeDescriptions,
-} from 'lib/shared/thread-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import {
-  type ThreadInfo,
-  threadTypes,
-  assertThreadType,
-  type ThreadType,
-  type ClientNewThreadRequest,
-  type NewThreadResult,
-} from 'lib/types/thread-types';
-import {
-  type DispatchActionPromise,
-  useDispatchActionPromise,
-  useServerCall,
-} from 'lib/utils/action-utils';
-import { firstLine } from 'lib/utils/string-utils';
-
-import Button from '../../components/button.react';
-import { useSelector } from '../../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../../selectors/nav-selectors';
-import css from '../../style.css';
-import Modal from '../modal.react';
-import ColorPicker from './color-picker.react';
-
-type BaseProps = {
-  +onClose: () => void,
-  +parentThreadID?: ?string,
-};
-type Props = {
-  ...BaseProps,
-  +inputDisabled: boolean,
-  +calendarQuery: () => CalendarQuery,
-  +parentThreadInfo: ?ThreadInfo,
-  +dispatchActionPromise: DispatchActionPromise,
-  +newThread: (request: ClientNewThreadRequest) => Promise<NewThreadResult>,
-};
-type State = {
-  +threadType: ?ThreadType,
-  +name: string,
-  +description: string,
-  +color: string,
-  +errorMessage: string,
-};
-
-const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
-
-class NewThreadModal extends React.PureComponent<Props, State> {
-  nameInput: ?HTMLInputElement;
-  openPrivacyInput: ?HTMLInputElement;
-  threadPasswordInput: ?HTMLInputElement;
-
-  constructor(props: Props) {
-    super(props);
-    this.state = {
-      threadType: props.parentThreadID ? undefined : COMMUNITY_SECRET_SUBTHREAD,
-      name: '',
-      description: '',
-      color: props.parentThreadInfo
-        ? props.parentThreadInfo.color
-        : generateRandomColor(),
-      errorMessage: '',
-    };
-  }
-
-  componentDidMount() {
-    invariant(this.nameInput, 'nameInput ref unset');
-    this.nameInput.focus();
-  }
-
-  render() {
-    let threadTypeSection = null;
-    if (this.props.parentThreadID) {
-      threadTypeSection = (
-        <div className={css['new-thread-privacy-container']}>
-          <div className={css['modal-radio-selector']}>
-            <div className={css['form-title']}>Chat type</div>
-            <div className={css['form-enum-selector']}>
-              <div className={css['form-enum-container']}>
-                <input
-                  type="radio"
-                  name="new-thread-type"
-                  id="new-thread-open"
-                  value={COMMUNITY_OPEN_SUBTHREAD}
-                  checked={this.state.threadType === COMMUNITY_OPEN_SUBTHREAD}
-                  onChange={this.onChangeThreadType}
-                  disabled={this.props.inputDisabled}
-                  ref={this.openPrivacyInputRef}
-                />
-                <div className={css['form-enum-option']}>
-                  <label htmlFor="new-thread-open">
-                    Open
-                    <span className={css['form-enum-description']}>
-                      {threadTypeDescriptions[COMMUNITY_OPEN_SUBTHREAD]}
-                    </span>
-                  </label>
-                </div>
-              </div>
-              <div className={css['form-enum-container']}>
-                <input
-                  type="radio"
-                  name="new-thread-type"
-                  id="new-thread-closed"
-                  value={COMMUNITY_SECRET_SUBTHREAD}
-                  checked={this.state.threadType === COMMUNITY_SECRET_SUBTHREAD}
-                  onChange={this.onChangeThreadType}
-                  disabled={this.props.inputDisabled}
-                />
-                <div className={css['form-enum-option']}>
-                  <label htmlFor="new-thread-closed">
-                    Secret
-                    <span className={css['form-enum-description']}>
-                      {threadTypeDescriptions[COMMUNITY_SECRET_SUBTHREAD]}
-                    </span>
-                  </label>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      );
-    }
-    return (
-      <Modal name="New chat" onClose={this.props.onClose} size="large">
-        <div className={css['modal-body']}>
-          <form method="POST">
-            <div>
-              <div className={css['form-title']}>Chat name</div>
-              <div className={css['form-content']}>
-                <input
-                  type="text"
-                  value={firstLine(this.state.name)}
-                  placeholder="Chat name"
-                  onChange={this.onChangeName}
-                  disabled={this.props.inputDisabled}
-                  ref={this.nameInputRef}
-                />
-              </div>
-            </div>
-            <div className={css['form-textarea-container']}>
-              <div className={css['form-title']}>Description</div>
-              <div className={css['form-content']}>
-                <textarea
-                  value={this.state.description}
-                  placeholder="Chat description"
-                  onChange={this.onChangeDescription}
-                  disabled={this.props.inputDisabled}
-                />
-              </div>
-            </div>
-            {threadTypeSection}
-            <div>
-              <div className={`${css['form-title']} ${css['color-title']}`}>
-                Color
-              </div>
-              <div className={css['form-content']}>
-                <ColorPicker
-                  id="new-thread-color"
-                  value={this.state.color}
-                  disabled={this.props.inputDisabled}
-                  onChange={this.onChangeColor}
-                />
-              </div>
-            </div>
-            <div className={css['form-footer']}>
-              <Button
-                onClick={this.onSubmit}
-                disabled={this.props.inputDisabled}
-                type="submit"
-              >
-                Save
-              </Button>
-              <div className={css['modal-form-error']}>
-                {this.state.errorMessage}
-              </div>
-            </div>
-          </form>
-        </div>
-      </Modal>
-    );
-  }
-
-  nameInputRef = (nameInput: ?HTMLInputElement) => {
-    this.nameInput = nameInput;
-  };
-
-  openPrivacyInputRef = (openPrivacyInput: ?HTMLInputElement) => {
-    this.openPrivacyInput = openPrivacyInput;
-  };
-
-  onChangeName = (event: SyntheticEvent<HTMLInputElement>) => {
-    const target = event.target;
-    invariant(target instanceof HTMLInputElement, 'target not input');
-    this.setState({ name: firstLine(target.value) });
-  };
-
-  onChangeDescription = (event: SyntheticEvent<HTMLTextAreaElement>) => {
-    const target = event.target;
-    invariant(target instanceof HTMLTextAreaElement, 'target not textarea');
-    this.setState({ description: target.value });
-  };
-
-  onChangeColor = (color: string) => {
-    this.setState({ color: color });
-  };
-
-  onChangeThreadType = (event: SyntheticEvent<HTMLInputElement>) => {
-    const target = event.target;
-    invariant(target instanceof HTMLInputElement, 'target not input');
-    this.setState({
-      threadType: assertThreadType(parseInt(target.value, 10)),
-    });
-  };
-
-  onSubmit = (event: SyntheticEvent<HTMLElement>) => {
-    event.preventDefault();
-
-    const threadType = this.state.threadType;
-    invariant(
-      threadType !== null,
-      'threadType state should never be set to null',
-    );
-    if (threadType === undefined) {
-      this.setState(
-        {
-          errorMessage: 'chat type unspecified',
-        },
-        () => {
-          invariant(this.openPrivacyInput, 'openPrivacyInput ref unset');
-          this.openPrivacyInput.focus();
-        },
-      );
-      return;
-    }
-
-    this.props.dispatchActionPromise(
-      newThreadActionTypes,
-      this.newThreadAction(threadType),
-    );
-  };
-
-  async newThreadAction(threadType: ThreadType) {
-    const name = this.state.name.trim();
-    try {
-      invariant(
-        threadType === 3 ||
-          threadType === 4 ||
-          threadType === 6 ||
-          threadType === 7,
-        "Sidebars and communities can't be created from the chat composer",
-      );
-      const query = this.props.calendarQuery();
-      const response = await this.props.newThread({
-        type: threadType,
-        name,
-        description: this.state.description,
-        color: this.state.color,
-        calendarQuery: query,
-      });
-      this.props.onClose();
-      return response;
-    } catch (e) {
-      this.setState(
-        {
-          threadType: undefined,
-          name: '',
-          description: '',
-          color: '',
-          errorMessage: 'unknown error',
-        },
-        () => {
-          invariant(this.nameInput, 'nameInput ref unset');
-          this.nameInput.focus();
-        },
-      );
-      throw e;
-    }
-  }
-}
-
-const loadingStatusSelector = createLoadingStatusSelector(newThreadActionTypes);
-
-const ConnectedNewThreadModal: React.ComponentType<BaseProps> = React.memo<BaseProps>(
-  function ConnectedNewThreadModal(props) {
-    const { parentThreadID } = props;
-    const parentThreadInfo: ?ThreadInfo = useSelector(state =>
-      parentThreadID ? threadInfoSelector(state)[parentThreadID] : null,
-    );
-    invariant(!parentThreadID || parentThreadInfo, 'parent chat should exist');
-    const inputDisabled = useSelector(loadingStatusSelector) === 'loading';
-    const calendarQuery = useSelector(nonThreadCalendarQuery);
-    const callNewThread = useServerCall(newThread);
-    const dispatchActionPromise = useDispatchActionPromise();
-
-    return (
-      <NewThreadModal
-        {...props}
-        parentThreadInfo={parentThreadInfo}
-        inputDisabled={inputDisabled}
-        calendarQuery={calendarQuery}
-        newThread={callNewThread}
-        dispatchActionPromise={dispatchActionPromise}
-      />
-    );
-  },
-);
-
-export default ConnectedNewThreadModal;
diff --git a/web/style.css b/web/style.css
--- a/web/style.css
+++ b/web/style.css
@@ -164,35 +164,6 @@
   line-height: 0;
 }
 
-div.form-enum-selector {
-  display: inline-block;
-  padding-bottom: 4px;
-}
-div.form-enum-selector > div.form-enum-container {
-  padding-top: 5px;
-}
-div.form-enum-selector > div.form-enum-container > input {
-  vertical-align: top;
-  margin-top: 4px;
-}
-div.form-enum-selector div.form-enum-option {
-  display: inline-block;
-  font-size: 15px;
-  font-weight: 600;
-  padding-left: 3px;
-}
-div.form-enum-selector span.form-enum-description {
-  display: block;
-  font-family: var(--font-stack);
-  font-weight: normal;
-  font-size: 13px;
-  max-width: 260px;
-  color: gray;
-}
-div.color-title {
-  margin-top: 4px;
-}
-
 .hidden {
   display: none;
 }
@@ -200,15 +171,6 @@
   font-style: italic;
 }
 
-div.form-textarea-container {
-  margin-top: 1px;
-}
-
-div.new-thread-privacy-container {
-  margin-bottom: 3px;
-  margin-top: -6px;
-}
-
 span.page-loading {
   margin-top: 5px;
   margin-right: 12px;