diff --git a/Dockerfile b/Dockerfile
index c53616677df17d0321b1f84719917a86fa20f67e..4f0d43a4d3d3dc6f6ea2f1bf4fa241df3babf5d1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,6 +13,11 @@ RUN apk add --update ca-certificates openssl
 
 COPY _output/bin/dex /usr/local/bin/dex
 
+# Import frontend assets and set the correct CWD directory so the assets
+# are in the default path.
+COPY web /web
+WORKDIR /
+
 ENTRYPOINT ["dex"]
 
 CMD ["version"]
diff --git a/Makefile b/Makefile
index 62ab589529a283b8298ea3a536d0dd0de8e90761..5aa8144e0fd57e53b2be1ae4a69b26e7c41d0755 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ LD_FLAGS="-w -X $(REPO_PATH)/version.Version=$(VERSION)"
 
 build: bin/dex bin/example-app
 
-bin/dex: FORCE generated
+bin/dex: FORCE
 	@go install -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/dex
 
 bin/example-app: FORCE
@@ -35,9 +35,6 @@ bin/example-app: FORCE
 release-binary:
 	@go build -o _output/bin/dex -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/dex
 
-.PHONY: generated
-generated: server/templates_default.go
-
 test:
 	@go test -v -i $(shell go list ./... | grep -v '/vendor/')
 	@go test -v $(shell go list ./... | grep -v '/vendor/')
@@ -57,9 +54,6 @@ lint:
       golint -set_exit_status $$package $$i || exit 1; \
 	done
 
