diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for blizzard-html
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2021 Joshua Obritsch
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/blizzard-html.cabal b/blizzard-html.cabal
new file mode 100644
--- /dev/null
+++ b/blizzard-html.cabal
@@ -0,0 +1,33 @@
+cabal-version:      3.0
+
+author:             Joshua Obritsch
+bug-reports:        https://github.com/joshua-obritsch/blizzard-html/issues
+build-type:         Simple
+category:           Text
+copyright:          2021 Joshua Obritsch
+description:        An HTML and CSS renderer for the Haskell
+                    programming language. It functions mostly
+                    as a wrapper for blaze-html and clay. The
+                    syntax was inspired by Elm and elm-css.
+extra-source-files: CHANGELOG.md
+homepage:           https://github.com/joshua-obritsch/blizzard-html
+license:            MIT
+license-file:       LICENSE
+maintainer:         Joshua Obritsch <joshua@obritsch.com>
+name:               blizzard-html
+stability:          Experimental
+synopsis:           An HTML and CSS renderer for Haskell
+version:            0.1.0.0
+
+library
+    build-depends:      base       >= 4    && < 5
+                      , blaze-html >= 0.9  && < 0.10
+                      , clay       >= 0.13 && < 0.14
+                      , text       >= 0.10 && < 1.3
+    default-language:   Haskell2010
+    exposed-modules:    Text.Blizzard.Css3
+                      , Text.Blizzard.Html5
+                      , Text.Blizzard.Html5.Attributes
+    other-modules:      Text.Blizzard.Css
+                      , Text.Blizzard.Html
+    hs-source-dirs:     src
diff --git a/src/Text/Blizzard/Css.hs b/src/Text/Blizzard/Css.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Blizzard/Css.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Text.Blizzard.Css
+    ( css
+    ) where
+
+
+import Clay (Css, compact, renderWith)
+import Data.String (fromString)
+import Data.Text (unpack)
+import Data.Text.Lazy (toStrict)
+import Text.Blaze.Html5 (Attribute)
+import Text.Blaze.Html5.Attributes (style)
+
+
+css :: [Css] -> Attribute
+css []     = style ""
+css styles = style . fromString . firstLast . unpack . toStrict . renderWith compact [] . foldl1 (>>) $ styles
+
+firstLast :: [a] -> [a]
+firstLast []  = []
+firstLast [x] = []
+firstLast xs  = tail (init xs)
diff --git a/src/Text/Blizzard/Css3.hs b/src/Text/Blizzard/Css3.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Blizzard/Css3.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Text.Blizzard.Css3
+    ( module Clay.Background
+    , module Clay.Border
+    , module Clay.Box
+    , module Clay.Color
+    , module Clay.Common
+    , module Clay.Display
+    , module Clay.Dynamic
+    , module Clay.Flexbox
+    , module Clay.Font
+    , module Clay.FontFace
+    , module Clay.Geometry
+    , module Clay.Gradient
+    , module Clay.List
+    , module Clay.Size
+    , module Clay.Text
+    , module Clay.Time
+    , module Clay.Transform
+    , module Clay.Transition
+    , module Clay.Animation
+    , module Clay.Mask
+    , module Clay.Filter
+    ) where
+
+
+import Clay.Background
+import Clay.Border
+import Clay.Box
+import Clay.Color
+import Clay.Common
+import Clay.Display hiding (table)
+import Clay.Dynamic
+import Clay.Flexbox hiding (flex, nowrap, wrap)
+import Clay.Font hiding (menu, caption, small, icon)
+import Clay.FontFace
+import Clay.Geometry
+import Clay.Gradient
+import Clay.List
+import Clay.Size
+import Clay.Text hiding (pre)
+import Clay.Time
+import Clay.Transform
+import Clay.Transition
+import Clay.Animation
+import Clay.Mask hiding (clear)
+import Clay.Filter hiding (url, opacity)
diff --git a/src/Text/Blizzard/Html.hs b/src/Text/Blizzard/Html.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Blizzard/Html.hs
@@ -0,0 +1,21 @@
+module Text.Blizzard.Html
+    ( module Text.Blaze.Html
+    , documentTag
+    , normalTag
+    , voidTag
+    ) where
+
+
+import Text.Blaze.Html
+
+
+documentTag :: (Html -> Html) -> [Html] -> Html
+documentTag element []       = element $ toHtml ("" :: String)
+documentTag element children = element $ foldl1 (>>) children
+
+normalTag :: (Html -> Html) -> [Attribute] -> [Html] -> Html
+normalTag element attributes []       = foldl (!) element attributes $ toHtml ("" :: String)
+normalTag element attributes children = foldl (!) element attributes $ foldl1 (>>) children
+
+voidTag :: Html -> [Attribute] -> Html
+voidTag = foldl (!)
diff --git a/src/Text/Blizzard/Html5.hs b/src/Text/Blizzard/Html5.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Blizzard/Html5.hs
@@ -0,0 +1,452 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Text.Blizzard.Html5
+    ( module Text.Blaze.Html
+    , docType
+    , docTypeHtml
+    , a
+    , abbr
+    , address
+    , area
+    , article
+    , aside
+    , audio
+    , b
+    , base
+    , bdo
+    , blockquote
+    , body
+    , br
+    , button
+    , canvas
+    , caption
+    , cite
+    , code
+    , col
+    , colgroup
+    , command
+    , datalist
+    , dd
+    , del
+    , details
+    , dfn
+    , div
+    , dl
+    , dt
+    , em
+    , embed
+    , fieldset
+    , figcaption
+    , figure
+    , footer
+    , form
+    , h1
+    , h2
+    , h3
+    , h4
+    , h5
+    , h6
+    , head
+    , header
+    , hgroup
+    , hr
+    , html
+    , i
+    , iframe
+    , img
+    , input
+    , ins
+    , kbd
+    , keygen
+    , label
+    , legend
+    , li
+    , link
+    , main
+    , map
+    , mark
+    , menu
+    , menuitem
+    , meta
+    , meter
+    , nav
+    , noscript
+    , object
+    , ol
+    , optgroup
+    , option
+    , output
+    , p
+    , param
+    , pre
+    , progress
+    , q
+    , rp
+    , rt
+    , ruby
+    , samp
+    , script
+    , section
+    , select
+    , small
+    , source
+    , span
+    , strong
+    , style
+    , sub
+    , summary
+    , sup
+    , table
+    , tbody
+    , td
+    , textarea
+    , tfoot
+    , th
+    , thead
+    , time
+    , title
+    , tr
+    , track
+    , u
+    , ul
+    , var
+    , video
+    , wbr
+    ) where
+
+
+import Text.Blaze.Html
+import Text.Blizzard.Html
+
+import qualified Text.Blaze.Html5 as H
+
+
+docType :: Html
+docType = H.docType
+
+docTypeHtml :: [Html] -> Html
+docTypeHtml = documentTag H.docTypeHtml
+
+a :: [Attribute] -> [Html] -> Html
+a = normalTag H.a
+
+abbr :: [Attribute] -> [Html] -> Html
+abbr = normalTag H.abbr
+
+address :: [Attribute] -> [Html] -> Html
+address = normalTag H.address
+
+area :: [Attribute] -> Html
+area = voidTag H.area
+
+article :: [Attribute] -> [Html] -> Html
+article = normalTag H.article
+
+aside :: [Attribute] -> [Html] -> Html
+aside = normalTag H.aside
+
+audio :: [Attribute] -> [Html] -> Html
+audio = normalTag H.audio
+
+b :: [Attribute] -> [Html] -> Html
+b = normalTag H.b
+
+base :: [Attribute] -> Html
+base = voidTag H.base
+
+bdo :: [Attribute] -> [Html] -> Html
+bdo = normalTag H.bdo
+
+blockquote :: [Attribute] -> [Html] -> Html
+blockquote = normalTag H.blockquote
+
+body :: [Attribute] -> [Html] -> Html
+body = normalTag H.body
+
+br :: [Attribute] -> Html
+br = voidTag H.br
+
+button :: [Attribute] -> [Html] -> Html
+button = normalTag H.button
+
+canvas :: [Attribute] -> [Html] -> Html
+canvas = normalTag H.canvas
+
+caption :: [Attribute] -> [Html] -> Html
+caption = normalTag H.caption
+
+cite :: [Attribute] -> [Html] -> Html
+cite = normalTag H.cite
+
+code :: [Attribute] -> [Html] -> Html
+code = normalTag H.code
+
+col :: [Attribute] -> Html
+col = voidTag H.col
+
+colgroup :: [Attribute] -> [Html] -> Html
+colgroup = normalTag H.colgroup
+
+command :: [Attribute] -> [Html] -> Html
+command = normalTag H.command
+
+datalist :: [Attribute] -> [Html] -> Html
+datalist = normalTag H.datalist
+
+dd :: [Attribute] -> [Html] -> Html
+dd = normalTag H.dd
+
+del :: [Attribute] -> [Html] -> Html
+del = normalTag H.del
+
+details :: [Attribute] -> [Html] -> Html
+details = normalTag H.details
+
+dfn :: [Attribute] -> [Html] -> Html
+dfn = normalTag H.dfn
+
+div :: [Attribute] -> [Html] -> Html
+div = normalTag H.div
+
+dl :: [Attribute] -> [Html] -> Html
+dl = normalTag H.dl
+
+dt :: [Attribute] -> [Html] -> Html
+dt = normalTag H.dt
+
+em :: [Attribute] -> [Html] -> Html
+em = normalTag H.em
+
+embed :: [Attribute] -> Html
+embed = voidTag H.embed
+
+fieldset :: [Attribute] -> [Html] -> Html
+fieldset = normalTag H.fieldset
+
+figcaption :: [Attribute] -> [Html] -> Html
+figcaption = normalTag H.figcaption
+
+figure :: [Attribute] -> [Html] -> Html
+figure = normalTag H.figure
+
+footer :: [Attribute] -> [Html] -> Html
+footer = normalTag H.footer
+
+form :: [Attribute] -> [Html] -> Html
+form = normalTag H.form
+
+h1 :: [Attribute] -> [Html] -> Html
+h1 = normalTag H.h1
+
+h2 :: [Attribute] -> [Html] -> Html
+h2 = normalTag H.h2
+
+h3 :: [Attribute] -> [Html] -> Html
+h3 = normalTag H.h3
+
+h4 :: [Attribute] -> [Html] -> Html
+h4 = normalTag H.h4
+
+h5 :: [Attribute] -> [Html] -> Html
+h5 = normalTag H.h5
+
+h6 :: [Attribute] -> [Html] -> Html
+h6 = normalTag H.h6
+
+head :: [Attribute] -> [Html] -> Html
+head = normalTag H.head
+
+header :: [Attribute] -> [Html] -> Html
+header = normalTag H.header
+
+hgroup :: [Attribute] -> [Html] -> Html
+hgroup = normalTag H.hgroup
+
+hr :: [Attribute] -> Html
+hr = voidTag H.hr
+
+html :: [Attribute] -> [Html] -> Html
+html = normalTag H.html
+
+i :: [Attribute] -> [Html] -> Html
+i = normalTag H.i
+
+iframe :: [Attribute] -> [Html] -> Html
+iframe = normalTag H.iframe
+
+img :: [Attribute] -> Html
+img = voidTag H.img
+
+input :: [Attribute] -> Html
+input = voidTag H.input
+
+ins :: [Attribute] -> [Html] -> Html
+ins = normalTag H.ins
+
+kbd :: [Attribute] -> [Html] -> Html
+kbd = normalTag H.kbd
+
+keygen :: [Attribute] -> Html
+keygen = voidTag H.keygen
+
+label :: [Attribute] -> [Html] -> Html
+label = normalTag H.label
+
+legend :: [Attribute] -> [Html] -> Html
+legend = normalTag H.legend
+
+li :: [Attribute] -> [Html] -> Html
+li = normalTag H.li
+
+link :: [Attribute] -> Html
+link = voidTag H.link
+
+main :: [Attribute] -> [Html] -> Html
+main = normalTag H.main
+
+map :: [Attribute] -> [Html] -> Html
+map = normalTag H.map
+
+mark :: [Attribute] -> [Html] -> Html
+mark = normalTag H.mark
+
+menu :: [Attribute] -> [Html] -> Html
+menu = normalTag H.menu
+
+menuitem :: [Attribute] -> Html
+menuitem = voidTag H.menuitem
+
+meta :: [Attribute] -> Html
+meta = voidTag H.meta
+
+meter :: [Attribute] -> [Html] -> Html
+meter = normalTag H.meter
+
+nav :: [Attribute] -> [Html] -> Html
+nav = normalTag H.nav
+
+noscript :: [Attribute] -> [Html] -> Html
+noscript = normalTag H.noscript
+
+object :: [Attribute] -> [Html] -> Html
+object = normalTag H.object
+
+ol :: [Attribute] -> [Html] -> Html
+ol = normalTag H.ol
+
+optgroup :: [Attribute] -> [Html] -> Html
+optgroup = normalTag H.optgroup
+
+option :: [Attribute] -> [Html] -> Html
+option = normalTag H.option
+
+output :: [Attribute] -> [Html] -> Html
+output = normalTag H.output
+
+p :: [Attribute] -> [Html] -> Html
+p = normalTag H.p
+
+param :: [Attribute] -> Html
+param = voidTag H.param
+
+pre :: [Attribute] -> [Html] -> Html
+pre = normalTag H.pre
+
+progress :: [Attribute] -> [Html] -> Html
+progress = normalTag H.progress
+
+q :: [Attribute] -> [Html] -> Html
+q = normalTag H.q
+
+rp :: [Attribute] -> [Html] -> Html
+rp = normalTag H.rp
+
+rt :: [Attribute] -> [Html] -> Html
+rt = normalTag H.rt
+
+ruby :: [Attribute] -> [Html] -> Html
+ruby = normalTag H.ruby
+
+samp :: [Attribute] -> [Html] -> Html
+samp = normalTag H.samp
+
+script :: [Attribute] -> [Html] -> Html
+script = normalTag H.script
+
+section :: [Attribute] -> [Html] -> Html
+section = normalTag H.section
+
+select :: [Attribute] -> [Html] -> Html
+select = normalTag H.select
+
+small :: [Attribute] -> [Html] -> Html
+small = normalTag H.small
+
+source :: [Attribute] -> Html
+source = voidTag H.source
+
+span :: [Attribute] -> [Html] -> Html
+span = normalTag H.span
+
+strong :: [Attribute] -> [Html] -> Html
+strong = normalTag H.strong
+
+style :: [Attribute] -> [Html] -> Html
+style = normalTag H.style
+
+sub :: [Attribute] -> [Html] -> Html
+sub = normalTag H.sub
+
+summary :: [Attribute] -> [Html] -> Html
+summary = normalTag H.summary
+
+sup :: [Attribute] -> [Html] -> Html
+sup = normalTag H.sup
+
+table :: [Attribute] -> [Html] -> Html
+table = normalTag H.table
+
+tbody :: [Attribute] -> [Html] -> Html
+tbody = normalTag H.tbody
+
+td :: [Attribute] -> [Html] -> Html
+td = normalTag H.td
+
+textarea :: [Attribute] -> [Html] -> Html
+textarea = normalTag H.textarea
+
+tfoot :: [Attribute] -> [Html] -> Html
+tfoot = normalTag H.tfoot
+
+th :: [Attribute] -> [Html] -> Html
+th = normalTag H.th
+
+thead :: [Attribute] -> [Html] -> Html
+thead = normalTag H.thead
+
+time :: [Attribute] -> [Html] -> Html
+time = normalTag H.time
+
+title :: [Attribute] -> [Html] -> Html
+title = normalTag H.title
+
+tr :: [Attribute] -> [Html] -> Html
+tr = normalTag H.tr
+
+track :: [Attribute] -> Html
+track = voidTag H.track
+
+u :: [Attribute] -> [Html] -> Html
+u = normalTag H.u
+
+ul :: [Attribute] -> [Html] -> Html
+ul = normalTag H.ul
+
+var :: [Attribute] -> [Html] -> Html
+var = normalTag H.var
+
+video :: [Attribute] -> [Html] -> Html
+video = normalTag H.video
+
+wbr :: [Attribute] -> Html
+wbr = voidTag H.wbr
diff --git a/src/Text/Blizzard/Html5/Attributes.hs b/src/Text/Blizzard/Html5/Attributes.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Blizzard/Html5/Attributes.hs
@@ -0,0 +1,8 @@
+module Text.Blizzard.Html5.Attributes
+    ( module Text.Blaze.Html5.Attributes
+    , module Text.Blizzard.Css
+    ) where
+
+
+import Text.Blaze.Html5.Attributes
+import Text.Blizzard.Css
