diff --git a/Clckwrks/Media/Page/Upload.hs b/Clckwrks/Media/Page/Upload.hs
--- a/Clckwrks/Media/Page/Upload.hs
+++ b/Clckwrks/Media/Page/Upload.hs
@@ -11,6 +11,7 @@
 import Clckwrks.Media.Monad (MediaConfig(..), MediaM, MediaForm)
 import Clckwrks.Media.Types (Medium(..), MediumId(..), MediumKind(..))
 import Clckwrks.Media.URL   (MediaURL(..))
+import Data.List            (intercalate)
 import           Data.Map   (Map)
 import qualified Data.Map   as Map
 import Data.Text            (pack)
@@ -30,6 +31,8 @@
 extensionMap =
     Map.fromList
            [ ("image/jpeg", ("jpg", JPEG))
+           , ("image/png",  ("png", PNG))
+           , ("image/gif",  ("gif", GIF))
            ]
 
 acceptedTypes :: [String]
@@ -57,7 +60,7 @@
                        template "Unsupported Type" () $
                            <%>
                             <h1>Unsupported Type</h1>
-                            <p>The file you uploaded appears to have the content type <b><% contentType %></b>. However, at this time the only supported types are <b><% acceptedTypes %></b>.</p>
+                            <p>The file you uploaded appears to have the content type <b><% contentType %></b>. However, at this time the only supported types are <b><% intercalate ", " acceptedTypes %></b>.</p>
                            </%>
                 (Just (ext, kind)) ->
                     do -- renameFile would be faster, but may not work if it has to cross physical devices
diff --git a/Clckwrks/Media/PreProcess.hs b/Clckwrks/Media/PreProcess.hs
--- a/Clckwrks/Media/PreProcess.hs
+++ b/Clckwrks/Media/PreProcess.hs
@@ -6,7 +6,7 @@
 import Clckwrks.Media.URL
 import Clckwrks.Media.Types (MediumId(..))
 import Clckwrks.Monad                   (transform, segments)
-import Data.Attoparsec.Text.Lazy        (Parser, Result(..), char, choice, decimal, parse, skipMany, space, stringCI, skipMany)
+import Data.Attoparsec.Text.Lazy        (Parser, Result(..), char, choice, decimal, parse, skipMany, space, asciiCI, skipMany)
 import           Data.Text (Text)
 import qualified Data.Text.Lazy         as TL
 import           Data.Text.Lazy.Builder (Builder)
@@ -20,7 +20,7 @@
 parseAttr :: Text -> Parser ()
 parseAttr name =
     do skipMany space
-       stringCI name
+       asciiCI name
        skipMany space
        char '='
        skipMany space
diff --git a/Clckwrks/Media/Preview.hs b/Clckwrks/Media/Preview.hs
--- a/Clckwrks/Media/Preview.hs
+++ b/Clckwrks/Media/Preview.hs
@@ -9,7 +9,7 @@
 import Clckwrks.Media.Acid (GetMediumById(..))
 import Clckwrks.Media.Types (Medium(..), MediumId(..), MediumKind(..), PreviewSize(..))
 
-import Graphics.GD (imageSize, loadJpegFile, resizeImage, saveJpegFile, withImage)
+import Graphics.GD (imageSize, loadGifFile, loadJpegFile, loadPngFile, resizeImage, saveJpegFile, savePngFile, withImage)
 import qualified Graphics.GD as GD
 import System.Directory (doesFileExist)
 import System.FilePath ((</>), splitExtension)
@@ -31,8 +31,44 @@
                     Venti  -> 400
       maxHeight = maxWidth
 
+pngThumbnail :: PreviewSize -> FilePath -> FilePath -> IO ()
+pngThumbnail size inPath outPath =
+    withImage (loadPngFile inPath) $ \image ->
+        do (w,h) <- imageSize image
+           let (w', h') =
+                 if w > h
+                 then (maxWidth, (h * maxWidth) `div` w)
+                 else ((w * maxHeight) `div` h, maxHeight)
+           image' <- resizeImage w' h' image
+           savePngFile outPath image'
+    where
+      maxWidth  = case size of
+                    Tall   -> 200
+                    Grande -> 300
+                    Venti  -> 400
+      maxHeight = maxWidth
+
+gifThumbnail :: PreviewSize -> FilePath -> FilePath -> IO ()
+gifThumbnail size inPath outPath =
+    withImage (loadGifFile inPath) $ \image ->
+        do (w,h) <- imageSize image
+           let (w', h') =
+                 if w > h
+                 then (maxWidth, (h * maxWidth) `div` w)
+                 else ((w * maxHeight) `div` h, maxHeight)
+           image' <- resizeImage w' h' image
+           savePngFile outPath image'
+    where
+      maxWidth  = case size of
+                    Tall   -> 200
+                    Grande -> 300
+                    Venti  -> 400
+      maxHeight = maxWidth
+
 mkThumbnail :: MediumKind -> PreviewSize -> FilePath -> FilePath -> IO ()
 mkThumbnail JPEG = jpgThumbnail
+mkThumbnail PNG  = pngThumbnail
+mkThumbnail GIF  = gifThumbnail
 
 applyTransforms :: FilePath -> FilePath -> (Medium, PreviewSize) -> IO FilePath
 applyTransforms storageDir cacheDir (medium, size) =
diff --git a/Clckwrks/Media/Types.hs b/Clckwrks/Media/Types.hs
--- a/Clckwrks/Media/Types.hs
+++ b/Clckwrks/Media/Types.hs
@@ -12,11 +12,15 @@
 
 data MediumKind
     = JPEG
+    | PNG
+    | GIF
       deriving (Eq, Ord, Read, Show, Data, Typeable)
 $(deriveSafeCopy 0 'base ''MediumKind)
 
 mediumContentType :: MediumKind -> String
 mediumContentType JPEG = "image/jpeg; charset=binary"
+mediumContentType PNG  = "image/png; charset=binary"
+mediumContentType GIF  = "image/gif; charset=binary"
 
 data Medium
     = Medium { mediumId     :: MediumId
diff --git a/clckwrks-plugin-media.cabal b/clckwrks-plugin-media.cabal
--- a/clckwrks-plugin-media.cabal
+++ b/clckwrks-plugin-media.cabal
@@ -1,5 +1,5 @@
 Name:                clckwrks-plugin-media
-Version:             0.5.1
+Version:             0.6.0
 Synopsis:            media plugin for clckwrks
 Homepage:            http://clckwrks.com/
 License:             BSD3
@@ -40,7 +40,7 @@
 
   Build-depends:
     base                    < 5,
-    acid-state             >= 0.7,
+    acid-state             >= 0.12 && < 0.13,
     attoparsec             == 0.10.*,
     blaze-html             >= 0.5 && < 0.7,
     clckwrks               >= 0.18 && < 0.20,
