       :background-size "contain"}]]
 
    [:.option
-    {:margin [[small-spacing 0]]}
+    {:margin [[small-spacing 0]]
+     :position "relative"}
 
     [:h2
      {:font-size "1em"

           [:div.explanation
            [:p "Anyone can find and join your group through the Braid Group Directory."]
            [:p "Unlimited everything. Free forever."]]]
          [:label
           [:input {:type "radio"
                    :name "type"
                    :value "private"
                    :checked (when (= "private" (@fields :type)))
                    :on-click (fn [e]
                                (let [value (.. e -target -value)]
                                  (swap! fields assoc :type value)))}]

  [:h1 "Braid"])

(defn form-view []
  (let [fields (r/atom {:name ""
                        :url ""
                        :type ""})
        focused? (r/atom {:name nil
                          :url nil
                          :type nil})]
    (fn []
      (let [blank? {:name (string/blank? (@fields :name))
                    :url (string/blank? (@fields :url))
                    :type (string/blank? (@fields :type))}
            validations {:name [{:valid? (not (blank? :name))
                                 :message "Your group needs a name"}]
                         :url [{:valid? (not (blank? :url))
                                :message "Your group needs a URL"}
                               {:valid? (boolean (re-matches #"[a-z0-9-]*" (@fields :url)))
                                :message "Your URL can only contain lowercase letters, numbers or dashes"}
                               {:valid? (not (re-matches #"-.*" (@fields :url)))
                                :message "Your URL can't start with a -"}
                               {:valid? (not (re-matches #".*-" (@fields :url)))
                                :message "Your URL can't end with a -"}]
                         :type [{:valid? (not (blank? :type))
                                 :message "You need to select a group type"}]}
            tee (fn [x]
                  (println x) x)
            valid? (fn [field]
                     (->> (validations field)
                          (map :valid?)
                          tee
                          (every? true?)))
            messages (fn [field]
                       (->> (validations field)
                            (remove :valid?)
                            (map :message)))
            _ (println (valid? :url))
            show-status? {:name (and
                                  (not (@focused? :name))
                                  (not (blank? :name)))
                          :url (and
                                 (not (@focused? :url))
                                 (not (blank? :url)))
                          :type (and
                                  (not (@focused? :type))
                                  (not (blank? :type)))}
            all-valid? (and (valid? :name) (valid? :url) (valid? :type))]
        [:form.register
         [header-view]

         [:div.option.group-name
          {:class (when (show-status? :name)
                    (if (valid? :name)
                      "valid" "invalid"))}
          [:label
           [:h2 "Group Name"]
           [:div.field
            [:input {:type "text"
                     :placeholder "Team Awesome"
                     :auto-focus true
                     :value (@fields :name) ; TODO guess from email
                     :on-focus (fn [_]
                                 (swap! focused? assoc :name true))
                     :on-blur (fn [_]
                                (swap! focused? assoc :name false))
                     :on-change (fn [e]
                                  (let [value (.. e -target -value)]
                                    (swap! fields assoc :name value)))}]]
           (when (and (show-status? :name) (not (valid? :name)))
             [:div.error-message (first (messages :name))])
           [:div.explanation
            [:p "Your group's name will show up in menus and headings. It doesn't need to be formal."]]]]

         [:div.option.group-url
          {:class (when (show-status? :url)
                    (if (valid? :url)
                      "valid" "invalid"))}
          [:label
           [:h2 "Group URL"]
           [:div.field
            [:input {:type "text"
                     :placeholder "awesome"
                     :autocomplete false
                     :autocorrect false
                     :autocapitalize false
                     :spellcheck false
                     :value (@fields :url) ; TODO guess from email
                     :on-focus (fn [_]
                                 (swap! focused? assoc :url true))
                     :on-blur (fn [_]
                                (swap! focused? assoc :url false))
                     :on-key-down (fn [e]
                                    (when (and
                                            (not (contains? #{KeyCodes.LEFT KeyCodes.RIGHT
                                                              KeyCodes.UP KeyCodes.DOWN
                                                              KeyCodes.TAB KeyCodes.BACKSPACE}
                                                            (.. e -keyCode)))
                                            (not (re-matches #"[a-z0-9-]" (.. e -key))))
                                      (.preventDefault e)))
                     :on-change (fn [e]
                                  (let [value (.. e -target -value)]
                                    (swap! fields assoc :url value)))}]
            [:span ".braid.chat"]]
           (when (and (show-status? :url) (not (valid? :url)))
             [:div.error-message (first (messages :url))])
           [:div.explanation
            [:p "Pick something short and recognizeable."]
            [:p "Lowercase letters, numbers and dashes only."]]]]

         [:div.option.group-type
          [:h2 "Group Type"]
          [:label {:class (when (= "public" (@fields :type)) "checked")}
           [:input {:type "radio"
                    :name "type"
                    :value "public"
                    :checked (when (= "public" (@fields :type)))
                    :on-focus (fn [_]
                                (swap! focused? assoc :type true))
                    :on-blur (fn [_]
                               (swap! focused? assoc :type false))
                    :on-click (fn [e]
                                (let [value (.. e -target -value)]
                                  (swap! fields assoc :type value)))}]
