 
 (def child-item? (complement (some-fn attrs-or-map? css? nil? empty?)))
 
-(defn assoc-attrs [t & key-vals]
-	(assoc t :attrs (merge (:attrs t) (apply hash-map key-vals))))
-
-(defn assoc-css [t & key-vals]
-	(assoc t :css (merge (:css t) (apply hash-map key-vals))))
-
-(defn attrs [& key-vals] (merge empty-attrs (apply hash-map key-vals)))
-
-(defn css [& key-vals] (merge empty-css (apply hash-map key-vals)))
+(defn assoc-attrs [t & {:as key-vals}] (update-in t [:attrs] (merge key-vals)))
+
+(defn assoc-css [t & {:as key-vals}] (update-in t [:css] (merge key-vals)))
+
+(defn attrs [& {:as key-vals}] (merge empty-attrs key-vals))
+
+(defn css [& {:as key-vals}] (merge empty-css key-vals))
 
 (defn tag [tag-name & stuff]
 	(let [attrs (apply merge empty-attrs (filter attrs-or-map? stuff))


(defn page-meta [prop value] (tag "meta" {:name prop :content value}))

;; Higher-order "tags"

(defn comp-tag [t u] (fn [& items] (t (map u (flatten items)))))


(def row-cells (comp-tag tr td))

(defn table-rows [& rows] (table (map (comp row-cells flatten) rows)))

(defn radio-list [param & opts] (mapcat (fn [[text value]] [(radio param value) (label text {:for value})]) (partition 2 opts)))

(defn vertical-radio-list [param & opts] (apply table-rows (partition 2 (apply radio-list param opts))))

;; CSS Units

