├── .cloud ├── docker │ └── Dockerfile └── nginx │ └── nginx.conf ├── .github └── FUNDING.yml ├── .gitignore ├── 401.html ├── 403.html ├── 404.html ├── 429.html ├── 500.html ├── 502.html ├── 503.html ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── _config.yml ├── _layouts └── default.html ├── assets ├── css │ └── application.css └── img │ ├── 403.svg │ ├── 404.svg │ ├── 500.svg │ └── 503.svg ├── netlify.toml └── robots.txt /.cloud/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # jekyll 2 | FROM jekyll/builder:latest as jekyll 3 | WORKDIR /tmp 4 | COPY . /tmp 5 | RUN chown -R jekyll:jekyll /tmp 6 | RUN gem install bundler:1.16.6 7 | RUN jekyll build 8 | 9 | # nginx 10 | FROM nginx:alpine as nginx 11 | 12 | COPY .cloud/nginx/nginx.conf /etc/nginx/conf.d/default.conf 13 | COPY --from=jekyll /tmp/_site/ /var/www/public/ 14 | -------------------------------------------------------------------------------- /.cloud/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | index index.php index.html index.htm; 4 | root /var/www/public/; 5 | 6 | try_files $uri =404; 7 | error_page 401 403 404 429 /404.html; 8 | } 9 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: guillaumebriday 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | .jekyll-metadata 4 | .jekyll-cache 5 | -------------------------------------------------------------------------------- /401.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Unauthorized 4 | code: 401 5 | asset: 403.svg 6 | --- 7 | 8 | Sorry, you are not authorized to access this page. 9 | -------------------------------------------------------------------------------- /403.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Forbidden 4 | code: 403 5 | asset: 403.svg 6 | --- 7 | 8 | Sorry, you are forbidden from accessing this page. 9 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Page Not Found 4 | code: 404 5 | asset: 404.svg 6 | --- 7 | 8 | Sorry, the page you are looking for could not be found. 9 | -------------------------------------------------------------------------------- /429.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Too Many Requests 4 | code: 429 5 | asset: 403.svg 6 | --- 7 | 8 | Sorry, you are making too many requests to our servers. 9 | -------------------------------------------------------------------------------- /500.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Error 4 | code: 500 5 | asset: 500.svg 6 | --- 7 | 8 | Whoops, something went wrong on our servers. 9 | -------------------------------------------------------------------------------- /502.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Bad Gateway 4 | code: 502 5 | asset: 503.svg 6 | --- 7 | 8 | Sorry, the page you are looking for is not available. Please check back soon. 9 | -------------------------------------------------------------------------------- /503.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Service Unavailable 4 | code: 503 5 | asset: 503.svg 6 | --- 7 | 8 | Sorry, we are doing some maintenance. Please check back soon. 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Hello! This is where you manage which Jekyll version is used to run. 4 | # When you want to use a different version, change it below, save the 5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 6 | # 7 | # bundle exec jekyll serve 8 | # 9 | # This will help ensure the proper Jekyll version is running. 10 | # Happy Jekylling! 11 | gem "jekyll" 12 | 13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 14 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 15 | # gem "github-pages", group: :jekyll_plugins 16 | 17 | # If you have any plugins, put them here! 18 | group :jekyll_plugins do 19 | gem "octopress-minify-html" 20 | gem "jekyll-assets" 21 | end 22 | 23 | # needed for jekyll-assets 24 | gem "sprockets", "~> 3.7" 25 | 26 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 27 | gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] 28 | 29 | # Performance-booster for watching directories on Windows 30 | gem "wdm", "~> 0.1.0" if Gem.win_platform? 31 | 32 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (5.2.4.3) 5 | concurrent-ruby (~> 1.0, >= 1.0.2) 6 | i18n (>= 0.7, < 2) 7 | minitest (~> 5.1) 8 | tzinfo (~> 1.1) 9 | addressable (2.6.0) 10 | public_suffix (>= 2.0.2, < 4.0) 11 | colorator (1.1.0) 12 | concurrent-ruby (1.1.5) 13 | css_press (0.3.2) 14 | csspool-st (= 3.1.2) 15 | json 16 | csspool-st (3.1.2) 17 | em-websocket (0.5.1) 18 | eventmachine (>= 0.12.9) 19 | http_parser.rb (~> 0.6.0) 20 | eventmachine (1.2.7) 21 | execjs (2.7.0) 22 | extras (0.3.0) 23 | forwardable-extended (~> 2.5) 24 | fastimage (2.1.7) 25 | ffi (1.10.0) 26 | forwardable-extended (2.6.0) 27 | html_press (0.8.2) 28 | htmlentities 29 | multi_css (>= 0.1.0) 30 | multi_js (>= 0.1.0) 31 | htmlentities (4.3.4) 32 | http_parser.rb (0.6.0) 33 | i18n (0.9.5) 34 | concurrent-ruby (~> 1.0) 35 | jekyll (3.8.5) 36 | addressable (~> 2.4) 37 | colorator (~> 1.0) 38 | em-websocket (~> 0.5) 39 | i18n (~> 0.7) 40 | jekyll-sass-converter (~> 1.0) 41 | jekyll-watch (~> 2.0) 42 | kramdown (~> 1.14) 43 | liquid (~> 4.0) 44 | mercenary (~> 0.3.3) 45 | pathutil (~> 0.9) 46 | rouge (>= 1.7, < 4) 47 | safe_yaml (~> 1.0) 48 | jekyll-assets (3.0.12) 49 | activesupport (~> 5.0) 50 | execjs (~> 2.7) 51 | extras (~> 0.2) 52 | fastimage (~> 2.0, >= 1.8) 53 | jekyll (>= 3.5, < 4.0) 54 | jekyll-sanity (~> 1.2) 55 | liquid-tag-parser (~> 1.0) 56 | nokogiri (~> 1.8) 57 | pathutil (~> 0.16) 58 | sprockets (>= 3.3, < 4.1.beta) 59 | jekyll-sanity (1.6.0) 60 | jekyll (>= 3.1, < 5.0) 61 | pathutil (~> 0.16) 62 | jekyll-sass-converter (1.5.2) 63 | sass (~> 3.4) 64 | jekyll-watch (2.1.2) 65 | listen (~> 3.0) 66 | json (2.3.1) 67 | kramdown (1.17.0) 68 | liquid (4.0.3) 69 | liquid-tag-parser (1.9.0) 70 | extras (~> 0.3) 71 | liquid (>= 3.0, < 5.0) 72 | listen (3.1.5) 73 | rb-fsevent (~> 0.9, >= 0.9.4) 74 | rb-inotify (~> 0.9, >= 0.9.7) 75 | ruby_dep (~> 1.2) 76 | mercenary (0.3.6) 77 | mini_portile2 (2.4.0) 78 | minitest (5.14.1) 79 | multi_css (0.1.0) 80 | css_press 81 | multi_js (0.1.0) 82 | uglifier (~> 2) 83 | nokogiri (1.10.10) 84 | mini_portile2 (~> 2.4.0) 85 | octopress-hooks (2.6.2) 86 | jekyll (>= 2.0) 87 | octopress-minify-html (1.3.1) 88 | html_press (~> 0.8) 89 | jekyll (>= 2.0) 90 | octopress-hooks 91 | pathutil (0.16.2) 92 | forwardable-extended (~> 2.6) 93 | public_suffix (3.0.3) 94 | rack (2.2.3) 95 | rb-fsevent (0.10.3) 96 | rb-inotify (0.10.0) 97 | ffi (~> 1.0) 98 | rouge (3.3.0) 99 | ruby_dep (1.5.0) 100 | safe_yaml (1.0.5) 101 | sass (3.7.3) 102 | sass-listen (~> 4.0.0) 103 | sass-listen (4.0.0) 104 | rb-fsevent (~> 0.9, >= 0.9.4) 105 | rb-inotify (~> 0.9, >= 0.9.7) 106 | sprockets (3.7.2) 107 | concurrent-ruby (~> 1.0) 108 | rack (> 1, < 3) 109 | thread_safe (0.3.6) 110 | tzinfo (1.2.7) 111 | thread_safe (~> 0.1) 112 | uglifier (2.7.2) 113 | execjs (>= 0.3.0) 114 | json (>= 1.8.0) 115 | 116 | PLATFORMS 117 | ruby 118 | 119 | DEPENDENCIES 120 | jekyll 121 | jekyll-assets 122 | octopress-minify-html 123 | sprockets (~> 3.7) 124 | tzinfo-data 125 | 126 | BUNDLED WITH 127 | 1.16.6 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Guillaume Briday 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/guillaumebriday) 2 | [![Docker Pulls](https://img.shields.io/docker/pulls/guillaumebriday/traefik-custom-error-pages.svg)](https://hub.docker.com/r/guillaumebriday/traefik-custom-error-pages/) 3 | [![Docker Stars](https://img.shields.io/docker/stars/guillaumebriday/traefik-custom-error-pages.svg)](https://hub.docker.com/r/guillaumebriday/traefik-custom-error-pages/) 4 | [![Netlify Status](https://api.netlify.com/api/v1/badges/64de9cea-fa16-4f76-b5b8-a1abb5eb4e2f/deploy-status)](https://app.netlify.com/sites/traefik-custom-error-pages/deploys) 5 | 6 | # ⚠️ DEPRECATION WARNING ⚠️ 7 | 8 | I'm not using this image anymore. I switched from Traefik to [Caddy](https://caddyserver.com) because Traefik is far too complicated for **my** needs. This image works as it. If you want new features, feel free to fork the project. An alternative project for the traefik error pages is [tarampampam/error-pages](https://github.com/tarampampam/error-pages). It also supports the theme used in this project. 9 | 10 | # Custom error pages for Traefik 11 | 12 | A bunch of custom error pages for Traefik built with [Jekyll](https://jekyllrb.com/). 13 | 14 | ## Development 15 | 16 | Install dependencies 17 | 18 | ```bash 19 | $ bundle install 20 | ``` 21 | 22 | If you want to build the project on your host: 23 | 24 | ```bash 25 | $ jekyll build 26 | ``` 27 | 28 | If you want to preview the pages before building the Docker image : 29 | 30 | ```bash 31 | $ jekyll serve 32 | ``` 33 | 34 | Open [http://127.0.0.1:4000/](http://127.0.0.1:4000/). 35 | 36 | ## How to use with Traefik and Docker in Production 37 | 38 | Run the container with labels, **change with your needs**: 39 | 40 | ```yml 41 | # docker-compose.yml 42 | 43 | errorpage: 44 | image: guillaumebriday/traefik-custom-error-pages 45 | restart: unless-stopped 46 | networks: 47 | - web 48 | labels: 49 | - traefik.enable: "true" 50 | - traefik.docker.network: "web" 51 | - traefik.http.routers.errorpage.entrypoints: "websecure" 52 | - traefik.http.routers.errorpage.rule: "HostRegexp(`{host:.+}`)" 53 | - traefik.http.services.globalerrorpage.loadbalancer.server.port: "80" 54 | ``` 55 | 56 | ## Build the image 57 | 58 | This is a [multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/), to build the final image: 59 | 60 | ```bash 61 | $ docker build -f .cloud/docker/Dockerfile -t traefik-custom-error-pages . 62 | ``` 63 | 64 | ## How it works? 65 | 66 | As you can see in the Dockerfile, I use [Nginx](https://www.nginx.com/) as Web server to serve static files. To generate this pages, I use [Jekyll](https://jekyllrb.com/) in the first step of the build. 67 | 68 | You will find in this article [https://www.techjunktrunk.com/docker/2017/11/03/traefik-default-server-catch-all](https://www.techjunktrunk.com/docker/2017/11/03/traefik-default-server-catch-all/) why I set up `rule` this way. 69 | 70 | It's very useful because this container will respond to all requests only if there is no container with a real rule. 71 | 72 | ## Credits 73 | 74 | I used the [Laravel](https://laravel.com/) default HTTP error pages. 75 | 76 | ## Contributing 77 | 78 | Do not hesitate to contribute to the project by adapting or adding features ! Bug reports or pull requests are welcome. 79 | 80 | ## License 81 | 82 | This project is released under the [MIT](http://opensource.org/licenses/MIT) license. 83 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Jekyll! 2 | # 3 | # This config file is meant for settings that affect your whole blog, values 4 | # which you are expected to set up once and rarely edit after that. If you find 5 | # yourself editing this file very often, consider using Jekyll's data files 6 | # feature for the data you need to update frequently. 7 | # 8 | # For technical reasons, this file is *NOT* reloaded automatically when you use 9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process. 10 | 11 | # Site settings 12 | # These are used to personalize your new site. If you look in the HTML files, 13 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. 14 | # You can create any custom variable you would like, and they will be accessible 15 | # in the templates via {{ site.myvariable }}. 16 | baseurl: "" # the subpath of your site, e.g. /blog 17 | url: "" # the base hostname & protocol for your site, e.g. http://example.com 18 | 19 | # Build settings 20 | markdown: kramdown 21 | 22 | plugins: 23 | - octopress-minify-html 24 | - jekyll-assets 25 | 26 | # Exclude from processing. 27 | # The following items will not be processed, by default. Create a custom list 28 | # to override the default setting. 29 | exclude: 30 | - Gemfile 31 | - Gemfile.lock 32 | - LICENSE 33 | - feed.xml 34 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ page.title }} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% asset application.css @inline %} 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | {{ page.code }} 22 |
23 | 24 |
25 | 26 |