-server/templates_default.go: $(wildcard web/templates/**)
-	@go run server/templates_default_gen.go
-
 _output/bin/dex:
 	# Using rkt to build the dex binary.
 	@./scripts/rkt-build
diff --git a/cmd/dex/config.go b/cmd/dex/config.go
index 2ee9e58ae2480e4516ea97295bf108b3eab636c7..dc3715b8f3ca3a2c4db48049845a404af201036a 100644
--- a/cmd/dex/config.go
+++ b/cmd/dex/config.go
@@ -30,7 +30,7 @@ type Config struct {
 	GRPC       GRPC        `json:"grpc"`
 	Expiry     Expiry      `json:"expiry"`
 
-	Templates server.TemplateConfig `json:"templates"`
+	Frontend server.WebConfig `json:"frontend"`
 
 	// StaticClients cause the server to use this list of clients rather than
 	// querying the storage. Write operations, like creating a client, will fail.
diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go
index e218e4732c90b6ff8c801aa2b71a00818e73aed7..c9baa9d38ce6a0de4ad05812c3404c6eb103c3e1 100644
--- a/cmd/dex/serve.go
+++ b/cmd/dex/serve.go
@@ -151,7 +151,7 @@ func serve(cmd *cobra.Command, args []string) error {
 		Issuer:                 c.Issuer,
 		Connectors:             connectors,
 		Storage:                s,
-		TemplateConfig:         c.Templates,
+		Web:                    c.Frontend,
 		EnablePasswordDB:       c.EnablePasswordDB,
 	}
 	if c.Expiry.SigningKeys != "" {
diff --git a/examples/config-dev.yaml b/examples/config-dev.yaml
index 5f94e2023709753bbf3b98564d1b1b664e6d6390..1b5a48d3f15cf0eb498548b6ea32e0fd2561187b 100644
--- a/examples/config-dev.yaml
+++ b/examples/config-dev.yaml
@@ -14,7 +14,7 @@ storage:
 
 # Configuration for the HTTP endpoints.
 web:
-  http: 127.0.0.1:5556
+  http: 0.0.0.0:5556
   # Uncomment for HTTPS options.
   # https: 127.0.0.1:5554
   # tlsCert: /etc/dex/tls.crt
diff --git a/server/server.go b/server/server.go
index b8d2c8d395d9295163bfb1d3a2616e79a19f9621..91d119e9fda8b06189eee939bbf3f3265bf9e911 100644
--- a/server/server.go
+++ b/server/server.go
@@ -56,7 +56,32 @@ type Config struct {
 
 	EnablePasswordDB bool
 
-	TemplateConfig TemplateConfig
+	Web WebConfig
+}
+
+// WebConfig holds the server's frontend templates and asset configuration.
+//
+// These are currently very custom to CoreOS and it's not recommended that
+// outside users attempt to customize these.
+type WebConfig struct {
+	// A filepath to web static.
+	//
+	// It is expected to contain the following directories:
+	//
+	//   * static - Static static served at "( issuer URL )/static".
+	//   * templates - HTML templates controlled by dex.
+	//   * themes/(theme) - Static static served at "( issuer URL )/theme".
+	//
+	Dir string
+
+	// Defaults to "( issuer URL )/theme/logo.png"
+	LogoURL string
+
+	// Defaults to "dex"
+	Issuer string
+
+	// Defaults to "coreos"
+	Theme string
 }
 
 func value(val, defaultValue time.Duration) time.Duration {
@@ -130,9 +155,17 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
 		supported[respType] = true
 	}
 
-	tmpls, err := loadTemplates(c.TemplateConfig)
+	web := webConfig{
+		dir:       c.Web.Dir,
+		logoURL:   c.Web.LogoURL,
+		issuerURL: c.Issuer,
+		issuer:    c.Web.Issuer,
+		theme:     c.Web.Theme,
+	}
+
+	static, theme, tmpls, err := loadWebConfig(web)
 	if err != nil {
-		return nil, fmt.Errorf("server: failed to load templates: %v", err)
+		return nil, fmt.Errorf("server: failed to load web static: %v", err)
 	}
 
 	now := c.Now
@@ -159,6 +192,10 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
 	handleFunc := func(p string, h http.HandlerFunc) {
 		r.HandleFunc(path.Join(issuerURL.Path, p), h)
 	}
+	handlePrefix := func(p string, h http.Handler) {
+		prefix := path.Join(issuerURL.Path, p)
+		r.PathPrefix(prefix).Handler(http.StripPrefix(prefix, h))
+	}
 	r.NotFoundHandler = http.HandlerFunc(s.notFound)
 
 	discoveryHandler, err := s.discoveryHandler()
@@ -175,6 +212,8 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
 	handleFunc("/callback", s.handleConnectorCallback)
 	handleFunc("/approval", s.handleApproval)
 	handleFunc("/healthz", s.handleHealth)
+	handlePrefix("/static", static)
+	handlePrefix("/theme", theme)
 	s.mux = r
 
 	startKeyRotation(ctx, c.Storage, rotationStrategy, now)
diff --git a/server/server_test.go b/server/server_test.go
index a5865dfa33e1a7b3828222e7edc3b580d5cda65e..3ab41940826a8352990a9ee418959f31a02cc87f 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -11,6 +11,8 @@ import (
 	"net/http/httptest"
 	"net/http/httputil"
 	"net/url"
+	"os"
+	"path/filepath"
 	"reflect"
 	"sort"
 	"strings"
@@ -85,6 +87,9 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi
 				Connector:   mock.NewCallbackConnector(),
 			},
 		},
+		Web: WebConfig{
+			Dir: filepath.Join(os.Getenv("GOPATH"), "src/github.com/coreos/dex/web"),
+		},
 	}
 	if updateConfig != nil {
 		updateConfig(&config)
diff --git a/server/templates.go b/server/templates.go
index e8285fe31e26b579b076cc430289ec8fe1f2b10b..649d5b0837e3a4ab15da1f1f253078846bf6f2de 100644
--- a/server/templates.go
+++ b/server/templates.go
@@ -6,8 +6,10 @@ import (
 	"io/ioutil"
 	"log"
 	"net/http"
+	"os"
 	"path/filepath"
 	"sort"
+	"strings"
 	"text/template"
 )
 
@@ -18,8 +20,6 @@ const (
 	tmplOOB      = "oob.html"
 )
 
-const coreOSLogoURL = "https://coreos.com/assets/images/brand/coreos-wordmark-135x40px.png"
-
 var requiredTmpls = []string{
 	tmplApproval,
 	tmplLogin,
@@ -27,65 +27,122 @@ var requiredTmpls = []string{
 	tmplOOB,
 }
 
-// TemplateConfig describes.
-type TemplateConfig struct {
-	// TODO(ericchiang): Asking for a directory with a set of templates doesn't indicate
-	// what the templates should look like and doesn't allow consumers of this package to
-	// provide their own templates in memory. In the future clean this up.
-
-	// Directory of the templates. If empty, these will be loaded from memory.
-	Dir string `yaml:"dir"`
+type templates struct {
+	loginTmpl    *template.Template
+	approvalTmpl *template.Template
+	passwordTmpl *template.Template
+	oobTmpl      *template.Template
+}
 
-	// Defaults to the CoreOS logo and "dex".
-	LogoURL string `yaml:"logoURL"`
-	Issuer  string `yaml:"issuerName"`
+type webConfig struct {
+	dir       string
+	logoURL   string
+	issuer    string
+	theme     string
+	issuerURL string
 }
 
-type globalData struct {
-	LogoURL string
-	Issuer  string
+func join(base, path string) string {
+	b := strings.HasSuffix(base, "/")
+	p := strings.HasPrefix(path, "/")
+	switch {
+	case b && p:
+		return base + path[1:]
+	case b || p:
+		return base + path
+	default:
+		return base + "/" + path
+	}
 }
 
-func loadTemplates(config TemplateConfig) (*templates, error) {
-	var tmpls *template.Template
-	if config.Dir != "" {
-		files, err := ioutil.ReadDir(config.Dir)
-		if err != nil {
-			return nil, fmt.Errorf("read dir: %v", err)
+func dirExists(dir string) error {
+	stat, err := os.Stat(dir)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return fmt.Errorf("directory %q does not exist", dir)
 		}
-		filenames := []string{}
-		for _, file := range files {
-			if file.IsDir() {
-				continue
-			}
-			filenames = append(filenames, filepath.Join(config.Dir, file.Name()))
-		}
-		if len(filenames) == 0 {
-			return nil, fmt.Errorf("no files in template dir %s", config.Dir)
-		}
-		if tmpls, err = template.ParseFiles(filenames...); err != nil {
-			return nil, fmt.Errorf("parse files: %v", err)
+		return fmt.Errorf("stat directory %q: %v", dir, err)
+	}
+	if !stat.IsDir() {
+		return fmt.Errorf("path %q is a file not a directory", dir)
+	}
+	return nil
+}
+
+// loadWebConfig returns static assets, theme assets, and templates used by the frontend by
+// reading the directory specified in the webConfig.
+//
+// The directory layout is expected to be:
+//
+//    ( web directory )
+//    |- static
+//    |- themes
+//    |  |- (theme name)
+//    |- templates
+//
+func loadWebConfig(c webConfig) (static, theme http.Handler, templates *templates, err error) {
+	if c.theme == "" {
+		c.theme = "coreos"
+	}
+	if c.issuer == "" {
+		c.issuer = "dex"
+	}
+	if c.dir == "" {
+		c.dir = "./web"
+	}
+	if c.logoURL == "" {
+		c.logoURL = join(c.issuerURL, "theme/logo.png")
+	}
+
+	if err := dirExists(c.dir); err != nil {
+		return nil, nil, nil, fmt.Errorf("load web dir: %v", err)
+	}
+
+	staticDir := filepath.Join(c.dir, "static")
+	templatesDir := filepath.Join(c.dir, "templates")
+	themeDir := filepath.Join(c.dir, "themes", c.theme)
+
+	for _, dir := range []string{staticDir, templatesDir, themeDir} {
+		if err := dirExists(dir); err != nil {
+			return nil, nil, nil, fmt.Errorf("load dir: %v", err)
 		}
-	} else {
-		// Load templates from memory. This code is largely copied from the standard library's
-		// ParseFiles source code.
-		// See: https://goo.gl/6Wm4mN
-		for name, data := range defaultTemplates {
-			var t *template.Template
-			if tmpls == nil {
-				tmpls = template.New(name)
-			}
-			if name == tmpls.Name() {
-				t = tmpls
-			} else {
-				t = tmpls.New(name)
-			}
-			if _, err := t.Parse(data); err != nil {
-				return nil, fmt.Errorf("parsing %s: %v", name, err)
-			}
+	}
+
+	static = http.FileServer(http.Dir(staticDir))
+	theme = http.FileServer(http.Dir(themeDir))
+
+	templates, err = loadTemplates(c, templatesDir)
+	return
+}
+
+// loadTemplates parses the expected templates from the provided directory.
+func loadTemplates(c webConfig, templatesDir string) (*templates, error) {
+	files, err := ioutil.ReadDir(templatesDir)
+	if err != nil {
+		return nil, fmt.Errorf("read dir: %v", err)
+	}
+
+	filenames := []string{}
+	for _, file := range files {
+		if file.IsDir() {
+			continue
 		}
+		filenames = append(filenames, filepath.Join(templatesDir, file.Name()))
+	}
+	if len(filenames) == 0 {
+		return nil, fmt.Errorf("no files in template dir %q", templatesDir)
 	}
 
+	funcs := map[string]interface{}{
+		"issuer": func() string { return c.issuer },
+		"logo":   func() string { return c.logoURL },
+		"url":    func(s string) string { return join(c.issuerURL, s) },
+	}
+
+	tmpls, err := template.New("").Funcs(funcs).ParseFiles(filenames...)
+	if err != nil {
+		return nil, fmt.Errorf("parse files: %v", err)
+	}
 	missingTmpls := []string{}
 	for _, tmplName := range requiredTmpls {
 		if tmpls.Lookup(tmplName) == nil {
@@ -95,16 +152,7 @@ func loadTemplates(config TemplateConfig) (*templates, error) {
 	if len(missingTmpls) > 0 {
 		return nil, fmt.Errorf("missing template(s): %s", missingTmpls)
 	}
-
-	if config.LogoURL == "" {
-		config.LogoURL = coreOSLogoURL
-	}
-	if config.Issuer == "" {
-		config.Issuer = "dex"
-	}
-
 	return &templates{
-		globalData:   config,
 		loginTmpl:    tmpls.Lookup(tmplLogin),
 		approvalTmpl: tmpls.Lookup(tmplApproval),
 		passwordTmpl: tmpls.Lookup(tmplPassword),
@@ -118,14 +166,6 @@ var scopeDescriptions = map[string]string{
 	"email":          "View your email",
 }
 
-type templates struct {
-	globalData   TemplateConfig
-	loginTmpl    *template.Template
-	approvalTmpl *template.Template
-	passwordTmpl *template.Template
-	oobTmpl      *template.Template
-}
-
 type connectorInfo struct {
 	ID   string
 	Name string
@@ -142,21 +182,19 @@ func (t *templates) login(w http.ResponseWriter, connectors []connectorInfo, aut
 	sort.Sort(byName(connectors))
 
 	data := struct {
-		TemplateConfig
 		Connectors []connectorInfo
 		AuthReqID  string
-	}{t.globalData, connectors, authReqID}
+	}{connectors, authReqID}
 	renderTemplate(w, t.loginTmpl, data)
 }
 
 func (t *templates) password(w http.ResponseWriter, authReqID, callback, lastUsername string, lastWasInvalid bool) {
 	data := struct {
-		TemplateConfig
 		AuthReqID string
 		PostURL   string
 		Username  string
 		Invalid   bool
-	}{t.globalData, authReqID, callback, lastUsername, lastWasInvalid}
+	}{authReqID, string(callback), lastUsername, lastWasInvalid}
 	renderTemplate(w, t.passwordTmpl, data)
 }
 
@@ -170,20 +208,18 @@ func (t *templates) approval(w http.ResponseWriter, authReqID, username, clientN
 	}
 	sort.Strings(accesses)
 	data := struct {
-		TemplateConfig
 		User      string
 		Client    string
 		AuthReqID string
 		Scopes    []string
-	}{t.globalData, username, clientName, authReqID, accesses}
+	}{username, clientName, authReqID, accesses}
 	renderTemplate(w, t.approvalTmpl, data)
 }
 
 func (t *templates) oob(w http.ResponseWriter, code string) {
 	data := struct {
-		TemplateConfig
 		Code string
-	}{t.globalData, code}
+	}{code}
 	renderTemplate(w, t.oobTmpl, data)
 }
 
diff --git a/server/templates_default.go b/server/templates_default.go
deleted file mode 100644
index 651c7411b8c9eaa9a7f26fae82aa59533ad31427..0000000000000000000000000000000000000000
--- a/server/templates_default.go
+++ /dev/null
@@ -1,362 +0,0 @@
-// This file was generated by the makefile. Do not edit.
-
-package server
-
-// defaultTemplates is a key for file name to file data of the files in web/templates.
-var defaultTemplates = map[string]string{
-	"approval.html": `{{ template "header.html" . }}
-
-<div class="panel">
-  <h2 class="heading">Grant Access</h2>
-
-  <hr>
-  <div class="list-with-title">
-    <div class="subtle-text">{{ .Client }} would like to:</div>
-      {{ range $scope := .Scopes }}
-      <li class="bullet-point">
-        <div class="subtle-text">
-          {{ $scope }}
-        </div>
-      </li>
-      {{ end }}
-  </div>
-  <hr>
-
-  <div>
-    <div class="form-row">
-      <form method="post">
-        <input type="hidden" name="req" value="{{ .AuthReqID }}"/>
-        <input type="hidden" name="approval" value="approve">
-        <button type="submit" class="btn btn-success">
-            <span class="btn-text">Grant Access</span>
-        </button>
-      </form>
-    </div>
-    <div class="form-row">
-      <form method="post">
-        <input type="hidden" name="req" value="{{ .AuthReqID }}"/>
-        <input type="hidden" name="approval" value="rejected">
-        <button type="submit" class="btn btn-provider">
-            <span class="btn-text">Cancel</span>
-        </button>
-      </form>
-    </div>
-  </div>
-
-</div>
-
-{{ template "footer.html" . }}
-`,
-	"footer.html": `    </div>
-  </body>
-</html>
-`,
-	"header.html": `<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <title>{{ .Issuer }}</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <style>
-      * {
-        -webkit-box-sizing: border-box;
-           -moz-box-sizing: border-box;
-                box-sizing: border-box;
-      }
-
-      html,
-      body {
-        margin: 0;
-        background-color: #efefef;
-        font-family: 'Source Sans Pro', Helvetica, sans-serif;
-        color: #333;
-      }
-      a {
-        color: #428BCA;
-        text-decoration: none;
-      }
-      a:active, a:hover, a:visited {
-        color: #2A6596;
-        text-decoration: underline;
-      }
-      #navbar {
-        background-color: #fff;
-        color: #333;
-        height: 46px;
-        box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
-        font-size: 13px;
-        font-weight: 100;
-        overflow: hidden;
-        padding: 0 10px;
-      }
-      #navbar-logo-wrap {
-        width: 300px;
-        height: 100%;
-        display: inline-block;
-        overflow: hidden;
-        padding: 10px 15px;
-      }
-      #navbar-logo {
-        height: 100%;
-        max-height: 25px;
-      }
-      #container {
-        margin: 45px auto;
-        text-align: center;
-        max-width: 500px;
-        min-width: 320px;
-      }
-      .heading {
-        font-size: 20px;
-        font-weight: 500;
-        margin-top: 0;
-        margin-bottom: 10px;
-      }
-      .footer {
-        margin: 30px;
-      }
-      .input-label-right {
-        position: absolute;
-        right: 0;
-        bottom: 0;
-      }
-      .input-desc {
-        width: 250px;
-        margin: 4px auto;
-        text-align: left;
-        position: relative;
-      }
-      .subtle-text {
-        color: #999;
-        font-size: 12px;
-      }
-      .panel {
-        background-color: #fff;
-        padding: 30px;
-        box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
-      }
-      .explain {
-        font-size: 13px;
-        color: #666;
-      }
-
-      .btn {
-        box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.25), 0 0px 1px rgba(0, 0, 0, 0.25);
-        padding: 0;
-        font-size: 14px;
-        border-radius: 4px;
-        border: none;
-        cursor: pointer;
-        font-size: 16px;
-      }
-      .btn:focus {
-        outline: none;
-      }
-      .btn:active {
-        outline: none;
-        box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-      }
-      .btn-primary {
-        color: #fff;
-        background-color: #333;
-        padding: 6px 12px;
-        min-width: 200px;
-        border: none;
-      }
-      .btn-primary:hover {
-        background-color: #666;
-        color: #fff;
-      }
-      .btn-provider {
-        background-color: #fff;
-        color: #333;
-        width: 250px;
-      }
-      .btn-provider:hover {
-        color: #999;
-      }
-      .btn-success {
-        background-color: #2FC98E;
-        color: #fff;
-        width: 250px;
-      }
-      .btn-success:hover {
-        background-color: #49E3A8;
-      }
-      .btn-icon {
-        width: 36px;
-        height: 36px;
-        float: left;
-        margin-right: 5px;
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: 24px;
-      }
-      .btn-icon-google {
-        background-color: #DB4437;
-        background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjM2cHgiIGhlaWdodD0iMzdweCIgdmlld0JveD0iMCAwIDM2IDM3IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggMy4zLjIgKDEyMDQzKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5TaGFwZSArIGcrPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSIzLjg0OTMxNTA3JSIgeTE9IjM0LjQ3MzI2MiUiIHgyPSI5Mi4yODU0Nzk1JSIgeTI9IjcwLjIyMzI2MiUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNFMjcyMyIgc3RvcC1vcGFjaXR5PSIwLjIiIG9mZnNldD0iMCUiPjwvc3RvcD4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNFMjcyMyIgc3RvcC1vcGFjaXR5PSIwLjAyIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+CiAgICAgICAgPGcgaWQ9IkEuMS1WZXJpZnktRW1haWwtU2NyZWVuX2xvZ2luLSIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQwNy4wMDAwMDAsIC0yNzIuMDAwMDAwKSI+CiAgICAgICAgICAgIDxnIGlkPSJTaGFwZS0rLWcrIiBza2V0Y2g6dHlwZT0iTVNMYXllckdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MDcuMDAwMDAwLCAyNzIuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMzUuOTYzOTg4MSwxNS4zMjM2OTA1IEwxOC43OTIzMjE0LDAuNzUyMDIzODEgTDEwLjc1Nzk3NjIsMC43NTIwMjM4MSBDNS4xNDQ5NDA0OCwwLjc1MjAyMzgxIDIuMzkzNDUyMzgsNC4xNjM4NjkwNSAyLjM5MzQ1MjM4LDguMDE1OTUyMzggQzIuMzkzNDUyMzgsMTAuOTg3NTU5NSA0LjgxNDc2MTksMTQuMjg5MzQ1MiA4Ljg4Njk2NDI5LDE0LjI4OTM0NTIgTDkuODc3NSwxNC4yODkzNDUyIEM5LjY1NzM4MDk1LDE0LjYxOTUyMzggOS41NDczMjE0MywxNS4yNzk4ODEgOS41NDczMjE0MywxNS43MjAxMTkgQzkuNTQ3MzIxNDMsMTYuODIwNzE0MyA5Ljk4NzU1OTUyLDE3LjM3MTAxMTkgMTAuNjQ3OTE2NywxOC4wMzEzNjkgQzguODg2OTY0MjksMTguMTQxNDI4NiA1LjU4NTE3ODU3LDE4LjQ3MTYwNzEgMy4xNjM4NjkwNSwyMC4wMTI0NDA1IEMwLjg1MjYxOTA0OCwyMS4zMzMxNTQ4IDAuMTkyMjYxOTA1LDIzLjMxNDIyNjIgMC4xOTIyNjE5MDUsMjQuNzQ1IEMwLjE5MjI2MTkwNSwyNS45NTU2NTQ4IDAuNjMyNSwyNy4wNTYyNSAxLjYyMzAzNTcxLDI4LjA0Njc4NTcgTDE1LjQ5MDUzNTcsMzYuOTE0Mjg1NyBMMzUuOTYzOTg4MSwzNi45MTQyODU3IEwzNS45NjM5ODgxLDE1LjMyMzY5MDUgWiIgaWQ9IlNoYXBlIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8ZyBpZD0iZysiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMTkyMjYyLCAxLjE5MjI2MikiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xOC42MDAwNTk1LC0wLjExMDA1OTUyNCBMMTguNjAwMDU5NSwtMC40NDAyMzgwOTUgTDEwLjU2NTcxNDMsLTAuMTEwMDU5NTI0IEM0Ljk1MjY3ODU3LC0wLjExMDA1OTUyNCAyLjIwMTE5MDQ4LDMuMzAxNzg1NzEgMi4yMDExOTA0OCw3LjE1Mzg2OTA1IEMyLjIwMTE5MDQ4LDEwLjEyNTQ3NjIgNC42MjI1LDEzLjQyNzI2MTkgOC42OTQ3MDIzOCwxMy40MjcyNjE5IEw5LjY4NTIzODEsMTMuNDI3MjYxOSBDOS40NjUxMTkwNSwxMy43NTc0NDA1IDkuMzU1MDU5NTIsMTQuNDE3Nzk3NiA5LjM1NTA1OTUyLDE0Ljk2ODA5NTIgQzkuMzU1MDU5NTIsMTYuMDY4NjkwNSA5Ljc5NTI5NzYyLDE2LjYxODk4ODEgMTAuNDU1NjU0OCwxNy4yNzkzNDUyIEM4LjY5NDcwMjM4LDE3LjM4OTQwNDggNS4zOTI5MTY2NywxNy43MTk1ODMzIDIuOTcxNjA3MTQsMTkuMjYwNDE2NyBDMC42NjAzNTcxNDMsMjAuNTgxMTMxIDAsMjIuNTYyMjAyNCAwLDIzLjk5Mjk3NjIgQzAsMjYuODU0NTIzOCAyLjc1MTQ4ODEsMjkuNDk1OTUyNCA4LjM2NDUyMzgxLDI5LjQ5NTk1MjQgQzE1LjA3ODE1NDgsMjkuNDk1OTUyNCAxOC42MDAwNTk1LDI1Ljg2Mzk4ODEgMTguNjAwMDU5NSwyMi4yMzIwMjM4IEMxOC42MDAwNTk1LDE5LjQ4MDUzNTcgMTcuMDU5MjI2MiwxOC4xNTk4MjE0IDE1LjI5ODI3MzgsMTYuNzI5MDQ3NiBMMTMuODY3NSwxNS42Mjg0NTI0IEMxMy40MjcyNjE5LDE1LjI5ODI3MzggMTIuOTg3MDIzOCwxNC44NTgwMzU3IDEyLjk4NzAyMzgsMTMuOTc3NTU5NSBDMTIuOTg3MDIzOCwxMy4wOTcwODMzIDEzLjUzNzMyMTQsMTIuNDM2NzI2MiAxNC4wODc2MTksMTIuMTA2NTQ3NiBDMTUuNzM4NTExOSwxMC43ODU4MzMzIDE3LjM4OTQwNDgsOS40NjUxMTkwNSAxNy4zODk0MDQ4LDYuNDkzNTExOSBDMTcuMzg5NDA0OCwzLjc0MjAyMzgxIDE1LjczODUxMTksMi4zMTEyNSAxNC43NDc5NzYyLDEuNTQwODMzMzMgTDE2Ljk0OTE2NjcsMS41NDA4MzMzMyBMMTguNjAwMDU5NSwtMC4xMTAwNTk1MjQgTDE4LjYwMDA1OTUsLTAuMTEwMDU5NTI0IFogTTE2LjA2ODY5MDUsMjMuNjYyNzk3NiBDMTYuMDY4NjkwNSwyNS44NjM5ODgxIDE0LjA4NzYxOSwyNy44NDUwNTk1IDEwLjM0NTU5NTIsMjcuODQ1MDU5NSBDNi4xNjMzMzMzMywyNy44NDUwNTk1IDMuNTIxOTA0NzYsMjUuNzUzOTI4NiAzLjUyMTkwNDc2LDIzLjExMjUgQzMuNTIxOTA0NzYsMjAuMzYxMDExOSA2LjA1MzI3MzgxLDE5LjM3MDQ3NjIgNi44MjM2OTA0OCwxOS4wNDAyOTc2IEM4LjQ3NDU4MzMzLDE4LjQ5IDEwLjU2NTcxNDMsMTguMzc5OTQwNSAxMC44OTU4OTI5LDE4LjM3OTk0MDUgTDExLjc3NjM2OSwxOC4zNzk5NDA1IEMxNC43NDc5NzYyLDIwLjU4MTEzMSAxNi4wNjg2OTA1LDIxLjY4MTcyNjIgMTYuMDY4NjkwNSwyMy42NjI3OTc2IEwxNi4wNjg2OTA1LDIzLjY2Mjc5NzYgWiBNMTAuNTY1NzE0MywxMi4xMDY1NDc2IEM3LjI2MzkyODU3LDEyLjEwNjU0NzYgNS41MDI5NzYxOSw4LjI1NDQ2NDI5IDUuNTAyOTc2MTksNS4yODI4NTcxNCBDNS41MDI5NzYxOSwyLjUzMTM2OTA1IDcuMjYzOTI4NTcsMS4yMTA2NTQ3NiA5LjEzNDk0MDQ4LDEuMjEwNjU0NzYgQzEyLjY1Njg0NTIsMS4yMTA2NTQ3NiAxNC40MTc3OTc2LDUuNjEzMDM1NzEgMTQuNDE3Nzk3Niw4LjI1NDQ2NDI5IEMxNC4zMDc3MzgxLDExLjQ0NjE5MDUgMTEuNTU2MjUsMTIuMTA2NTQ3NiAxMC41NjU3MTQzLDEyLjEwNjU0NzYgTDEwLjU2NTcxNDMsMTIuMTA2NTQ3NiBaIE0yNi40MTQyODU3LDEyLjk4NzAyMzggTDI2LjQxNDI4NTcsOC4wMzQzNDUyNCBMMjQuNzYzMzkyOSw4LjAzNDM0NTI0IEwyNC43NjMzOTI5LDEyLjk4NzAyMzggTDE5LjgxMDcxNDMsMTIuOTg3MDIzOCBMMTkuODEwNzE0MywxNC42Mzc5MTY3IEwyNC43NjMzOTI5LDE0LjYzNzkxNjcgTDI0Ljc2MzM5MjksMTkuNTkwNTk1MiBMMjYuNDE0Mjg1NywxOS41OTA1OTUyIEwyNi40MTQyODU3LDE0LjYzNzkxNjcgTDMxLjM2Njk2NDMsMTQuNjM3OTE2NyBMMzEuMzY2OTY0MywxMi45ODcwMjM4IEwyNi40MTQyODU3LDEyLjk4NzAyMzggTDI2LjQxNDI4NTcsMTIuOTg3MDIzOCBaIiBpZD0iU2hhcGUiIG9wYWNpdHk9IjAuMTYiIGZpbGw9IiMzRTI3MjMiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTguNjAwMDU5NSwtMC40NDAyMzgwOTUgTDEwLjU2NTcxNDMsLTAuNDQwMjM4MDk1IEM0Ljk1MjY3ODU3LC0wLjQ0MDIzODA5NSAyLjIwMTE5MDQ4LDIuOTcxNjA3MTQgMi4yMDExOTA0OCw2LjgyMzY5MDQ4IEMyLjIwMTE5MDQ4LDkuNzk1Mjk3NjIgNC42MjI1LDEzLjA5NzA4MzMgOC42OTQ3MDIzOCwxMy4wOTcwODMzIEw5LjY4NTIzODEsMTMuMDk3MDgzMyBDOS40NjUxMTkwNSwxMy40MjcyNjE5IDkuMzU1MDU5NTIsMTQuMDg3NjE5IDkuMzU1MDU5NTIsMTQuNTI3ODU3MSBDOS4zNTUwNTk1MiwxNS42Mjg0NTI0IDkuNzk1Mjk3NjIsMTYuMTc4NzUgMTAuNDU1NjU0OCwxNi44MzkxMDcxIEM4LjY5NDcwMjM4LDE2Ljk0OTE2NjcgNS4zOTI5MTY2NywxNy4yNzkzNDUyIDIuOTcxNjA3MTQsMTguODIwMTc4NiBDMC42NjAzNTcxNDMsMjAuMTQwODkyOSAwLDIyLjEyMTk2NDMgMCwyMy41NTI3MzgxIEMwLDI2LjQxNDI4NTcgMi43NTE0ODgxLDI5LjA1NTcxNDMgOC4zNjQ1MjM4MSwyOS4wNTU3MTQzIEMxNS4wNzgxNTQ4LDI5LjA1NTcxNDMgMTguNjAwMDU5NSwyNS40MjM3NSAxOC42MDAwNTk1LDIxLjc5MTc4NTcgQzE4LjYwMDA1OTUsMTkuMDQwMjk3NiAxNy4wNTkyMjYyLDE3LjcxOTU4MzMgMTUuMjk4MjczOCwxNi4yODg4MDk1IEwxMy44Njc1LDE1LjE4ODIxNDMgQzEzLjQyNzI2MTksMTQuODU4MDM1NyAxMi45ODcwMjM4LDE0LjQxNzc5NzYgMTIuOTg3MDIzOCwxMy41MzczMjE0IEMxMi45ODcwMjM4LDEyLjY1Njg0NTIgMTMuNTM3MzIxNCwxMS45OTY0ODgxIDE0LjA4NzYxOSwxMS42NjYzMDk1IEMxNS43Mzg1MTE5LDEwLjM0NTU5NTIgMTcuMzg5NDA0OCw5LjAyNDg4MDk1IDE3LjM4OTQwNDgsNi4wNTMyNzM4MSBDMTcuMzg5NDA0OCwzLjMwMTc4NTcxIDE1LjczODUxMTksMS44NzEwMTE5IDE0Ljc0Nzk3NjIsMS4xMDA1OTUyNCBMMTYuOTQ5MTY2NywxLjEwMDU5NTI0IEwxOC42MDAwNTk1LC0wLjQ0MDIzODA5NSBMMTguNjAwMDU5NSwtMC40NDAyMzgwOTUgWiBNMTYuMDY4NjkwNSwyMy4zMzI2MTkgQzE2LjA2ODY5MDUsMjUuNTMzODA5NSAxNC4wODc2MTksMjcuNTE0ODgxIDEwLjM0NTU5NTIsMjcuNTE0ODgxIEM2LjE2MzMzMzMzLDI3LjUxNDg4MSAzLjUyMTkwNDc2LDI1LjQyMzc1IDMuNTIxOTA0NzYsMjIuNzgyMzIxNCBDMy41MjE5MDQ3NiwyMC4wMzA4MzMzIDYuMDUzMjczODEsMTkuMDQwMjk3NiA2LjgyMzY5MDQ4LDE4LjcxMDExOSBDOC40NzQ1ODMzMywxOC4xNTk4MjE0IDEwLjU2NTcxNDMsMTguMDQ5NzYxOSAxMC44OTU4OTI5LDE4LjA0OTc2MTkgTDExLjc3NjM2OSwxOC4wNDk3NjE5IEMxNC43NDc5NzYyLDIwLjI1MDk1MjQgMTYuMDY4NjkwNSwyMS4zNTE1NDc2IDE2LjA2ODY5MDUsMjMuMzMyNjE5IEwxNi4wNjg2OTA1LDIzLjMzMjYxOSBaIE0xMC41NjU3MTQzLDExLjg4NjQyODYgQzcuMjYzOTI4NTcsMTEuODg2NDI4NiA1LjUwMjk3NjE5LDguMDM0MzQ1MjQgNS41MDI5NzYxOSw1LjA2MjczODEgQzUuNTAyOTc2MTksMi4zMTEyNSA3LjI2MzkyODU3LDAuOTkwNTM1NzE0IDkuMTM0OTQwNDgsMC45OTA1MzU3MTQgQzEyLjY1Njg0NTIsMC45OTA1MzU3MTQgMTQuNDE3Nzk3Niw1LjM5MjkxNjY3IDE0LjQxNzc5NzYsOC4wMzQzNDUyNCBDMTQuMzA3NzM4MSwxMS4yMjYwNzE0IDExLjU1NjI1LDExLjg4NjQyODYgMTAuNTY1NzE0MywxMS44ODY0Mjg2IEwxMC41NjU3MTQzLDExLjg4NjQyODYgWiBNMjYuNDE0Mjg1NywxMi42NTY4NDUyIEwyNi40MTQyODU3LDcuNzA0MTY2NjcgTDI0Ljc2MzM5MjksNy43MDQxNjY2NyBMMjQuNzYzMzkyOSwxMi42NTY4NDUyIEwxOS44MTA3MTQzLDEyLjY1Njg0NTIgTDE5LjgxMDcxNDMsMTQuMzA3NzM4MSBMMjQuNzYzMzkyOSwxNC4zMDc3MzgxIEwyNC43NjMzOTI5LDE5LjI2MDQxNjcgTDI2LjQxNDI4NTcsMTkuMjYwNDE2NyBMMjYuNDE0Mjg1NywxNC4zMDc3MzgxIEwzMS4zNjY5NjQzLDE0LjMwNzczODEgTDMxLjM2Njk2NDMsMTIuNjU2ODQ1MiBMMjYuNDE0Mjg1NywxMi42NTY4NDUyIEwyNi40MTQyODU3LDEyLjY1Njg0NTIgWiIgaWQ9IlNoYXBlIiBmaWxsPSIjRjFGMUYxIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkuNzk1Mjk3NjIsMTMuMzE3MjAyNCBMOS43OTUyOTc2MiwxMy4wOTcwODMzIEM5LjU3NTE3ODU3LDEzLjQyNzI2MTkgOS40NjUxMTkwNSwxNC4wODc2MTkgOS40NjUxMTkwNSwxNC41Mjc4NTcxIEw5LjQ2NTExOTA1LDE0LjYzNzkxNjcgQzkuNDY1MTE5MDUsMTQuMTk3Njc4NiA5LjU3NTE3ODU3LDEzLjY0NzM4MSA5Ljc5NTI5NzYyLDEzLjMxNzIwMjQgTDkuNzk1Mjk3NjIsMTMuMzE3MjAyNCBaIE0xMC40NTU2NTQ4LDE2Ljk0OTE2NjcgQzguNjk0NzAyMzgsMTcuMDU5MjI2MiA1LjM5MjkxNjY3LDE3LjM4OTQwNDggMi45NzE2MDcxNCwxOC45MzAyMzgxIEMwLjY2MDM1NzE0MywyMC4yNTA5NTI0IDAsMjIuMjMyMDIzOCAwLDIzLjY2Mjc5NzYgTDAsMjMuNzcyODU3MSBDMC4xMTAwNTk1MjQsMjIuMzQyMDgzMyAwLjc3MDQxNjY2NywyMC40NzEwNzE0IDIuOTcxNjA3MTQsMTkuMTUwMzU3MSBDNS4zOTI5MTY2NywxNy43MTk1ODMzIDguNjk0NzAyMzgsMTcuMjc5MzQ1MiAxMC40NTU2NTQ4LDE3LjE2OTI4NTcgTDEwLjQ1NTY1NDgsMTYuOTQ5MTY2NyBMMTAuNDU1NjU0OCwxNi45NDkxNjY3IFogTTEwLjM0NTU5NTIsMjcuNTE0ODgxIEM2LjI3MzM5Mjg2LDI3LjUxNDg4MSAzLjYzMTk2NDI5LDI1LjUzMzgwOTUgMy41MjE5MDQ3NiwyMi44OTIzODEgTDMuNTIxOTA0NzYsMjMuMDAyNDQwNSBDMy41MjE5MDQ3NiwyNS42NDM4NjkgNi4xNjMzMzMzMywyNy43MzUgMTAuMzQ1NTk1MiwyNy43MzUgQzE0LjA4NzYxOSwyNy43MzUgMTYuMDY4NjkwNSwyNS43NTM5Mjg2IDE2LjA2ODY5MDUsMjMuNTUyNzM4MSBMMTYuMDY4NjkwNSwyMy40NDI2Nzg2IEMxNS45NTg2MzEsMjUuNjQzODY5IDEzLjk3NzU1OTUsMjcuNTE0ODgxIDEwLjM0NTU5NTIsMjcuNTE0ODgxIEwxMC4zNDU1OTUyLDI3LjUxNDg4MSBaIE0xNC4zMDc3MzgxLDguMjU0NDY0MjkgTDE0LjMwNzczODEsOC4xNDQ0MDQ3NiBDMTQuMTk3Njc4NiwxMS4zMzYxMzEgMTEuNTU2MjUsMTEuODg2NDI4NiAxMC40NTU2NTQ4LDExLjg4NjQyODYgQzcuMjYzOTI4NTcsMTEuODg2NDI4NiA1LjM5MjkxNjY3LDguMTQ0NDA0NzYgNS4zOTI5MTY2Nyw1LjE3Mjc5NzYyIEw1LjM5MjkxNjY3LDUuMjgyODU3MTQgQzUuMzkyOTE2NjcsOC4yNTQ0NjQyOSA3LjE1Mzg2OTA1LDEyLjEwNjU0NzYgMTAuNDU1NjU0OCwxMi4xMDY1NDc2IEMxMS41NTYyNSwxMi4xMDY1NDc2IDE0LjMwNzczODEsMTEuNDQ2MTkwNSAxNC4zMDc3MzgxLDguMjU0NDY0MjkgTDE0LjMwNzczODEsOC4yNTQ0NjQyOSBaIE0xNS40MDgzMzMzLDE2LjI4ODgwOTUgTDEzLjk3NzU1OTUsMTUuMTg4MjE0MyBDMTMuNTM3MzIxNCwxNC44NTgwMzU3IDEzLjIwNzE0MjksMTQuNDE3Nzk3NiAxMy4wOTcwODMzLDEzLjY0NzM4MSBMMTMuMDk3MDgzMywxMy43NTc0NDA1IEMxMy4wOTcwODMzLDE0LjYzNzkxNjcgMTMuNTM3MzIxNCwxNS4wNzgxNTQ4IDEzLjk3NzU1OTUsMTUuNDA4MzMzMyBMMTUuNDA4MzMzMywxNi41MDg5Mjg2IEMxNy4wNTkyMjYyLDE3LjkzOTcwMjQgMTguNjAwMDU5NSwxOS4yNjA0MTY3IDE4LjcxMDExOSwyMS43OTE3ODU3IEwxOC43MTAxMTksMjEuNjgxNzI2MiBDMTguNjAwMDU5NSwxOS4wNDAyOTc2IDE3LjA1OTIyNjIsMTcuODI5NjQyOSAxNS40MDgzMzMzLDE2LjI4ODgwOTUgTDE1LjQwODMzMzMsMTYuMjg4ODA5NSBaIE0yNi40MTQyODU3LDEyLjY1Njg0NTIgTDI2LjQxNDI4NTcsMTIuODc2OTY0MyBMMzEuMzY2OTY0MywxMi44NzY5NjQzIEwzMS4zNjY5NjQzLDEyLjY1Njg0NTIgTDI2LjQxNDI4NTcsMTIuNjU2ODQ1MiBMMjYuNDE0Mjg1NywxMi42NTY4NDUyIFogTTE3LjQ5OTQ2NDMsNi4yNzMzOTI4NiBMMTcuNDk5NDY0Myw2LjE2MzMzMzMzIEMxNy40OTk0NjQzLDMuNDExODQ1MjQgMTUuODQ4NTcxNCwxLjk4MTA3MTQzIDE0Ljg1ODAzNTcsMS4yMTA2NTQ3NiBMMTQuODU4MDM1NywxLjU0MDgzMzMzIEMxNS44NDg1NzE0LDIuMjAxMTkwNDggMTcuNDk5NDY0MywzLjYzMTk2NDI5IDE3LjQ5OTQ2NDMsNi4yNzMzOTI4NiBMMTcuNDk5NDY0Myw2LjI3MzM5Mjg2IFogTTI2LjQxNDI4NTcsNy43MDQxNjY2NyBMMjQuNzYzMzkyOSw3LjcwNDE2NjY3IEwyNC43NjMzOTI5LDcuOTI0Mjg1NzEgTDI2LjQxNDI4NTcsNy45MjQyODU3MSBMMjYuNDE0Mjg1Nyw3LjcwNDE2NjY3IEwyNi40MTQyODU3LDcuNzA0MTY2NjcgWiBNMi4zMTEyNSw2LjgyMzY5MDQ4IEwyLjMxMTI1LDYuOTMzNzUgQzIuNDIxMzA5NTIsMy4wODE2NjY2NyA1LjA2MjczODEsLTAuMTEwMDU5NTI0IDEwLjU2NTcxNDMsLTAuMTEwMDU5NTI0IEwxOC4zNzk5NDA1LC0wLjExMDA1OTUyNCBMMTguNzEwMTE5LC0wLjQ0MDIzODA5NSBMMTAuNjc1NzczOCwtMC40NDAyMzgwOTUgQzQuOTUyNjc4NTcsLTAuNDQwMjM4MDk1IDIuMzExMjUsMi45NzE2MDcxNCAyLjMxMTI1LDYuODIzNjkwNDggTDIuMzExMjUsNi44MjM2OTA0OCBaIE0xOS44MTA3MTQzLDEyLjk4NzAyMzggTDI0Ljc2MzM5MjksMTIuOTg3MDIzOCBMMjQuNzYzMzkyOSwxMi43NjY5MDQ4IEwxOS44MTA3MTQzLDEyLjc2NjkwNDggTDE5LjgxMDcxNDMsMTIuOTg3MDIzOCBMMTkuODEwNzE0MywxMi45ODcwMjM4IFoiIGlkPSJTaGFwZSIgZmlsbC1vcGFjaXR5PSIwLjY0IiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);
-      }
-      .btn-icon-local {
-        background-color: #84B6EF;
-        background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjBweCIgdmlld0JveD0iMCAwIDI0IDIwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggMy4zLjIgKDEyMDQzKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5SZWN0YW5nbGUgMjkxICsgUGF0aCAyMzI8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4KICAgICAgICA8ZyBpZD0iQS4xLVZlcmlmeS1FbWFpbC1TY3JlZW5fbG9naW4tIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDA5LjAwMDAwMCwgLTIwOS4wMDAwMDApIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0iI0ZGRkZGRiI+CiAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMzktQ29weS02LSstRW1haWwtQ29weS0rLVJlY3RhbmdsZS0yOTAtKy1SZWN0YW5nbGUtMjkxLSstUGF0aC0yMzIiIHNrZXRjaDp0eXBlPSJNU0xheWVyR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMC4wMDAwMDAsIDE5Ny4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMjkwLSstUmVjdGFuZ2xlLTI5MS0rLVBhdGgtMjMyIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0iUmVjdGFuZ2xlLTI5MS0rLVBhdGgtMjMyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg5LjAwMDAwMCwgMTIuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS0yOTEiIHg9IjAiIHk9IjAiIHdpZHRoPSIyNCIgaGVpZ2h0PSIxOS4zNSI+PC9yZWN0PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTAsMS45MjcyNzEzOSBMMTEuNjExMzAxOSwxMi45IEwyNCwxLjE5MjYyODgxIiBpZD0iUGF0aC0yMzIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+);
-      }
-      .btn-icon-coreos {
-        /* B&W CoreOS SVG logo */
-        background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjNjY2IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDIxNSAyMTUiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KICA8Zz4NCiAgICA8Zz4NCiAgICAgIDxwYXRoIGQ9Ik0xMDcuNDc5LDEuMDc1Yy01OC42NzcsMC0xMDYuNDA0LDQ3LjczLTEwNi40MDQsMTA2LjM5OGMwLDU4LjY3Miw0Ny43MjcsMTA2LjM5OSwxMDYuNDA0LDEwNi4zOTkNCiAgICAgICAgICAgICAgYzU4LjY1OSwwLDEwNi4zOS00Ny43MjcsMTA2LjM5LTEwNi4zOTlDMjEzLjg2OSw0OC44MDUsMTY2LjEzOCwxLjA3NSwxMDcuNDc5LDEuMDc1eiBNMTQ3LjQ0OSwxMzQuNjI3DQogICAgICAgICAgICAgIGMtMC44OCwwLjEyOC0xLjc0OSwwLjI1MS0yLjYzMiwwLjM2NGMtOC4wMywxLjAzOC0xNi42MDIsMS43NDMtMjUuNTYxLDIuMDc4Yy0zLjg1NiwwLjE0NC03Ljc5MywwLjIzMS0xMS43NzYsMC4yMzENCiAgICAgICAgICAgICAgYy0zLjk5NSwwLTcuOTItMC4wODYtMTEuNzg4LTAuMjMxYy04Ljk0OC0wLjMzNS0xNy41MjYtMS4wNC0yNS41NDktMi4wNzhjLTAuNzE2LTUuOTg3LTEuMjAxLTEyLjIxNi0xLjQ0My0xOC42MjMNCiAgICAgICAgICAgICAgYy0wLjExNi0yLjkyNi0wLjE3My01Ljg5Ni0wLjE3My04Ljg5NWMwLTMuMDAyLDAuMDU3LTUuOTY2LDAuMTczLTguODk4YzAuMjQzLTYuNDA4LDAuNzI4LTEyLjYzMywxLjQ0My0xOC42Mg0KICAgICAgICAgICAgICBjMC4xNDQtMS4yNDYsMC4zMDYtMi40ODUsMC40NzMtMy43MDljNS4yNDEtMzguMDQsMTkuNzUyLTY1LjQwOCwzNi44NjMtNjUuNDA4YzUzLjM2NCwwLDk2LjYzMiw0My4yNjIsOTYuNjMzLDk2LjYzNQ0KICAgICAgICAgICAgICBDMjA0LjExMiwxMTkuNTQ3LDE4MC44NjYsMTI5LjkzNCwxNDcuNDQ5LDEzNC42Mjd6Ii8+DQogICAgICA8cGF0aCBkPSJNMTQ3LjQ0OCw4MC4zMTZjLTAuOTY5LTEuNDE0LTIuMDA5LTIuNzY4LTMuMTE3LTQuMDY5Yy04Ljg2Ni0xMC40NTEtMjIuMDc0LTE3LjA5Mi0zNi44NTItMTcuMDkyDQogICAgICAgICAgICAgIGMtNC43OTEsMC05LjA1Nyw3LjMzMy0xMS43ODgsMTguNzJjLTEuMDg1LDQuNTQtMS45MjgsOS43MjEtMi40NywxNS4zNDNjLTAuNDI4LDQuNTA1LTAuNjU4LDkuMjk3LTAuNjU4LDE0LjI1NQ0KICAgICAgICAgICAgICBzMC4yMzEsOS43NTEsMC42NTgsMTQuMjUyYzQuNTA4LDAuNDI4LDkuMjkzLDAuNjU3LDE0LjI1OCwwLjY1N2M0Ljk1OSwwLDkuNzQ0LTAuMjMsMTQuMjUyLTAuNjU3DQogICAgICAgICAgICAgIGM5LjkxMS0wLjk0LDE4LjQ2Ni0yLjg0NiwyNC41MjctNS4zNTdjNS45ODYtMi40NzYsOS41MjgtNS41NTksOS41MjgtOC44OTVDMTU1Ljc4Niw5Ny40MDcsMTUyLjcxMiw4OC4wNTcsMTQ3LjQ0OCw4MC4zMTZ6Ii8+DQogICAgPC9nPg0KICA8L2c+DQo8L3N2Zz4NCg==);
-      }
-      .btn-icon-github {
-        background-color: #F5F5F5;
-        background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTggMEMzLjU4IDAgMCAzLjU4IDAgOGMwIDMuNTQgMi4yOSA2LjUzIDUuNDcgNy41OSAwLjQgMC4wNyAwLjU1LTAuMTcgMC41NS0wLjM4IDAtMC4xOS0wLjAxLTAuODItMC4wMS0xLjQ5LTIuMDEgMC4zNy0yLjUzLTAuNDktMi42OS0wLjk0LTAuMDktMC4yMy0wLjQ4LTAuOTQtMC44Mi0xLjEzLTAuMjgtMC4xNS0wLjY4LTAuNTItMC4wMS0wLjUzIDAuNjMtMC4wMSAxLjA4IDAuNTggMS4yMyAwLjgyIDAuNzIgMS4yMSAxLjg3IDAuODcgMi4zMyAwLjY2IDAuMDctMC41MiAwLjI4LTAuODcgMC41MS0xLjA3LTEuNzgtMC4yLTMuNjQtMC44OS0zLjY0LTMuOTUgMC0wLjg3IDAuMzEtMS41OSAwLjgyLTIuMTUtMC4wOC0wLjItMC4zNi0xLjAyIDAuMDgtMi4xMiAwIDAgMC42Ny0wLjIxIDIuMiAwLjgyIDAuNjQtMC4xOCAxLjMyLTAuMjcgMi0wLjI3IDAuNjggMCAxLjM2IDAuMDkgMiAwLjI3IDEuNTMtMS4wNCAyLjItMC44MiAyLjItMC44MiAwLjQ0IDEuMSAwLjE2IDEuOTIgMC4wOCAyLjEyIDAuNTEgMC41NiAwLjgyIDEuMjcgMC44MiAyLjE1IDAgMy4wNy0xLjg3IDMuNzUtMy42NSAzLjk1IDAuMjkgMC4yNSAwLjU0IDAuNzMgMC41NCAxLjQ4IDAgMS4wNy0wLjAxIDEuOTMtMC4wMSAyLjIgMCAwLjIxIDAuMTUgMC40NiAwLjU1IDAuMzhDMTMuNzEgMTQuNTMgMTYgMTEuNTMgMTYgOCAxNiAzLjU4IDEyLjQyIDAgOCAweiIgLz4KPC9zdmc+Cg==);
-      }
-      .btn-icon-bitbucket {
-        background-color: #205081;
-        background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTAwMCIgd2lkdGg9Ijc4NS43MTQiPjxwYXRoIGQ9Ik00NTQuNzcgNDc5LjM4NnE0LjQ2NCAzNS4xNTQgLTI4LjE3OSA1Ni4zNTh0LTYyLjIxNyAzLjM0OHEtMjEuNzYyIC05LjQ4NiAtMjkuODUzIC0zMi4zNjR0LS4yNzkgLTQ1Ljc1NiAyOS4wMTYgLTMyLjM2NHEyMC4wODggLTEwLjA0NCA0MC40NTUgLTYuNjk2dDM1LjcxMiAxOS44MDkgMTUuMzQ1IDM3LjY2NXptNjEuOTM4IC0xMS43MThxLTcuODEyIC01OS43MDYgLTYzLjA1NCAtOTEuNTEydC0xMDkuOTI2IC03LjI1NHEtMzUuMTU0IDE1LjYyNCAtNTYuMDc5IDQ5LjM4M3QtMTkuMjUxIDcyLjI2MXEyLjIzMiA1MC43NzggNDMuMjQ1IDg2LjQ5dDkyLjM0OSAzMS4yNDhxNTAuNzc4IC00LjQ2NCA4NC44MTYgLTQ2Ljg3MnQyNy45IC05My43NDR6bTEzMy4zNjIgLTMwMi40MzZxLTExLjE2IC0xNS4wNjYgLTMxLjI0OCAtMjQuODMxdC0zMi4zNjQgLTEyLjI3NiAtMzkuNjE4IC02Ljk3NXEtMTYyLjM3OCAtMjYuMjI2IC0zMTUuODI4IDEuMTE2IC0yMy45OTQgMy45MDYgLTM2LjgyOCA2LjY5NnQtMzAuNjkgMTIuMjc2IC0yNy45IDIzLjk5NHExNi43NCAxNS42MjQgNDIuNDA4IDI1LjM4OXQ0MS4wMTMgMTIuMjc2IDQ4LjgyNSA2LjQxN3ExMjcuMjI0IDE2LjE4MiAyNDkuOTg0IC41NTggMzUuMTU0IC00LjQ2NCA0OS45NDEgLTYuNjk2dDQwLjQ1NSAtMTEuOTk3IDQxLjg1IC0yNS45NDd6bTMxLjgwNiA1NzcuNTNxLTQuNDY0IDE0LjUwOCAtOC42NDkgNDIuNjg3dC03LjgxMiA0Ni44NzIgLTE1LjkwMyAzOS4wNiAtMzIuMzY0IDMxLjUyN3EtNDcuOTg4IDI2Ljc4NCAtMTA1Ljc0MSAzOS44OTd0LTExMi43MTYgMTIuMjc2IC0xMTIuNDM3IC0xMC4zMjNxLTI1LjY2OCAtNC40NjQgLTQ1LjQ3NyAtMTAuMDQ0dC00Mi42ODcgLTE1LjA2NiAtNDAuNzM0IC0yNC4yNzMgLTI5LjAxNiAtMzQuMzE3cS0xMy45NSAtNTMuNTY4IC0zMS44MDYgLTE2Mi45MzZsMy4zNDggLTguOTI4IDEwLjA0NCAtNS4wMjJxMTI0LjQzNCA4Mi41ODQgMjgyLjYyNyA4Mi41ODR0MjgzLjE4NSAtODIuNTg0cTExLjcxOCAzLjM0OCAxMy4zOTIgMTIuODM0dC0yLjc5IDI1LjExIC00LjQ2NCAyMC42NDZ6bTEwMC45OTggLTUzNi4yMzhxLTE0LjUwOCA5My4xODYgLTYxLjkzOCAzNjUuNDkgLTIuNzkgMTYuNzQgLTE1LjA2NiAzMS4yNDh0LTI0LjI3MyAyMi4zMiAtMzAuNDExIDE3LjI5OHEtMTQwLjYxNiA3MC4zMDggLTM0MC4zOCA0OS4xMDQgLTEzOC4zODQgLTE1LjA2NiAtMjE5Ljg1MiAtNzcuNTYyIC04LjM3IC02LjY5NiAtMTQuMjI5IC0xNC43ODd0LTkuNDg2IC0xOS41MyAtNS4wMjIgLTE4Ljk3MiAtMy4zNDggLTIyLjA0MSAtMy4wNjkgLTE5LjUzcS01LjAyMiAtMjcuOSAtMTQuNzg3IC04My43dC0xNS42MjQgLTkwLjExNyAtMTMuMTEzIC04Mi4zMDUgLTEyLjI3NiAtODguMTY0cTEuNjc0IC0xNC41MDggOS43NjUgLTI3LjA2M3QxNy41NzcgLTIwLjkyNSAyNS4xMSAtMTYuNzQgMjUuNjY4IC0xMi41NTUgMjYuNzg0IC0xMC4zMjNxNjkuNzUgLTI1LjY2OCAxNzQuNjU0IC0zNS43MTIgMjExLjQ4MiAtMjAuNjQ2IDM3Ny4yMDggMjcuOSA4Ni40OSAyNS42NjggMTE5Ljk3IDY4LjA3NiA4LjkyOCAxMS4xNiA5LjIwNyAyOC40NTh0LTMuMDY5IDMwLjEzMnoiIGZpbGw9IiNGRkZGRkYiLz48L3N2Zz4K);
-      }
-      .btn-text {
-        line-height: 36px;
-        padding: 6px 12px;
-        text-align: center;
-        font-weight: 600;
-      }
-      .form-row {
-        display: block;
-        margin: 20px auto;
-      }
-      label {
-        font-size: 13px;
-        font-weight: 600;
-      }
-      .input-box {
-        display: block;
-        height: 36px;
-        padding: 6px 12px;
-        font-size: 14px;
-        line-height: 1.42857143;
-        color: #666;
-        border: 1px solid #CCC;
-        border-radius: 4px;
-        box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-        width: 250px;
-        margin: auto;
-      }
-      .input-box:focus,
-      .input-box:active {
-        outline: none;
-        border-color: #66AFE9;
-      }
-      .error-box-field,
-      .error-box {
-        background-color: #DD1327;
-        max-width: 320px;
-        color: #fff;
-        font-size: 14px;
-        font-weight: normal;
-        padding: 4px 0;
-      }
-      .error-box {
-        margin: 20px auto;
-      }
-      .error-box-field {
-        margin: 0 auto;
-        width: 250px;
-      }
-      .instruction-block {
-        font-size: 14px;
-      }
-      .detail-block {
-        color: #777;
-        font-size: 12px;
-        margin-top: 20px;
-      }
-      .bullet-point {
-        list-style: square;
-      }
-      .list-with-title {
-        text-align: left;
-        margin: 0 25%;
-      }
-      .hr {
-        color: #999;
-      }
-    </style>
-  </head>
-
-  <body>
-    <div id="navbar">
-      <div id="navbar-logo-wrap">
-        <img id="navbar-logo" src="{{ .LogoURL }}">
-      </div>
-    </div>
-
-    <div id="container">
-
-`,
-	"login.html": `{{ template "header.html" . }}
-
-<div class="panel">
-  <h2 class="heading">Log in to {{ .Issuer }} </h2>
-
-  <div>
-    {{ range $c := .Connectors }}
-      <div class="form-row">
-        <a href="{{ $c.URL }}?req={{ $.AuthReqID }}" target="_self">
-          <button class="btn btn-provider">
-            <span class="btn-icon btn-icon-{{ $c.ID }}"></span>
-            <span class="btn-text">Log in with {{ $c.Name }}</span>
-          </button>
-        </a>
-      </div>
-    {{ end }}
-  </div>
-
-</div>
-
-
-{{ template "footer.html" . }}
-`,
-	"oob.html": `{{ template "header.html" . }}
-
-<div class="panel">
-  <h2 class="heading">Login Successful</h2>
-
-  Please copy this code, switch to your application and paste it there:
-  <br/>
-  <input type="text" value="{{ .Code }}" />
-</div>
-
-{{ template "footer.html" . }}
-`,
-	"password.html": `{{ template "header.html" . }}
-
-<div class="panel">
-  <h2 class="heading">Log in to Your Account</h2>
-  <form method="post" action="{{ .PostURL }}">
-    <div class="form-row">
-      <div class="input-desc">
-        <label for="userid">Username</label>
-      </div>
-	  <input tabindex="1" required id="login" name="login" type="text" class="input-box" placeholder="username" {{ if .Username }}value="{{ .Username }}" {{ else }} autofocus {{ end }}/>
-    </div>
-    <div class="form-row">
-      <div class="input-desc">
-        <label for="password">Password</label>
-      </div>
-	  <input tabindex="2" required id="password" name="password" type="password" class="input-box" placeholder="password" {{ if .Invalid }} autofocus {{ end }}/>
-    </div>
-    <input type="hidden" name="req" value="{{ .AuthReqID }}"/>
-
-    {{ if .Invalid }}
-      <div class="error-box">
-        Invalid username and password.
-      </div>
-    {{ end }}
-
-    <button tabindex="3" type="submit" class="btn btn-primary">Login</button>
-
-  </form>
-</div>
-
-{{ template "footer.html" . }}
-`,
-}
diff --git a/server/templates_default_gen.go b/server/templates_default_gen.go
deleted file mode 100644
index 0e46df780e9e1a3d8446cff1947f89f303913321..0000000000000000000000000000000000000000
--- a/server/templates_default_gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// +build ignore
-
-package main
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os/exec"
-	"path/filepath"
-)
-
-// ignoreFile uses "git check-ignore" to determine if we should ignore a file.
-func ignoreFile(p string) (ok bool, err error) {
-	err = exec.Command("git", "check-ignore", p).Run()
-	if err == nil {
-		return true, nil
-	}
-	exitErr, ok := err.(*exec.ExitError)
-	if ok {
-		if sys := exitErr.Sys(); sys != nil {
-			e, ok := sys.(interface {
-				// Is the returned value something that returns an exit status?
-				ExitStatus() int
-			})
-			if ok && e.ExitStatus() == 1 {
-				return false, nil
-			}
-		}
-	}
-	return false, err
-}
-
-// Maps aren't deterministic, use a struct instead.
-
-type fileData struct {
-	name string
-	data string
-}
-
-func main() {
-	// ReadDir guarentees result in sorted order.
-	dir, err := ioutil.ReadDir("web/templates")
-	if err != nil {
-		log.Fatal(err)
-	}
-	files := []fileData{}
-	for _, file := range dir {
-		p := filepath.Join("web/templates", file.Name())
-		ignore, err := ignoreFile(p)
-		if err != nil {
-			log.Fatal(err)
-		}
-		if ignore {
-			continue
-		}
-
-		data, err := ioutil.ReadFile(p)
-		if err != nil {
-			log.Fatal(err)
-		}
-		if bytes.Contains(data, []byte{'`'}) {
-			log.Fatalf("file %s contains escape character '`' and cannot be compiled into go source", p)
-		}
-		files = append(files, fileData{file.Name(), string(data)})
-	}
-
-	f := new(bytes.Buffer)
-
-	fmt.Fprintln(f, "// This file was generated by the makefile. Do not edit.")
-	fmt.Fprintln(f)
-	fmt.Fprintln(f, "package server")
-	fmt.Fprintln(f)
-	fmt.Fprintln(f, "// defaultTemplates is a key for file name to file data of the files in web/templates.")
-	fmt.Fprintln(f, "var defaultTemplates = map[string]string{")
-	for _, file := range files {
-		fmt.Fprintf(f, "\t%q: `%s`,\n", file.name, file.data)
-	}
-	fmt.Fprintln(f, "}")
-
-	if err := ioutil.WriteFile("server/templates_default.go", f.Bytes(), 0644); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/server/templates_test.go b/server/templates_test.go
index efbb29edf9ad03f12a894f8c3a6bb2f4138798d0..abb4e431abd516750a5a1e5e2b77073c236b8f9e 100644
--- a/server/templates_test.go
+++ b/server/templates_test.go
@@ -1,16 +1 @@
 package server
