 
 ;; Core types
 
-(defn- str-attrs [attrs]
-	(str-join (map (fn [[k v]] [" " k "=\"" (html-escape v) "\""]) attrs)))
+(defrecord Attrs []
+	java.lang.Object
+	(toString [this]
+		(str-join (map (fn [[k v]] [" " k "=\"" (html-escape v) "\""]) this)))
+	clojure.lang.IFn
+	(invoke [this] this)
+	(invoke [this x] (.applyTo this (list x)))
+	(applyTo [this args] (let [t (first args)] (t this))))
 
 (defrecord Css []
 	java.lang.Object

(defn extend-tag [t & stuff]
	(if (empty? stuff)
		t
		(let [attrs (apply merge (:attrs t) (filter attrs? stuff))
		      css (apply merge (:css t) (filter css? stuff))
		      items (concat (:items t) (flatten (filter child-item? stuff)))]
			(Tag. (:tag-name t) attrs css items))))

(defn radio-list [param & opts]
	(mapcat (fn [[t v]] [(label v {:for t}) (input {:id v :value v :name param :type "radio"})]) opts))

;; CSS Units

(defmacro defunit [suffix] `(defn ~suffix [~'x] (if (number? ~'x) (str ~'x ~(name suffix)) (str-k ~'x))))

(defunit px)
(defunit deg)
(defunit %)

;; CSS Value Builders

(defmacro defcssval [id & args]
	(let [prepare-arg (fn [arg] (if (.contains (name arg) "angle") `(deg ~arg) `(str-k ~arg)))