27 | {{ content }} 28 |

29 |
30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /assets/css/application.css: -------------------------------------------------------------------------------- 1 | html { 2 | line-height: 1.15; 3 | -ms-text-size-adjust: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | } 6 | 7 | body { 8 | margin: 0; 9 | } 10 | 11 | header, 12 | nav, 13 | section { 14 | display: block; 15 | } 16 | 17 | figcaption, 18 | main { 19 | display: block; 20 | } 21 | 22 | a { 23 | background-color: transparent; 24 | -webkit-text-decoration-skip: objects; 25 | } 26 | 27 | strong { 28 | font-weight: inherit; 29 | } 30 | 31 | strong { 32 | font-weight: bolder; 33 | } 34 | 35 | code { 36 | font-family: monospace, monospace; 37 | font-size: 1em; 38 | } 39 | 40 | dfn { 41 | font-style: italic; 42 | } 43 | 44 | svg:not(:root) { 45 | overflow: hidden; 46 | } 47 | 48 | button, 49 | input { 50 | font-family: sans-serif; 51 | font-size: 100%; 52 | line-height: 1.15; 53 | margin: 0; 54 | } 55 | 56 | button, 57 | input { 58 | overflow: visible; 59 | } 60 | 61 | button { 62 | text-transform: none; 63 | } 64 | 65 | button, 66 | html [type="button"], 67 | [type="reset"], 68 | [type="submit"] { 69 | -webkit-appearance: button; 70 | } 71 | 72 | button::-moz-focus-inner, 73 | [type="button"]::-moz-focus-inner, 74 | [type="reset"]::-moz-focus-inner, 75 | [type="submit"]::-moz-focus-inner { 76 | border-style: none; 77 | padding: 0; 78 | } 79 | 80 | button:-moz-focusring, 81 | [type="button"]:-moz-focusring, 82 | [type="reset"]:-moz-focusring, 83 | [type="submit"]:-moz-focusring { 84 | outline: 1px dotted ButtonText; 85 | } 86 | 87 | legend { 88 | -webkit-box-sizing: border-box; 89 | box-sizing: border-box; 90 | color: inherit; 91 | display: table; 92 | max-width: 100%; 93 | padding: 0; 94 | white-space: normal; 95 | } 96 | 97 | [type="checkbox"], 98 | [type="radio"] { 99 | -webkit-box-sizing: border-box; 100 | box-sizing: border-box; 101 | padding: 0; 102 | } 103 | 104 | [type="number"]::-webkit-inner-spin-button, 105 | [type="number"]::-webkit-outer-spin-button { 106 | height: auto; 107 | } 108 | 109 | [type="search"] { 110 | -webkit-appearance: textfield; 111 | outline-offset: -2px; 112 | } 113 | 114 | [type="search"]::-webkit-search-cancel-button, 115 | [type="search"]::-webkit-search-decoration { 116 | -webkit-appearance: none; 117 | } 118 | 119 | ::-webkit-file-upload-button { 120 | -webkit-appearance: button; 121 | font: inherit; 122 | } 123 | 124 | menu { 125 | display: block; 126 | } 127 | 128 | canvas { 129 | display: inline-block; 130 | } 131 | 132 | template { 133 | display: none; 134 | } 135 | 136 | [hidden] { 137 | display: none; 138 | } 139 | 140 | html { 141 | -webkit-box-sizing: border-box; 142 | box-sizing: border-box; 143 | font-family: sans-serif; 144 | } 145 | 146 | *, 147 | *::before, 148 | *::after { 149 | -webkit-box-sizing: inherit; 150 | box-sizing: inherit; 151 | } 152 | 153 | p { 154 | margin: 0; 155 | } 156 | 157 | button { 158 | background: transparent; 159 | padding: 0; 160 | } 161 | 162 | button:focus { 163 | outline: 1px dotted; 164 | outline: 5px auto -webkit-focus-ring-color; 165 | } 166 | 167 | *, 168 | *::before, 169 | *::after { 170 | border-width: 0; 171 | border-style: solid; 172 | border-color: #dae1e7; 173 | } 174 | 175 | button, 176 | [type="button"], 177 | [type="reset"], 178 | [type="submit"] { 179 | border-radius: 0; 180 | } 181 | 182 | button, 183 | input { 184 | font-family: inherit; 185 | } 186 | 187 | input::-webkit-input-placeholder { 188 | color: inherit; 189 | opacity: .5; 190 | } 191 | 192 | input:-ms-input-placeholder { 193 | color: inherit; 194 | opacity: .5; 195 | } 196 | 197 | input::-ms-input-placeholder { 198 | color: inherit; 199 | opacity: .5; 200 | } 201 | 202 | input::placeholder { 203 | color: inherit; 204 | opacity: .5; 205 | } 206 | 207 | button, 208 | [role=button] { 209 | cursor: pointer; 210 | } 211 | 212 | .bg-transparent { 213 | background-color: transparent; 214 | } 215 | 216 | .bg-white { 217 | background-color: #fff; 218 | } 219 | 220 | .bg-teal-light { 221 | background-color: #64d5ca; 222 | } 223 | 224 | .bg-blue-dark { 225 | background-color: #2779bd; 226 | } 227 | 228 | .bg-indigo-light { 229 | background-color: #7886d7; 230 | } 231 | 232 | .bg-purple-light { 233 | background-color: #a779e9; 234 | } 235 | 236 | .bg-no-repeat { 237 | background-repeat: no-repeat; 238 | } 239 | 240 | .bg-cover { 241 | background-size: cover; 242 | } 243 | 244 | .border-grey-light { 245 | border-color: #dae1e7; 246 | } 247 | 248 | .hover\:border-grey:hover { 249 | border-color: #b8c2cc; 250 | } 251 | 252 | .rounded-lg { 253 | border-radius: .5rem; 254 | } 255 | 256 | .border-2 { 257 | border-width: 2px; 258 | } 259 | 260 | .hidden { 261 | display: none; 262 | } 263 | 264 | .flex { 265 | display: -webkit-box; 266 | display: -ms-flexbox; 267 | display: flex; 268 | } 269 | 270 | .items-center { 271 | -webkit-box-align: center; 272 | -ms-flex-align: center; 273 | align-items: center; 274 | } 275 | 276 | .justify-center { 277 | -webkit-box-pack: center; 278 | -ms-flex-pack: center; 279 | justify-content: center; 280 | } 281 | 282 | .font-sans { 283 | font-family: Nunito, sans-serif; 284 | } 285 | 286 | .font-light { 287 | font-weight: 300; 288 | } 289 | 290 | .font-bold { 291 | font-weight: 700; 292 | } 293 | 294 | .font-black { 295 | font-weight: 900; 296 | } 297 | 298 | .h-1 { 299 | height: .25rem; 300 | } 301 | 302 | .leading-normal { 303 | line-height: 1.5; 304 | } 305 | 306 | .m-8 { 307 | margin: 2rem; 308 | } 309 | 310 | .my-3 { 311 | margin-top: .75rem; 312 | margin-bottom: .75rem; 313 | } 314 | 315 | .mb-8 { 316 | margin-bottom: 2rem; 317 | } 318 | 319 | .max-w-sm { 320 | max-width: 30rem; 321 | } 322 | 323 | .min-h-screen { 324 | min-height: 100vh; 325 | } 326 | 327 | .py-3 { 328 | padding-top: .75rem; 329 | padding-bottom: .75rem; 330 | } 331 | 332 | .px-6 { 333 | padding-left: 1.5rem; 334 | padding-right: 1.5rem; 335 | } 336 | 337 | .pb-full { 338 | padding-bottom: 100%; 339 | } 340 | 341 | .absolute { 342 | position: absolute; 343 | } 344 | 345 | .relative { 346 | position: relative; 347 | } 348 | 349 | .pin { 350 | top: 0; 351 | right: 0; 352 | bottom: 0; 353 | left: 0; 354 | } 355 | 356 | .text-black { 357 | color: #22292f; 358 | } 359 | 360 | .text-grey-darkest { 361 | color: #3d4852; 362 | } 363 | 364 | .text-grey-darker { 365 | color: #606f7b; 366 | } 367 | 368 | .text-2xl { 369 | font-size: 1.5rem; 370 | } 371 | 372 | .text-5xl { 373 | font-size: 3rem; 374 | } 375 | 376 | .uppercase { 377 | text-transform: uppercase; 378 | } 379 | 380 | .antialiased { 381 | -webkit-font-smoothing: antialiased; 382 | -moz-osx-font-smoothing: grayscale; 383 | } 384 | 385 | .tracking-wide { 386 | letter-spacing: .05em; 387 | } 388 | 389 | .w-16 { 390 | width: 4rem; 391 | } 392 | 393 | .w-full { 394 | width: 100%; 395 | } 396 | 397 | @media (min-width: 768px) { 398 | .md\:bg-left { 399 | background-position: left; 400 | } 401 | 402 | .md\:bg-right { 403 | background-position: right; 404 | } 405 | 406 | .md\:flex { 407 | display: -webkit-box; 408 | display: -ms-flexbox; 409 | display: flex; 410 | } 411 | 412 | .md\:my-6 { 413 | margin-top: 1.5rem; 414 | margin-bottom: 1.5rem; 415 | } 416 | 417 | .md\:min-h-screen { 418 | min-height: 100vh; 419 | } 420 | 421 | .md\:pb-0 { 422 | padding-bottom: 0; 423 | } 424 | 425 | .md\:text-3xl { 426 | font-size: 1.875rem; 427 | } 428 | 429 | .md\:text-15xl { 430 | font-size: 9rem; 431 | } 432 | 433 | .md\:w-1\/2 { 434 | width: 50%; 435 | } 436 | } 437 | 438 | @media (min-width: 992px) { 439 | .lg\:bg-center { 440 | background-position: center; 441 | } 442 | } 443 | -------------------------------------------------------------------------------- /assets/img/403.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/img/404.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/img/500.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/503.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "jekyll build" 3 | publish = "_site/" 4 | 5 | [build.environment] 6 | CI = "true" 7 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | User-agent: * 5 | Disallow: / 6 | --------------------------------------------------------------------------------