-
-import "testing"
-
-func TestNewTemplates(t *testing.T) {
-	var config TemplateConfig
-	if _, err := loadTemplates(config); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestLoadTemplates(t *testing.T) {
-	var config TemplateConfig
-
-	config.Dir = "../web/templates"
-}
diff --git a/web/static/main.css b/web/static/main.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/web/templates/header.html b/web/templates/header.html
index cadb078d9750f0b1aab2b81a82eb3b85f60096d6..79438ec44e2a0927282ee56adfe8be002f7e20bf 100644
--- a/web/templates/header.html
+++ b/web/templates/header.html
@@ -3,8 +3,10 @@
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <title>{{ .Issuer }}</title>
+    <title>{{ issuer }}</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="{{ url "static/main.css" }}" rel="stylesheet">
+    <link href="{{ url "theme/style.css" }}" rel="stylesheet">
     <style>
       * {
         -webkit-box-sizing: border-box;
@@ -232,7 +234,7 @@
   <body>
     <div id="navbar">
       <div id="navbar-logo-wrap">
-        <img id="navbar-logo" src="{{ .LogoURL }}">
+        <img id="navbar-logo" src="{{ logo }}">
       </div>
     </div>
 
diff --git a/web/templates/login.html b/web/templates/login.html
index ea43903a538e55b652babf21dc4f0ec722b6dd58..e52f775ac6979a12c945ddfb562a941e4e1584f0 100644
--- a/web/templates/login.html
+++ b/web/templates/login.html
@@ -1,7 +1,7 @@
 {{ template "header.html" . }}
 
 <div class="panel">
-  <h2 class="heading">Log in to {{ .Issuer }} </h2>
+  <h2 class="heading">Log in to {{ issuer }} </h2>
 
   <div>
     {{ range $c := .Connectors }}
diff --git a/web/themes/coreos/logo.png b/web/themes/coreos/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf8caaaee53500d4efa77c587997788ac8d4fa6e
Binary files /dev/null and b/web/themes/coreos/logo.png differ
diff --git a/web/themes/coreos/style.css b/web/themes/coreos/style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391