    "width" (:x value)})
 
 (defn get-border-width-css [value]
-  {"border-width" value
-   "border-style" "solid"})
+  {"borderWidth" value
+   "borderStyle" "solid"})
+
+(defn get-opacity-css [value]
+  {"opacity" value})
 
 (defn get-border-color-css [value]
-  {"border-color" value
-   "border-style" "solid"})
+  {"borderColor" value
+   "borderStyle" "solid"})
+
+(defn get-border-radius-css [value])
+
+(defn get-border-style-css [value])
+
+(defn get-transform-css [{rotation :Rotation, scale :Scale, pivot :PivotPoint, 
+                          :or {rotation 0, scale 1, pivot {:x 0, :y 0}}}]
+  {html5TransformProperty (str "rotation(" rotation ") scale(" scale ")")
+   html5TransformOriginProperty (str (:x pivot) "px " (:y pivot) "px")})
 
 ; translation from morph data to CSS style prop
 
 (defn dict->js [dict]
   (apply js-obj (apply concat (seq dict))))
 
-(defn extract-style [state]
+(defn extract-morph-css [->self]
   (apply merge 
-        (map (fn [[prop value]] 
-            (case prop 
-              :Fill (get-fill-css value)
+     (let [morph-props (get ->self :morph)]
+       (map (fn [[prop value]]               
+          (let [value value]
+             (case prop 
               :Position (get-position-css value)
+              (:Scale :Rotation :PivotPoint) (get-transform-css morph-props)
+              ;; more to come... 
+              nil))) morph-props))))
+
+(defn extract-shape-css [->self]
+  (apply merge 
+       (map (fn [[prop value]]               
+          (let [value value]
+             (case prop 
               :Extent (get-extent-css value)
               :BorderWidth (get-border-width-css value)
               :BorderColor (get-border-color-css value)
+              :Fill (get-fill-css value)
+              :Opacity (get-opacity-css value)
+              :BorderRadius (get-border-radius-css value)
+              :BorderStyle (get-border-style-css value)
+;   _BorderStyle: {/*...*/},
+;   _ClipMode: {/*...*/},
+;   _PreviousBorderWidth: {/*...*/},
+;   _StyleClassNames: {/*...*/},
+;   _StyleSheet: {/*...*/},
+; }
               ;; more to come... 
-              nil
-              )) state)))
+                nil))) (get ->self :shape))))
 
 ; morph component + rendering functions
 
+; multimethod for shape
 (defmulti shape (fn [app owner] (get-in app [:shape :ShapeClass])))
+
+; multimethod for morph
 (defmulti morph (fn [app owner] (get-in app [:morph :MorphClass])))
 
 ; utilities

                   :stroke (get-in app [:shape :Fill]) 
                   :d (to-svg-attr (get-in app [:shape :PathElements]))}))))

(defmethod shape "Image" [app owner]
  (let [style (dict->js (extract-style (:shape app)))]
    (dom/img #js {:style style
                  :draggable false
                  :src (get-in app [:shape :url])})))

(defmethod shape "Path" [app owner]
  (let [style (extract-style (:shape app))]
      (dom/div #js {:style (dict->js style) :className "Morph Path"} 
        ; we render a svg sub-tag into which we place a 
        ; <path> that covers the given PathElements
        (render-path-node app owner)
        (render-submorphs app))))
  
(defmethod shape "Ellipse" [app owner]
  (let [style (extract-style (:shape app))]
    ;; we apply some customizations to the style, to make the shape elliptical
    (let [ellipse-style (assoc style 
                          "border-radius" (str (style "width") " /" (style "height")))]
      (dom/div #js {:style (dict->js ellipse-style)} (render-submorphs app)))))

(defmethod shape "Text" [app owner]
  (prn "Rendering Text Shape")
  (let [style (extract-style (:shape app))]
    (let [text-style (assoc style "cursor" "default")]
      (dom/div #js {:style (dict->js text-style)
                    :className "Morph Text"} (create-text-node app owner)))))

(defmethod shape :default [app owner]
  (let [style (extract-style (:shape app))]
    (dom/div #js {:style (dict->js style)} (render-submorphs app))))
      (prn (.-timeStamp event) " ... was not yet handled!")
      true)))

(defn handle-click [e state]
  ; add/remove morph from preserve list
  ; (branch-merge/toggle-preserve state)
  ; handle the custom behavior
  (when (and (not-yet-handled e) (.-altKey e))
    (@right-click-behavior e @state))
  (when-let [cb (get-in @state [:morph :onClick])] 
              (cb state)))

; morph property to CSS property translators

(defn get-fill-css [value]
