├── CNAME ├── requirements.txt ├── favicon.png ├── img ├── tube.png ├── logo-2x.png ├── tube1x.png ├── octojekyll.png ├── footer-arrow.png ├── footer-logo.png └── article-footer.png ├── README.md ├── .gitignore ├── _config.yml ├── _layouts ├── default.html └── docs.html ├── Makefile ├── Gemfile ├── _includes ├── primary-nav-items.html ├── footer.html ├── header.html ├── section_nav.html ├── top.html ├── docs_contents_mobile.html ├── analytics.html └── docs_contents.html ├── docs ├── index.md ├── app-design-rules.md ├── settings-and-requirements.md ├── how-to-contribute.md ├── project-layout.md └── coding-style.md ├── LICENSE ├── Gemfile.lock ├── index.html ├── css ├── gridism.css ├── pygments.css ├── normalize.css └── style.css └── js └── modernizr-2.5.3.min.js /CNAME: -------------------------------------------------------------------------------- 1 | dbp.lenciel.com 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Pygments==2.1.1 2 | -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/favicon.png -------------------------------------------------------------------------------- /img/tube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/tube.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | django-notes 2 | ==================== 3 | 4 | django best practice notes 5 | -------------------------------------------------------------------------------- /img/logo-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/logo-2x.png -------------------------------------------------------------------------------- /img/tube1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/tube1x.png -------------------------------------------------------------------------------- /img/octojekyll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/octojekyll.png -------------------------------------------------------------------------------- /img/footer-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/footer-arrow.png -------------------------------------------------------------------------------- /img/footer-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/footer-logo.png -------------------------------------------------------------------------------- /img/article-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lenciel/django-notes/HEAD/img/article-footer.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /serve/ 2 | /_site/ 3 | /build/ 4 | 5 | /npm-debug.log 6 | /.idea/ 7 | .UlyssesRoot 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | highlighter: pygments 2 | relative_permalinks: false 3 | #url: https://dbp.lenciel.com 4 | google_analytics_id: UA-175991-3 5 | markdown: kramdown 6 | kramdown: 7 | auto_ids: true 8 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | {% include top.html %} 2 | 3 | 4 | {% include header.html %} 5 | 6 | {{ content }} 7 | 8 | {% include footer.html %} 9 | {% include analytics.html %} 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: update 2 | 3 | preview: 4 | jekyll build && jekyll serve --watch --host=172.16.121.110 5 | 6 | update: 7 | jekyll build && \ 8 | git checkout gh-pages 9 | git add .; \ 10 | git commit -am "site update $$(date +%Y-%m-%d)"; \ 11 | git push origin gh-pages 12 | 13 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | ruby '2.4.0' 3 | 4 | # Hello! This is where you manage which Jekyll version is used to run. 5 | # When you want to use a different version, change it below, save the 6 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 7 | # 8 | # bundle exec jekyll serve 9 | # 10 | # This will help ensure the proper Jekyll version is running. 11 | # Happy Jekylling! 12 | gem "jekyll" 13 | gem "pygments.rb" 14 | -------------------------------------------------------------------------------- /_layouts/docs.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 | 8 | {% include docs_contents_mobile.html %} 9 | 10 |
11 |
12 |

{{ page.title }}

13 | {{ content }} 14 | {% include section_nav.html %} 15 |
16 |
17 | 18 | {% include docs_contents.html %} 19 | 20 |
21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /_includes/primary-nav-items.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /_includes/header.html: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 14 | 17 |
18 |
19 | -------------------------------------------------------------------------------- /_includes/section_nav.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {% if page.prev_section != null %} 4 | 7 | {% else %} 8 | 上一页 9 | {% endif %} 10 |
11 |
12 | {% if page.next_section != null %} 13 | 16 | {% else %} 17 | 下一页 18 | {% endif %} 19 |
20 |
21 |
22 | 23 | -------------------------------------------------------------------------------- /_includes/top.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ page.title }} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /_includes/docs_contents_mobile.html: -------------------------------------------------------------------------------- 1 |
2 | 21 |
22 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: 欢迎 4 | next_section: coding-style 5 | permalink: /docs/home/ 6 | --- 7 | 8 | 如果你想把自己从Django初学者提升到另外一个档次,一个很不错的途径就是学习和整理自己和其他人使用Django的最佳实践。 9 | 10 | ## Django是什么? 11 | 12 | 如果你还有这方面的疑问,可能还不太适合现在就开始阅读最佳实践相关的文档。可以先去看看 [官方的文档](https://docs.djangoproject.com/en/1.5/) ,自己动手做一两个项目,体会以下Django这个框架再来。 13 | 14 | ## Django最佳实践是什么? 15 | 16 | 和 [官方的文档](https://docs.djangoproject.com/en/1.5/) 不同,最佳实践主要入手点是结合具体的使用场景,描述并推荐具体的编码风格、开发模式、解决方案等。这些最佳实践来源于其他人的经验和ZooM Xerus团队自己的项目实践,并且会不断地被继续使用并演进,所以这个文档也会不断地修改。 17 | 18 | ## ProTips™, Notes, 和 Warnings 19 | 20 | 在这个最佳实践的文档里面,我们使用以下标记来给出一些我们特别想highlight的东西: 21 | 22 |
23 |
ProTips™ 来源于经验
24 |

帮助你更好的使用Django的小技巧!

25 |
26 | 27 |
28 |
Notes 来源于深度理解
29 |

帮助你深入理解Django的一些信息。

30 |
31 | 32 |
33 |
Warnings 来源于教训
34 |

帮助你避免掉进坑里的一些提示。

35 |
36 | 37 | 如果你发现有什么没有讲到的地方,或者有任何问题,可以 [提交一个issue](https://github.com/lenciel/django-notes/issues/new) 给我们。 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Lenciel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /_includes/analytics.html: -------------------------------------------------------------------------------- 1 | {% if site.gauges_id %} 2 | 3 | 16 | {% endif %} 17 | 18 | {% if site.google_analytics_id %} 19 | 20 | 29 | {% endif %} 30 | -------------------------------------------------------------------------------- /_includes/docs_contents.html: -------------------------------------------------------------------------------- 1 |
2 | 37 |
38 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.5.1) 5 | public_suffix (~> 2.0, >= 2.0.2) 6 | colorator (1.1.0) 7 | ffi (1.9.18) 8 | forwardable-extended (2.6.0) 9 | jekyll (3.4.3) 10 | addressable (~> 2.4) 11 | colorator (~> 1.0) 12 | jekyll-sass-converter (~> 1.0) 13 | jekyll-watch (~> 1.1) 14 | kramdown (~> 1.3) 15 | liquid (~> 3.0) 16 | mercenary (~> 0.3.3) 17 | pathutil (~> 0.9) 18 | rouge (~> 1.7) 19 | safe_yaml (~> 1.0) 20 | jekyll-sass-converter (1.5.0) 21 | sass (~> 3.4) 22 | jekyll-watch (1.5.0) 23 | listen (~> 3.0, < 3.1) 24 | kramdown (1.13.2) 25 | liquid (3.0.6) 26 | listen (3.0.8) 27 | rb-fsevent (~> 0.9, >= 0.9.4) 28 | rb-inotify (~> 0.9, >= 0.9.7) 29 | mercenary (0.3.6) 30 | multi_json (1.12.1) 31 | pathutil (0.14.0) 32 | forwardable-extended (~> 2.6) 33 | public_suffix (2.0.5) 34 | pygments.rb (1.1.1) 35 | multi_json (>= 1.0.0) 36 | rb-fsevent (0.9.8) 37 | rb-inotify (0.9.8) 38 | ffi (>= 0.5.0) 39 | rouge (1.11.1) 40 | safe_yaml (1.0.4) 41 | sass (3.4.23) 42 | 43 | PLATFORMS 44 | ruby 45 | 46 | DEPENDENCIES 47 | jekyll 48 | pygments.rb 49 | 50 | RUBY VERSION 51 | ruby 2.4.0p0 52 | 53 | BUNDLED WITH 54 | 1.14.6 55 | -------------------------------------------------------------------------------- /docs/app-design-rules.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: App设计准则 4 | prev_section: project-layout 5 | next_section: settings-and-requirements 6 | permalink: /docs/app-design-rules/ 7 | --- 8 | 9 | 初学Django常见的一个问题就是什么是"app"。 10 | 11 | - 一个 `Django project` 是指使用Django框架开发的一个完整的web应用。 12 | - 一个 `Django app` 是指Django project下的一个具体的模块。每个Django project都有多个app,其中一部分app是内部使用的,其他的是可以被别的project重用的。 13 | - 一个 `Third-party Django package` 是指第三方开发的即插即用的Django app。所谓即插即用通常是指该app使用了Python的打包工具打包,可以直接通过pip安装和使用。 14 | 15 | ## Django App设计的基本准则 16 | 17 | James Bennett,Django的release manager和core developer说过: 18 | 19 | 20 | >“The art of a creating and maintaining a good Django app is that it should follow 21 | the truncated Unix philosophy according to Douglas McIlroy: 22 | >‘Write programs that do one thing and do it well.’” 23 | 24 | 也就是说,每个app应该聚焦并完成一个特定的功能点。如果一个app的作用不能用一句话说明白,可能它就需要被拆分成更小的app。 25 | 26 | ## Django App的命名准则 27 | 28 | 由于前面的基本准则的设计思想,推荐简单的app命名使用单个单词:一般来说就是这个模块的model的复数即可。很多时候,由于app是一个完整的功能模块,包含的model可能很多,这个时候反而用单数来命名app表示它是一个集合比较合适,比如一个叫blog的app。 29 | 30 | 另外,注意命名的时候不仅需要考虑model的名字,还需要考虑url的pattern。如果你希望你的博客访问地址是`http://www.example.com/weblog`,那么对应的app就应该叫weblog而不是blog或者posts,即使这个app的主要的model就是POST。这样做可以让你在维护项目的时候很方便地确定哪个app对应哪个入口。 31 | 32 | app的命名如果超过一个单词,就要注意符合[PEP-8规范](http://www.python.org/dev/peps/pep-0008/),因为app其实说白了就是一个Python的package,它的命名应该都使用小写字母,单词之间用下划线隔开,不能使用数字、空格、斜杠等特殊符号。 33 | 34 | ## 让App变小 35 | 36 | 在项目开始阶段不需要纠结于追求完美的app设计:it's an art, not science。很多时候你都会在项目过程中重命名或者打散app,这很正常。你只需要有一个基本的思路:让app变小。一个由很多app组成的project通常是好设计的表现,相反如果一个app非常的臃肿,那多半是设计上出现了问题。 -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Django Best Practice by ZooM Xerus Team. 4 | overview: true 5 | --- 6 | 7 |
8 |
9 |
10 |

Django最佳实践

11 |
12 |
13 |
14 |
15 |
16 |
17 |

18 | 如何使用Django Web Framework进行开发和部署。 19 |

20 | 什么是Django → 21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |

贡献你的内容 非常简单:

29 |

详细指引请参考 30 | 如何贡献内容 → 31 |

32 |
33 |
34 |

Quick start is quick:

35 |
36 |

37 | ~ 38 | $ 39 | gem install jekyll 40 |

41 |

42 | ~ 43 | $ 44 | git clone git@github.com:lenciel/django-notes.git 45 |

46 |

47 | ~ 48 | $ 49 | cd django-notes/site 50 |

51 |

52 | ~/site 53 | $ 54 | jekyll serve --watch 55 |

56 |

57 | # => 打开浏览器浏览 http://localhost:4000 58 |

59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Free Jekyll hosting on GitHub Pages 70 |
71 |

Jekyll站点可以直接部署到GitHub Pages

72 |

使用GitHub Pages 可以host任何使用 Jekyll编写的站点,你可以部署站点到Github甚至还可以为这些站点绑定自己的域名

73 | 什么是GitHub Pages → 74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | -------------------------------------------------------------------------------- /docs/settings-and-requirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: 配置文件 4 | prev_section: app-design-rules 5 | next_section: home 6 | permalink: /docs/settings-and-requirements/ 7 | --- 8 | 9 | 这里所谓的配置文件主要指settings文件和requirements文件。 10 | 11 | Django 1.5有超过130项可以通过 `settings` 文件进行配置的选项。由于是在服务器启动的时候加载配置,所以大多数针对settings的修改需要在服务器重启后才能生效。一些相关的最佳实践是: 12 | 13 | - **所有的配置文件都应该版本控制** :特别是在production环境下使用的配置文件更是如此。 14 | - **DRY** : `Don't repeat yourself` ,也就是尽量把公共的配置项放到一个基础的配置文件里面,而不要在不同环境的配置文件里面拷来拷去。 15 | 16 | ## 避免使用不在代码库里面的本地配置 17 | 18 | 本地的开发环境不可避免的有些跟生产环境不同的配置,比如数据库连接,SECRET_KEY等等。 19 | 20 |
21 |
Warning:保护好你的秘密
22 |
23 |

在Django里面,`SECRET_KEY` 被用来进行加密签名,因此最好是不要放在代码库里面。使用一个对别人来说已知的 `SECRET_KEY` ,会使得很多Django提供的安全机制失效,造成严重的安全隐患。更多的详情,可以参考:官方文档

24 |
25 |

基于同样的理由,诸如数据库密码、AWS key、OAuth的token等信息,最好都不要放在代码仓库里面。

26 |
27 | 28 | 保存本地配置过去通行的做法就是创建一个 `local_settings.py` 文件。这个文件是针对具体机器创建的(可以是开发机也可以是产品机),并且故意没有放到代码库里面。这样做可能带来的问题有: 29 | 30 | * 每个机器都有一些没有被版本控制的代码 31 | * 因为有没有加入版本控制的代码,就意味着部署有手工流程,经常会发生配置文件拷错的情况 32 | * 同时,没有版本控制意味着每个开发人员都要手动同步这堆配置文件 33 | 34 | 更先进的做法是,为不同的环境编写不同的配置文件,同时仍然能保障具体环境的秘密仍然是秘密。 35 | 36 | ## 使用多个配置文件 37 | 38 |
39 |
ProTips™ 灵感来源于"The One True Way"
40 |
41 |

这种配置方式由Jacob Kaplan-Moss提出,并在OSCON 2011上以'The Best and Worst of Django'为题目的演讲中被提到。

42 |
43 | 44 | 和Django标准教程中使用单个settings.py不同,这种配置方式是创建一个settings/文件夹,然后在这个文件夹下面放置下面的这些配置文件: 45 | 46 | {% highlight bash %} 47 | settings/ 48 | __init__.py 49 | base.py 50 | local.py 51 | staging.py 52 | test.py 53 | production.py 54 | {% endhighlight %} 55 | 56 |
57 |
Warning:Requirements + Settings
58 |
59 |

每个settings文件对应一个环境,所以一般也有对应的requirements文件。

60 |
61 | 62 | 63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 76 | 79 | 80 | 81 | 84 | 87 | 88 | 89 | 92 | 95 | 96 | 97 | 100 | 103 | 104 | 105 | 108 | 111 | 112 | 113 |
Settings 文件用途
74 |

base.py

75 |
77 |

通用的配置

78 |
82 |

local.py

83 |
85 |

本地开发使用的配置。一般来说这种配置下 `DEBUG` 模式是打开的,又更多的日志,`django-debug-toolbar` 这类辅助app也是启用的

86 |
90 |

staging.py

91 |
93 |

Staging环境用来在部署生产环境之前给QA或者PO甚至是用户进行体验。同时有些团队也把Staging用来进行产品环境上出现的bug的调试

94 |
98 |

test.py

99 |
101 |

所有和测试有关的配置,比如test runner,内存数据库定义,log配置等

102 |
106 |

production.py

107 |
109 |

顾名思义用来放置生产环境的配置文件,有些时候被命名成prod.py

110 |
114 |
115 | 116 | -------------------------------------------------------------------------------- /css/gridism.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Gridism 3 | * A simple, responsive, and handy CSS grid by @cobyism 4 | * https://github.com/cobyism/gridism 5 | */ 6 | 7 | /* Preserve some sanity */ 8 | .grid, 9 | .unit { 10 | -webkit-box-sizing: border-box; 11 | -moz-box-sizing: border-box; 12 | box-sizing: border-box; 13 | } 14 | 15 | /* Set up some rules to govern the grid */ 16 | .grid { 17 | display: block; 18 | clear: both; 19 | } 20 | .grid .unit { 21 | float: left; 22 | width: 100%; 23 | padding: 10px; 24 | } 25 | 26 | /* This ensures the outer gutters are equal to the (doubled) inner gutters. */ 27 | .grid .unit:first-child { padding-left: 20px; } 28 | .grid .unit:last-child { padding-right: 20px; } 29 | 30 | /* Nested grids already have padding though, so let’s nuke it */ 31 | .unit .unit:first-child { padding-left: 0; } 32 | .unit .unit:last-child { padding-right: 0; } 33 | .unit .grid:first-child > .unit { padding-top: 0; } 34 | .unit .grid:last-child > .unit { padding-bottom: 0; } 35 | 36 | /* Let people nuke the gutters/padding completely in a couple of ways */ 37 | .no-gutters .unit, 38 | .unit.no-gutters { 39 | padding: 0 !important; 40 | } 41 | 42 | /* Wrapping at a maximum width is optional */ 43 | .wrap .grid, 44 | .grid.wrap { 45 | max-width: 978px; 46 | margin: 0 auto; 47 | } 48 | 49 | /* Width classes also have shorthand versions numbered as fractions 50 | * For example: for a grid unit 1/3 (one third) of the parent width, 51 | * simply apply class="w-1-3" to the element. */ 52 | .grid .whole, .grid .w-1-1 { width: 100%; } 53 | .grid .half, .grid .w-1-2 { width: 50%; } 54 | .grid .one-third, .grid .w-1-3 { width: 33.3332%; } 55 | .grid .two-thirds, .grid .w-2-3 { width: 66.6665%; } 56 | .grid .one-quarter, .grid .w-1-4 { width: 25%; } 57 | .grid .three-quarters, .grid .w-3-4 { width: 75%; } 58 | .grid .one-fifth, .grid .w-1-5 { width: 20%; } 59 | .grid .two-fifths, .grid .w-2-5 { width: 40%; } 60 | .grid .three-fifths, .grid .w-3-5 { width: 60%; } 61 | .grid .four-fifths, .grid .w-4-5 { width: 80%; } 62 | .grid .golden-small, .grid .w-g-s { width: 38.2716%; } /* Golden section: smaller piece */ 63 | .grid .golden-large, .grid .w-g-l { width: 61.7283%; } /* Golden section: larger piece */ 64 | 65 | /* Utility classes */ 66 | .align-center { text-align: center; } 67 | .align-left { text-align: left; } 68 | .align-right { text-align: right; } 69 | .pull-left { float: left; } 70 | .pull-right { float: right; } 71 | 72 | .show-on-mobiles { 73 | display: none; 74 | } 75 | 76 | /* Responsive Stuff */ 77 | @media screen and (max-width: 568px) { 78 | /* Stack anything that isn’t full-width on smaller screens */ 79 | .grid .unit { 80 | width: 100% !important; 81 | padding-left: 20px; 82 | padding-right: 20px; 83 | } 84 | .unit .grid .unit { 85 | padding-left: 0px; 86 | padding-right: 0px; 87 | } 88 | 89 | /* Sometimes, you just want to be different on small screens */ 90 | .center-on-mobiles { 91 | text-align: center !important; 92 | } 93 | .hide-on-mobiles { 94 | display: none !important; 95 | } 96 | .show-on-mobiles { 97 | display: block !important; 98 | } 99 | a .show-on-mobiles { 100 | display: inline !important; 101 | } 102 | } 103 | 104 | /* Expand the wrap a bit further on larger screens */ 105 | /*@media screen and (min-width: 1180px) { 106 | .wrap .grid { 107 | max-width: 1180px; 108 | margin: 0 auto; 109 | } 110 | }*/ 111 | -------------------------------------------------------------------------------- /docs/how-to-contribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: 如何贡献内容 4 | prev_section: project-layout 5 | permalink: /docs/how-to-contribute/ 6 | --- 7 | 8 | 你有自己的最佳实践想要分享或者是修订现有的内容?Great! 下面是一些你可能用得上的信息。 9 | 10 | Dependencies 11 | ------------- 12 | 13 | 要编译和查看这个Jekyll生成的站点,你需要安装Jekyll所需的依赖: 14 | 15 | {% highlight bash %} 16 | ~ $ gem install jekyll 17 | {% endhighlight %} 18 | 19 | 一个比较详细的Jekyll安装过程可以参考 [这里](http://lenciel.github.io/blog/2013/03/10/blog-with-octopress-and-github-pages/)。 20 | 21 | Workflow 22 | -------- 23 | 24 | 目前这个项目放在Github上,我们协作的最直接的方式当然是用Github的fork模式: 25 | 26 | * Fork本项目 27 | * Clone你自己的fork: 28 | 29 | {% highlight bash %} 30 | git clone git://github.com//django-notes.git 31 | {% endhighlight %} 32 | 33 | * 创建一个 `topic branch` 来放你的修改: 34 | 35 | {% highlight bash %} 36 | git checkout -b my_awesome_feature 37 | {% endhighlight %} 38 | 39 | * 修改后确保一切正常: 40 | 41 | {% highlight bash %} 42 | ~/django-notes $ cd site 43 | ~/django-notes/site $ jekyll serve --watch 44 | # => 查看 http://localhost:4000 45 | {% endhighlight %} 46 | 47 |
48 |
ProTips™ --watch参数
49 |

使用watch参数,jekyll项目会被自动build和部署,刷新浏览器即可查看修改后的效果。

50 |
51 | 52 | * 如果需要, `rebase` 你的 `commit` 。 53 | * `push` 这个 `branch` : 54 | 55 | {% highlight bash %} 56 | git push origin my_awesome_feature 57 | {% endhighlight %} 58 | 59 | * 创建一个 `pull request` 并简单描述你添加的部分。 60 | 61 |
62 |
提醒我们缺失或错误的部分!
63 |

64 | 如果你只是想提建议而不是直接编写文档,或者你发现的问题不是你编写的部分,可以提交一个 issue 给我们。 66 |

67 |
68 | 69 | 项目结构 70 | -------- 71 | 72 | Jekyll其实主要就是个文本转换的引擎。你把用你自己熟悉的markup语言(不管是Markdown还是Textile等)或者是HTML编写的页面交给它,它通过layout文件等配置文件定义的样子生成最终的静态网页。 73 | 74 | 我们的项目的site文件夹主要的结构如下: 75 | 76 | {% highlight bash %} 77 | . 78 | ├── _config.yml 79 | ├── _includes 80 | | ├── footer.html 81 | | └── header.html 82 | | └── ... 83 | ├── _layouts 84 | | ├── default.html 85 | | └── docs.html 86 | ├── _site 87 | ├── css 88 | ├── img 89 | ├── js 90 | └── index.html 91 | {% endhighlight %} 92 | 93 | 它们的用途简单归纳如下: 94 | 95 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 108 | 113 | 114 | 115 | 118 | 123 | 124 | 125 | 128 | 137 | 138 | 139 | 142 | 149 | 150 | 151 | 154 | 162 | 163 | 164 | 167 | 174 | 175 | 176 |
File / DirectoryDescription
106 |

_config.yml

107 |
109 |

110 | 保存全局配置。注意,如果你在本地调试的时候,需要把url这条配置注释掉。 111 |

112 |
116 |

_includes

117 |
119 |

120 | 可重用的页面或者部分页面。 121 |

122 |
126 |

_layouts

127 |
129 |

130 | 131 | 页面的模板。在 `_includes` 中定义的内容可以在模板中被使用, 132 | {% raw %}{{ content }}{% endraw %} 133 | 可以用来规定页面内容被插入到哪里。 134 | 135 |

136 |
140 |

_site

141 |
143 |

144 | 145 | Jekyll编译后生成的内容,一般加到 .gitignore 中。 146 | 147 |

148 |
152 |

index.html 和其他HTML, Markdown, Textile文件

153 |
155 |

156 | 157 | 任何在site根目录的.html.markdown、 158 | .md或者 .textile文件都会被Jekyll转换。 159 | 160 |

161 |
165 |

其他文件和目录

166 |
168 |

169 | 170 | 任何site根目录下的其他目录或者文件如cssimagesjs目录或者favicon.png文件, 会被直接拷贝到 `_site` 目录下。 171 | 172 |

173 |
177 |
178 | -------------------------------------------------------------------------------- /css/pygments.css: -------------------------------------------------------------------------------- 1 | /*.highlight { background: #333333; color: #ffffff}*/ 2 | .highlight .hll { background-color: #ffffcc } 3 | .highlight .c { color: #87ceeb} /* Comment */ 4 | .highlight .err { color: #ffffff} /* Error */ 5 | .highlight .g { color: #ffffff} /* Generic */ 6 | .highlight .k { color: #f0e68c} /* Keyword */ 7 | .highlight .l { color: #ffffff} /* Literal */ 8 | .highlight .n { color: #ffffff} /* Name */ 9 | .highlight .o { color: #ffffff} /* Operator */ 10 | .highlight .x { color: #ffffff} /* Other */ 11 | .highlight .p { color: #ffffff} /* Punctuation */ 12 | .highlight .cm { color: #87ceeb} /* Comment.Multiline */ 13 | .highlight .cp { color: #cd5c5c} /* Comment.Preproc */ 14 | .highlight .c1 { color: #87ceeb} /* Comment.Single */ 15 | .highlight .cs { color: #87ceeb} /* Comment.Special */ 16 | .highlight .gd { color: #0000c0; font-weight: bold; background-color: #008080 } /* Generic.Deleted */ 17 | .highlight .ge { color: #c000c0; text-decoration: underline} /* Generic.Emph */ 18 | .highlight .gr { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Error */ 19 | .highlight .gh { color: #cd5c5c} /* Generic.Heading */ 20 | .highlight .gi { color: #ffffff; background-color: #0000c0 } /* Generic.Inserted */ 21 | .highlight span.go { color: #add8e6; font-weight: bold; background-color: #4d4d4d } /* Generic.Output, qualified with span to prevent applying this style to the Go language, see #1153. */ 22 | .highlight .gp { color: #ffffff} /* Generic.Prompt */ 23 | .highlight .gs { color: #ffffff} /* Generic.Strong */ 24 | .highlight .gu { color: #cd5c5c} /* Generic.Subheading */ 25 | .highlight .gt { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Traceback */ 26 | .highlight .kc { color: #f0e68c} /* Keyword.Constant */ 27 | .highlight .kd { color: #f0e68c} /* Keyword.Declaration */ 28 | .highlight .kn { color: #f0e68c} /* Keyword.Namespace */ 29 | .highlight .kp { color: #f0e68c} /* Keyword.Pseudo */ 30 | .highlight .kr { color: #f0e68c} /* Keyword.Reserved */ 31 | .highlight .kt { color: #bdb76b} /* Keyword.Type */ 32 | .highlight .ld { color: #ffffff} /* Literal.Date */ 33 | .highlight .m { color: #ffffff} /* Literal.Number */ 34 | .highlight .s { color: #ffffff} /* Literal.String */ 35 | .highlight .na { color: #ffffff} /* Name.Attribute */ 36 | .highlight .nb { color: #ffffff} /* Name.Builtin */ 37 | .highlight .nc { color: #ffffff} /* Name.Class */ 38 | .highlight .no { color: #ffa0a0} /* Name.Constant */ 39 | .highlight .nd { color: #ffffff} /* Name.Decorator */ 40 | .highlight .ni { color: #ffdead} /* Name.Entity */ 41 | .highlight .ne { color: #ffffff} /* Name.Exception */ 42 | .highlight .nf { color: #ffffff} /* Name.Function */ 43 | .highlight .nl { color: #ffffff} /* Name.Label */ 44 | .highlight .nn { color: #ffffff} /* Name.Namespace */ 45 | .highlight .nx { color: #ffffff} /* Name.Other */ 46 | .highlight .py { color: #ffffff} /* Name.Property */ 47 | .highlight .nt { color: #f0e68c} /* Name.Tag */ 48 | .highlight .nv { color: #98fb98} /* Name.Variable */ 49 | .highlight .ow { color: #ffffff} /* Operator.Word */ 50 | .highlight .w { color: #ffffff} /* Text.Whitespace */ 51 | .highlight .mf { color: #ffffff} /* Literal.Number.Float */ 52 | .highlight .mh { color: #ffffff} /* Literal.Number.Hex */ 53 | .highlight .mi { color: #ffffff} /* Literal.Number.Integer */ 54 | .highlight .mo { color: #ffffff} /* Literal.Number.Oct */ 55 | .highlight .sb { color: #ffffff} /* Literal.String.Backtick */ 56 | .highlight .sc { color: #ffffff} /* Literal.String.Char */ 57 | .highlight .sd { color: #ffffff} /* Literal.String.Doc */ 58 | .highlight .s2 { color: #ffffff} /* Literal.String.Double */ 59 | .highlight .se { color: #ffffff} /* Literal.String.Escape */ 60 | .highlight .sh { color: #ffffff} /* Literal.String.Heredoc */ 61 | .highlight .si { color: #ffffff} /* Literal.String.Interpol */ 62 | .highlight .sx { color: #ffffff} /* Literal.String.Other */ 63 | .highlight .sr { color: #ffffff} /* Literal.String.Regex */ 64 | .highlight .s1 { color: #ffffff} /* Literal.String.Single */ 65 | .highlight .ss { color: #ffffff} /* Literal.String.Symbol */ 66 | .highlight .bp { color: #ffffff} /* Name.Builtin.Pseudo */ 67 | .highlight .vc { color: #98fb98} /* Name.Variable.Class */ 68 | .highlight .vg { color: #98fb98} /* Name.Variable.Global */ 69 | .highlight .vi { color: #98fb98} /* Name.Variable.Instance */ 70 | .highlight .il { color: #ffffff} /* Literal.Number.Integer.Long */ 71 | -------------------------------------------------------------------------------- /docs/project-layout.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: 项目布局 4 | prev_section: coding-style 5 | next_section: app-design-rules 6 | permalink: /docs/project-layout/ 7 | --- 8 | 9 | ## 概览 10 | 11 | 大多数Django的项目布局都是互不相同的。出现这种情况的原因是,一方面,Django默认的项目布局不被大家普遍接受:它过分强调简单性,使得对较大规模的Django项目的维护变得困难;另一方面,因为默认的项目布局没有成为标准,究竟什么样的项目布局更好成了仁者见仁智者见智的事情,大家都有了各自的最佳实践。当然,无论各自的最佳实践究竟是什么,都可以从默认的布局入手,分析可以改进的部分,得到符合自己需要的布局。 12 | 13 | ## Django 1.5的默认布局 14 | 15 | 建立一个Django 1.5的项目就可以看到它的默认布局: 16 | 17 | {% highlight bash %} 18 | $ workon django 19 | $ django-admin.py startproject mysite 20 | $ cd mysite 21 | $ tree . 22 | {% endhighlight %} 23 | 24 |
25 |
workon django激活了一个virtualenv
26 |

27 | 更多关于virtualenv的话题见这里。 28 |

29 |
30 | 31 | 命令 `tree .` 的输出如下: 32 | 33 | {% highlight bash %} 34 | . 35 | |____manage.py 36 | |____mysite 37 | | |______init__.py 38 | | |____settings.py 39 | | |____urls.py 40 | | |____wsgi.py 41 | {% endhighlight %} 42 | 43 | 如果再创建一个自定义的app之后,会增加一些文件: 44 | 45 | {% highlight bash %} 46 | $ django-admin.py startapp my_app 47 | $ tree . 48 | . 49 | |____manage.py 50 | |____my_app 51 | | |______init__.py 52 | | |____models.py 53 | | |____tests.py 54 | | |____views.py 55 | |____mysite 56 | | |______init__.py 57 | | |____settings.py 58 | | |____urls.py 59 | | |____wsgi.py 60 | {% endhighlight %} 61 | 62 | ## 改进一:管理依赖 63 | 64 | 首先,在根目录放置一个 `requirements.txt` 文件,然后创建一个 `requirments` 目录来放对应各种场景的具体依赖: 65 | 66 | {% highlight bash %} 67 | $ touch requirements.txt 68 | $ mkdir requirements 69 | $ touch requirements/{base.txt,local.txt,production.txt,test.txt} 70 | $ tree . 71 | . 72 | |____manage.py 73 | |____my_app 74 | | |______init__.py 75 | | |____models.py 76 | | |____tests.py 77 | | |____views.py 78 | |____mysite 79 | | |______init__.py 80 | | |____settings.py 81 | | |____urls.py 82 | | |____wsgi.py 83 | |____requirement.txt 84 | | |____requirements 85 | | | |____base.txt 86 | | | |____local.txt 87 | | | |____production.txt 88 | | | |____test.txt 89 | {% endhighlight %} 90 | 91 | 顶层的 `requirements.txt` 只是引用具体的某个文件:通常是 `production.txt`。 `base.txt` 里面放一些公共的依赖,比如Django。 `local.txt` 和 `production.txt` 分别放本地开发的依赖和实际部署的依赖。 `test.txt` 放测试所需的依赖。这样分割有显而易见的好处:如果你在开发环境里使用的是sqlite,那么就不需要安装部署环境中跟mysql有关的依赖了。除此之外,分割依赖到多个文件中还可以: 92 | 93 | 97 | 98 |
99 |
为什么在顶层目录要放一个仅仅是引用其他文件的requirements.txt
100 |

101 | 这是因为在流行的部署环境如Heroku等要求项目的根目录必须有一个 `requirements.txt` 文件。 102 |

103 |
104 | 105 | ## 改进二:优化Applications和Libraries的布局 106 | 107 | Django项目的组成单位是 `apps` 。有一些 `app` 没有 `model` , `views` 而是简单的提供功能的函数或者manangement命令或者是自定义的 `templatetags` , 这些 `app` 被称为 `helpers` 或者 `libraries` 。 108 | 109 | 优化项目的布局,主要是通过把 `app` 放到 `apps`下面,把 `library` 放到 `libraries` 下面,结合 [前面](/docs/coding-style/) 提到的相对路径导入: 110 | 111 | {% highlight bash %} 112 | ... 113 | | | | |____apps 114 | | | | | |______init__.py 115 | | | | |____libs 116 | | | | | |______init__.py 117 | ... 118 | {% endhighlight %} 119 | 120 | 这样布局的好处在于: 121 | 122 | - 可以方便的找到并重用你自己写的一个 `app` 123 | - 可以方便的找到并重用你自己写的一个 `library` 124 | 125 | ## 改进三:优化Settings 126 | 127 | 关于项目布局的最佳实践争论最多的地方就是Django的 `settings` 模块。我们抛弃了系统自动生成的 `settings.py` ,参考依赖的管理方式,生成了各个场景对应的配置文件: 128 | 129 | {% highlight bash %} 130 | ... 131 | | | | |____settings 132 | | | | | |______init__.py 133 | | | | | |____base.py 134 | | | | | |____local.py 135 | | | | | |____production.py 136 | | | | | |____test.py 137 | ... 138 | {% endhighlight %} 139 | 140 | 这样布局主要是考虑: 141 | 147 | 148 | ## 改进四:资源文件 149 | 150 | 项目的资源文件放在static文件夹下,目前默认包括了 `bootstrap` 相关文件: 151 | 152 | {% highlight bash %} 153 | ... 154 | | | |____static 155 | | | | |____css 156 | | | | | |____bootstrap-responsive.min.css 157 | | | | | |____bootstrap.min.css 158 | | | | | |____project.css 159 | | | | |____img 160 | | | | | |____glyphicons-halflings-white.png 161 | | | | | |____glyphicons-halflings.png 162 | | | | |____js 163 | | | | | |____bootstrap.min.js 164 | | | | | |____project.js 165 | ... 166 | {% endhighlight %} 167 | 168 | 目前项目放在 [django-zoomteam-template](http://gitlab.zoomteam.cn/django-zoomteam-template) ,使用这个模板的具体方法可以看该项目的说明。 169 | -------------------------------------------------------------------------------- /docs/coding-style.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: 编码规范 4 | next_section: project-layout 5 | prev_section: home 6 | permalink: /docs/coding-style/ 7 | --- 8 | 9 | Python的 [The Zen of Python (PEP 20)](http://www.python.org/dev/peps/pep-0020/) 是Python编码的最佳实践的浓缩。在编写Django项目的代码时,我们要求: 10 | 11 | - 尽量合理地遵守 [Style Guide for Python Code(PEP8)](http://www.python.org/dev/peps/pep-0008/) 12 | - 遵守 [Django coding style](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/) 13 | 14 | ## PEP8 15 | 16 | PEP8作为Python官方的编程规范,对命名、缩进、注释等各个方面都有详细的规定。代码提交review之前,所有的文件都应该符合PEP8要求(如果你记不住那些规则,找一个你使用的IDE的插件来检验)。每次代码提交之后,我们的Jenkins上也有PEP8的检查。如果不幸(不幸是指,违反PEP8的文件都不应该上传到代码库)发现了PEP8的violation,要及时去查看并处理。 17 | 18 | 如果你加入的项目本来就没有遵循PEP8规范,那么就按照项目现有的风格来完成你的开发。你可以在PEP8的 [A Foolish Consistency is the Hobgoblin of Little Minds](http://www.python.org/dev/peps/pep-0008/#id8) 查看这样做的原因以及其他可以不遵循PEP8的万不得已的情况。 19 | 20 | ## Imports的管理 21 | 22 | PEP8建议 `import` 应该按照下面的顺序来排列: 23 | 24 | {% highlight python %} 25 | 1. 标准库 26 | 2. 项目相关第三方库 27 | 3. 本地应用或者库 28 | {% endhighlight %} 29 | 30 | 在Django项目中,我们使用的导入顺序一般如下例所示: 31 | 32 | {% highlight python %} 33 | 例子 1.1 34 | 35 | # 标准库 36 | from math import sqrt  37 | from os.path import abspath  38 |   39 | # Django核心库 40 | from django.db import models  41 | from django.utils.translation \  42 |     import ugettext_lazy as _  43 |   44 | # 第三方应用  45 | from django_extensions.db.models \  46 |     import TimeStampedModel  47 |   48 | # local应用  49 | from splits.models import BananaSplit 50 | {% endhighlight %} 51 | 52 |
53 |

实际的开发中imports不需要像例子1.1那样注释,这里只是为了更清楚地说明。

54 |
55 | 56 | 所以我们的 `import` 顺序为: 57 | 58 | {% highlight python %} 59 | 1. 标准库 60 | 2. Django的核心库 61 | 3. 项目相关的第三方库 62 | 4. Local的application或者library 63 | {% endhighlight %} 64 | 65 | ## 使用显式声明的相对路径导入 66 | 67 | Python里面使用显式声明的相对路径导入来对各个module进行解耦。我们先看一个使用硬编码路径而不是相对路径导入的例子: 68 | 69 | {% highlight python %} 70 | 例子 1.2 71 | 72 | # report/views.py  73 | from django.views.generic \  74 |     import CreateView  75 |   76 | # 硬编码的导入方式 77 | from report.models import Report  78 | from report.forms import ReportForm  79 | from report.views import ReportPage  80 |   81 | class WaffleConeCreateView(ReportPage,  82 |                         CreateView):  83 |     model = Report  84 |     form_class = ReportForm 85 | 86 | {% endhighlight %} 87 | 88 | 虽然在当前项目里面这样的导入是没有问题的但是会严重降低模块的移植性和重用性: 89 | 90 | - 如果你需要在其他项目里面使用这个 `report` app,但是那个项目里面已经有一个叫 `report` 的包了呢? 91 | - 如果你突然发现用户要的是图表而不是表格,所以这个app的名字要从 `report` 要改成 `chart` 呢? 92 | 93 | 如果是硬编码的导入,出现上面的需求时,你就得到每个文件里面去把这些导入都改一遍。下面我们看看如何使用显式的相对路径导入: 94 | 95 | {% highlight python %} 96 | 例子 1.3 97 | 98 | # report/views.py  99 | from django.views.generic \  100 |     import CreateView  101 |   102 | # Relative imports of the  103 | #   ’report’ package  104 | from .models import Report  105 | from .forms import ReportForm  106 | from core.views import ReportPage 107 | 108 | class WaffleConeCreateView(ReportPage,  109 |                         CreateView):  110 |     model = Report  111 |     form_class = ReportForm 112 | {% endhighlight %} 113 | 114 | 下面总结一下Python里面不同的导入方式和它们在Django项目中使用的方式: 115 | 116 | 117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 133 | 136 | 139 | 140 | 141 | 146 | 149 | 152 | 153 | 154 | 159 | 162 | 165 | 166 | 167 |
Code导入方式用途
129 |

130 | from core.views import FoodMixin 131 |

132 |
134 |

绝对路径导入

135 |
137 |

从当前app之外导入

138 |
142 |

143 | from .models import WaffleCone 144 |

145 |
147 |

显式声明的相对路径

148 |
150 |

推荐用来从当前app的另一个module中导入

151 |
155 |

156 | from cones.models import WaffleCone 157 |

158 |
160 |

隐式声明的相对路径

161 |
163 |

常被用来从当前app的另一个module中导入,不推荐

164 |
168 |
169 | 170 |
171 |
ProTips™ PEP 328和PEP 8难道不是矛盾的么?
172 |

Guido Van Rossum 这样说

173 |

更多信息见 这里

174 |
175 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */ 2 | 3 | /* ============================================================================= 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /* 8 | * Corrects block display not defined in IE6/7/8/9 & FF3 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | nav, 20 | section, 21 | summary { 22 | display: block; 23 | } 24 | 25 | /* 26 | * Corrects inline-block display not defined in IE6/7/8/9 & FF3 27 | */ 28 | 29 | audio, 30 | canvas, 31 | video { 32 | display: inline-block; 33 | *display: inline; 34 | *zoom: 1; 35 | } 36 | 37 | /* 38 | * Prevents modern browsers from displaying 'audio' without controls 39 | * Remove excess height in iOS5 devices 40 | */ 41 | 42 | audio:not([controls]) { 43 | display: none; 44 | height: 0; 45 | } 46 | 47 | /* 48 | * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4 49 | * Known issue: no IE6 support 50 | */ 51 | 52 | [hidden] { 53 | display: none; 54 | } 55 | 56 | 57 | /* ============================================================================= 58 | Base 59 | ========================================================================== */ 60 | 61 | /* 62 | * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units 63 | * http://clagnut.com/blog/348/#c790 64 | * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom 65 | * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ 66 | */ 67 | 68 | html { 69 | font-size: 100%; /* 1 */ 70 | -webkit-text-size-adjust: 100%; /* 2 */ 71 | -ms-text-size-adjust: 100%; /* 2 */ 72 | } 73 | 74 | /* 75 | * Addresses font-family inconsistency between 'textarea' and other form elements. 76 | */ 77 | 78 | html, 79 | button, 80 | input, 81 | select, 82 | textarea { 83 | font-family: sans-serif; 84 | } 85 | 86 | /* 87 | * Addresses margins handled incorrectly in IE6/7 88 | */ 89 | 90 | body { 91 | margin: 0; 92 | } 93 | 94 | 95 | /* ============================================================================= 96 | Links 97 | ========================================================================== */ 98 | 99 | /* 100 | * Addresses outline displayed oddly in Chrome 101 | */ 102 | 103 | a:focus { 104 | outline: thin dotted; 105 | } 106 | 107 | /* 108 | * Improves readability when focused and also mouse hovered in all browsers 109 | * people.opera.com/patrickl/experiments/keyboard/test 110 | */ 111 | 112 | a:hover, 113 | a:active { 114 | outline: 0; 115 | } 116 | 117 | 118 | /* ============================================================================= 119 | Typography 120 | ========================================================================== */ 121 | 122 | /* 123 | * Addresses font sizes and margins set differently in IE6/7 124 | * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 125 | */ 126 | 127 | h1 { 128 | font-size: 2em; 129 | margin: 0.67em 0; 130 | } 131 | 132 | h2 { 133 | font-size: 1.5em; 134 | margin: 0.83em 0; 135 | } 136 | 137 | h3 { 138 | font-size: 1.17em; 139 | margin: 1em 0; 140 | } 141 | 142 | h4 { 143 | font-size: 1em; 144 | margin: 1.33em 0; 145 | } 146 | 147 | h5 { 148 | font-size: 0.83em; 149 | margin: 1.67em 0; 150 | } 151 | 152 | h6 { 153 | font-size: 0.75em; 154 | margin: 2.33em 0; 155 | } 156 | 157 | /* 158 | * Addresses styling not present in IE7/8/9, S5, Chrome 159 | */ 160 | 161 | abbr[title] { 162 | border-bottom: 1px dotted; 163 | } 164 | 165 | /* 166 | * Addresses style set to 'bolder' in FF3+, S4/5, Chrome 167 | */ 168 | 169 | b, 170 | strong { 171 | font-weight: bold; 172 | } 173 | 174 | blockquote { 175 | margin: 1em 40px; 176 | } 177 | 178 | /* 179 | * Addresses styling not present in S5, Chrome 180 | */ 181 | 182 | dfn { 183 | font-style: italic; 184 | } 185 | 186 | /* 187 | * Addresses styling not present in IE6/7/8/9 188 | */ 189 | 190 | mark { 191 | background: #ff0; 192 | color: #000; 193 | } 194 | 195 | /* 196 | * Addresses margins set differently in IE6/7 197 | */ 198 | 199 | p, 200 | pre { 201 | margin: 1em 0; 202 | } 203 | 204 | /* 205 | * Corrects font family set oddly in IE6, S4/5, Chrome 206 | * en.wikipedia.org/wiki/User:Davidgothberg/Test59 207 | */ 208 | 209 | pre, 210 | code, 211 | kbd, 212 | samp { 213 | font-family: monospace, serif; 214 | _font-family: 'courier new', monospace; 215 | font-size: 1em; 216 | } 217 | 218 | /* 219 | * Improves readability of pre-formatted text in all browsers 220 | */ 221 | 222 | pre { 223 | white-space: pre; 224 | white-space: pre-wrap; 225 | word-wrap: break-word; 226 | } 227 | 228 | /* 229 | * 1. Addresses CSS quotes not supported in IE6/7 230 | * 2. Addresses quote property not supported in S4 231 | */ 232 | 233 | /* 1 */ 234 | 235 | q { 236 | quotes: none; 237 | } 238 | 239 | /* 2 */ 240 | 241 | q:before, 242 | q:after { 243 | content: ''; 244 | content: none; 245 | } 246 | 247 | small { 248 | font-size: 75%; 249 | } 250 | 251 | /* 252 | * Prevents sub and sup affecting line-height in all browsers 253 | * gist.github.com/413930 254 | */ 255 | 256 | sub, 257 | sup { 258 | font-size: 75%; 259 | line-height: 0; 260 | position: relative; 261 | vertical-align: baseline; 262 | } 263 | 264 | sup { 265 | top: -0.5em; 266 | } 267 | 268 | sub { 269 | bottom: -0.25em; 270 | } 271 | 272 | 273 | /* ============================================================================= 274 | Lists 275 | ========================================================================== */ 276 | 277 | /* 278 | * Addresses margins set differently in IE6/7 279 | */ 280 | 281 | dl, 282 | menu, 283 | ol, 284 | ul { 285 | margin: 1em 0; 286 | } 287 | 288 | dd { 289 | margin: 0 0 0 40px; 290 | } 291 | 292 | /* 293 | * Addresses paddings set differently in IE6/7 294 | */ 295 | 296 | menu, 297 | ol, 298 | ul { 299 | padding: 0 0 0 40px; 300 | } 301 | 302 | /* 303 | * Corrects list images handled incorrectly in IE7 304 | */ 305 | 306 | nav ul, 307 | nav ol { 308 | list-style: none; 309 | list-style-image: none; 310 | } 311 | 312 | 313 | /* ============================================================================= 314 | Embedded content 315 | ========================================================================== */ 316 | 317 | /* 318 | * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 319 | * 2. Improves image quality when scaled in IE7 320 | * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ 321 | */ 322 | 323 | img { 324 | border: 0; /* 1 */ 325 | -ms-interpolation-mode: bicubic; /* 2 */ 326 | } 327 | 328 | /* 329 | * Corrects overflow displayed oddly in IE9 330 | */ 331 | 332 | svg:not(:root) { 333 | overflow: hidden; 334 | } 335 | 336 | 337 | /* ============================================================================= 338 | Figures 339 | ========================================================================== */ 340 | 341 | /* 342 | * Addresses margin not present in IE6/7/8/9, S5, O11 343 | */ 344 | 345 | figure { 346 | margin: 0; 347 | } 348 | 349 | 350 | /* ============================================================================= 351 | Forms 352 | ========================================================================== */ 353 | 354 | /* 355 | * Corrects margin displayed oddly in IE6/7 356 | */ 357 | 358 | form { 359 | margin: 0; 360 | } 361 | 362 | /* 363 | * Define consistent border, margin, and padding 364 | */ 365 | 366 | fieldset { 367 | border: 1px solid #c0c0c0; 368 | margin: 0 2px; 369 | padding: 0.35em 0.625em 0.75em; 370 | } 371 | 372 | /* 373 | * 1. Corrects color not being inherited in IE6/7/8/9 374 | * 2. Corrects text not wrapping in FF3 375 | * 3. Corrects alignment displayed oddly in IE6/7 376 | */ 377 | 378 | legend { 379 | border: 0; /* 1 */ 380 | padding: 0; 381 | white-space: normal; /* 2 */ 382 | *margin-left: -7px; /* 3 */ 383 | } 384 | 385 | /* 386 | * 1. Corrects font size not being inherited in all browsers 387 | * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome 388 | * 3. Improves appearance and consistency in all browsers 389 | */ 390 | 391 | button, 392 | input, 393 | select, 394 | textarea { 395 | font-size: 100%; /* 1 */ 396 | margin: 0; /* 2 */ 397 | vertical-align: baseline; /* 3 */ 398 | *vertical-align: middle; /* 3 */ 399 | } 400 | 401 | /* 402 | * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet 403 | */ 404 | 405 | button, 406 | input { 407 | line-height: normal; /* 1 */ 408 | } 409 | 410 | /* 411 | * 1. Improves usability and consistency of cursor style between image-type 'input' and others 412 | * 2. Corrects inability to style clickable 'input' types in iOS 413 | * 3. Removes inner spacing in IE7 without affecting normal text inputs 414 | * Known issue: inner spacing remains in IE6 415 | */ 416 | 417 | button, 418 | input[type="button"], 419 | input[type="reset"], 420 | input[type="submit"] { 421 | cursor: pointer; /* 1 */ 422 | -webkit-appearance: button; /* 2 */ 423 | *overflow: visible; /* 3 */ 424 | } 425 | 426 | /* 427 | * Re-set default cursor for disabled elements 428 | */ 429 | 430 | button[disabled], 431 | input[disabled] { 432 | cursor: default; 433 | } 434 | 435 | /* 436 | * 1. Addresses box sizing set to content-box in IE8/9 437 | * 2. Removes excess padding in IE8/9 438 | * 3. Removes excess padding in IE7 439 | Known issue: excess padding remains in IE6 440 | */ 441 | 442 | input[type="checkbox"], 443 | input[type="radio"] { 444 | box-sizing: border-box; /* 1 */ 445 | padding: 0; /* 2 */ 446 | *height: 13px; /* 3 */ 447 | *width: 13px; /* 3 */ 448 | } 449 | 450 | /* 451 | * 1. Addresses appearance set to searchfield in S5, Chrome 452 | * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) 453 | */ 454 | 455 | input[type="search"] { 456 | -webkit-appearance: textfield; /* 1 */ 457 | -moz-box-sizing: content-box; 458 | -webkit-box-sizing: content-box; /* 2 */ 459 | box-sizing: content-box; 460 | } 461 | 462 | /* 463 | * Removes inner padding and search cancel button in S5, Chrome on OS X 464 | */ 465 | 466 | input[type="search"]::-webkit-search-decoration, 467 | input[type="search"]::-webkit-search-cancel-button { 468 | -webkit-appearance: none; 469 | } 470 | 471 | /* 472 | * Removes inner padding and border in FF3+ 473 | * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ 474 | */ 475 | 476 | button::-moz-focus-inner, 477 | input::-moz-focus-inner { 478 | border: 0; 479 | padding: 0; 480 | } 481 | 482 | /* 483 | * 1. Removes default vertical scrollbar in IE6/7/8/9 484 | * 2. Improves readability and alignment in all browsers 485 | */ 486 | 487 | textarea { 488 | overflow: auto; /* 1 */ 489 | vertical-align: top; /* 2 */ 490 | } 491 | 492 | 493 | /* ============================================================================= 494 | Tables 495 | ========================================================================== */ 496 | 497 | /* 498 | * Remove most spacing between table cells 499 | */ 500 | 501 | table { 502 | border-collapse: collapse; 503 | border-spacing: 0; 504 | } -------------------------------------------------------------------------------- /js/modernizr-2.5.3.min.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.5.3 (Custom Build) | MIT & BSD 2 | * Build: http://www.modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a)if(j[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.substr(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function L(){e.input=function(c){for(var d=0,e=c.length;d",a,""].join(""),k.id=h,m.innerHTML+=f,m.appendChild(k),l||(m.style.background="",g.appendChild(m)),i=c(k,a),l?k.parentNode.removeChild(k):m.parentNode.removeChild(m),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e});var K=function(c,d){var f=c.join(""),g=d.length;y(f,function(c,d){var f=b.styleSheets[b.styleSheets.length-1],h=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"",i=c.childNodes,j={};while(g--)j[i[g].id]=i[g];e.touch="ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch||(j.touch&&j.touch.offsetTop)===9,e.csstransforms3d=(j.csstransforms3d&&j.csstransforms3d.offsetLeft)===9&&j.csstransforms3d.offsetHeight===3,e.generatedcontent=(j.generatedcontent&&j.generatedcontent.offsetHeight)>=1,e.fontface=/src/i.test(h)&&h.indexOf(d.split(" ")[0])===0},g,d)}(['@font-face {font-family:"font";src:url("https://")}',["@media (",n.join("touch-enabled),("),h,")","{#touch{top:9px;position:absolute}}"].join(""),["@media (",n.join("transform-3d),("),h,")","{#csstransforms3d{left:9px;position:absolute;height:3px;}}"].join(""),['#generatedcontent:after{content:"',l,'";visibility:hidden}'].join("")],["fontface","touch","csstransforms3d","generatedcontent"]);s.flexbox=function(){return J("flexOrder")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){try{var d=b.createElement("canvas"),e;e=!(!a.WebGLRenderingContext||!d.getContext("experimental-webgl")&&!d.getContext("webgl")),d=c}catch(f){e=!1}return e},s.touch=function(){return e.touch},s.geolocation=function(){return!!navigator.geolocation},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){for(var b=-1,c=p.length;++b",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f header, body > section, body > footer { 35 | float: left; 36 | width: 100%; 37 | clear: both; 38 | } 39 | 40 | /* Header */ 41 | 42 | body > header h1, body > header nav { 43 | display: inline-block; 44 | } 45 | 46 | body > header h1 span { 47 | display: none; 48 | } 49 | 50 | nav ul { 51 | padding: 0; 52 | margin: 0; 53 | } 54 | 55 | nav li { 56 | display: inline-block; 57 | } 58 | 59 | .main-nav { 60 | margin-top: 52px; 61 | } 62 | 63 | .main-nav li { 64 | margin-right: 10px; 65 | } 66 | 67 | .main-nav li a { 68 | border-radius: 5px; 69 | font-weight: 800; 70 | font-size: 14px; 71 | padding: 0.5em 1em; 72 | text-shadow: none; 73 | text-transform: uppercase; 74 | transition: all .25s; 75 | -moz-transition: all .25s; 76 | -webkit-transition: all .25s; 77 | } 78 | 79 | .main-nav li a:hover { 80 | background: #252525; 81 | box-shadow: inset 0 1px 3px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.1); 82 | text-shadow: 0 1px 3px rgba(0,0,0,.5); 83 | } 84 | 85 | .main-nav li.current a { 86 | background: #fc0; 87 | color: #222; 88 | box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5); 89 | text-shadow: 0 1px 0 rgba(255,255,255,.3); 90 | } 91 | 92 | .mobile-nav ul { 93 | overflow: hidden; 94 | width: 100%; 95 | display: table; 96 | } 97 | 98 | .mobile-nav a { 99 | float: left; 100 | width: 100%; 101 | background: #333; 102 | color: #fc0; 103 | text-align: center; 104 | text-transform: uppercase; 105 | font-size: 14px; 106 | font-weight: 800; 107 | padding: 5px 0; 108 | border-radius: 5px; 109 | } 110 | 111 | .mobile-nav .current a { 112 | background: #fc0; 113 | color: #222; 114 | box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5); 115 | text-shadow: 0 1px 0 rgba(255,255,255,.3); 116 | } 117 | 118 | .mobile-nav li { 119 | display: table-cell; 120 | width: 33.3%; 121 | padding: 8px; 122 | } 123 | 124 | @media (max-width: 768px){ 125 | .main-nav ul { 126 | text-align: right; 127 | } 128 | } 129 | @media (max-width: 720px){ 130 | .main-nav .show-on-mobiles { 131 | display: inline; 132 | } 133 | .main-nav .hide-on-mobiles { 134 | display: none; 135 | } 136 | } 137 | 138 | /* Footer */ 139 | 140 | body > footer { 141 | background: #222; 142 | font-size: 16px; 143 | padding-bottom: 5px; 144 | color: #888; 145 | margin-top: 40px; 146 | } 147 | 148 | body > footer a { 149 | color: #fff; 150 | } 151 | 152 | body > footer .align-right p, body > footer img { 153 | display: inline-block; 154 | } 155 | 156 | body > footer img { 157 | position: relative; 158 | top: 8px; 159 | margin-left: 5px; 160 | width: 100px; 161 | height: 30px; 162 | opacity: .8; 163 | padding: 1px; 164 | -webkit-transition: opacity .2s; 165 | -moz-transition: opacity .2s; 166 | transition: opacity .2s; 167 | } 168 | 169 | body > footer a:hover img { 170 | opacity: 1; 171 | } 172 | 173 | @media (max-width: 568px){ 174 | footer .one-third p { 175 | margin-bottom: 0; 176 | } 177 | footer .two-thirds p { 178 | margin-top: -20px; 179 | } 180 | } 181 | 182 | /* Intro */ 183 | 184 | .intro .unit { 185 | padding: 10px 0 40px; 186 | } 187 | 188 | .intro p { 189 | font-size: 1.75em; 190 | line-height: 1em; 191 | margin: 0; 192 | } 193 | 194 | @media (min-width: 569px){ 195 | .intro p { 196 | font-size: 3.2em; 197 | } 198 | } 199 | 200 | /* Quickstart */ 201 | 202 | .quickstart { 203 | background: #3F1F1F; 204 | color: #fff; 205 | margin: 60px 0; 206 | box-shadow: inset 0 3px 10px rgba(0,0,0,.4); 207 | } 208 | 209 | .quickstart .content { 210 | padding: 0px 0; 211 | } 212 | 213 | .quickstart h4 { 214 | font-size: 24px; 215 | line-height: 24px; 216 | margin-top: 20px; 217 | text-shadow: 0 1px 3px rgba(0,0,0,.8); 218 | } 219 | 220 | .quickstart .code { 221 | font-size: 12px; 222 | display: block; 223 | margin: 0 0 -30px; 224 | } 225 | 226 | @media (min-width: 768px){ 227 | .quickstart .code { 228 | font-size: 18px; 229 | margin: -30px 0; 230 | float: right; 231 | } 232 | .quickstart h4 { 233 | margin: 50px 0 0; 234 | text-align: center; 235 | } 236 | } 237 | 238 | /* Code */ 239 | 240 | .quickstart .code { 241 | display: block; 242 | padding: 0; 243 | font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace; 244 | line-height: 1.3em; 245 | } 246 | 247 | .quickstart .code .title { 248 | display: block; 249 | text-align: center; 250 | margin: 0 20px; 251 | padding: 5px 0; 252 | border-radius: 5px 5px 0 0; 253 | box-shadow: 0 3px 10px rgba(0,0,0,.5); 254 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 255 | font-size: 16px; 256 | font-weight: normal; 257 | color: #444; 258 | text-shadow: 0 1px 0 rgba(255,255,255,.5); 259 | background: #f7f7f7; 260 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y3ZjdmNyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjY2ZjZmNmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); 261 | background: -moz-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%); 262 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f7f7f7), color-stop(7%,#cfcfcf), color-stop(100%,#aaaaaa)); 263 | background: -webkit-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%); 264 | background: -o-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%); 265 | background: -ms-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%); 266 | background: linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%); 267 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#aaaaaa',GradientType=0 ); 268 | border-bottom: 1px solid #111; 269 | } 270 | 271 | .quickstart .code .shell { 272 | padding: 20px; 273 | text-shadow: none; 274 | margin: 0 20px; 275 | background: #3d3d3d; 276 | border-radius: 0 0 5px 5px; 277 | box-shadow: 0 5px 30px rgba(0,0,0,.3); 278 | } 279 | 280 | .quickstart .code .line { 281 | display: block; 282 | margin: 0; 283 | padding: 0; 284 | } 285 | 286 | .quickstart .code .line span { 287 | display: inline-block; 288 | } 289 | 290 | .quickstart .code .path { 291 | color: #87ceeb; 292 | } 293 | 294 | .quickstart .code .prompt { 295 | color: #cd5c5c; 296 | } 297 | 298 | .quickstart .code .command { 299 | color: #f0e68c; 300 | } 301 | 302 | .quickstart .code .output { 303 | color: #888; 304 | } 305 | 306 | /* Free Hosting */ 307 | 308 | .free-hosting .pane { 309 | background: #444; 310 | border-radius: 10px; 311 | text-shadow: none; 312 | position: relative; 313 | padding: 0 20px 30px; 314 | } 315 | 316 | .free-hosting img { 317 | margin: -30px 0 0; 318 | width: 180px; 319 | height: 150px; 320 | } 321 | 322 | .free-hosting h2 { 323 | font-size: 28px; 324 | } 325 | 326 | .free-hosting p, 327 | .free-hosting a { 328 | font-size: 16px; 329 | } 330 | 331 | .free-hosting p { 332 | margin: .75em 0; 333 | } 334 | 335 | @media (min-width: 768px){ 336 | .free-hosting img { 337 | float: left; 338 | margin: -20px -30px -30px -50px; 339 | width: 300px; 340 | height: 251px; 341 | } 342 | .free-hosting .pane-content { 343 | margin-top: 35px; 344 | padding-right: 30px; 345 | } 346 | .free-hosting p, 347 | .free-hosting a { 348 | font-size: 18px; 349 | } 350 | .free-hosting .pane:after { 351 | content: " "; 352 | float: right; 353 | background: url(../img/footer-arrow.png) top left no-repeat; 354 | width: 73px; 355 | height: 186px; 356 | position: absolute; 357 | right: 0; 358 | bottom: -30px; 359 | } 360 | } 361 | 362 | /* Documentation */ 363 | 364 | .docs .content { 365 | padding: 0; 366 | } 367 | 368 | .docs article { 369 | background: #444; 370 | border-radius: 10px; 371 | padding: 20px; 372 | margin: 0 10px; 373 | box-shadow: 0 3px 10px rgba(0,0,0,.1); 374 | min-height: 800px; 375 | font-size: 16px; 376 | } 377 | 378 | @media (max-width: 568px){ 379 | .docs article { 380 | margin: 0; 381 | } 382 | } 383 | 384 | @media (min-width: 768px){ 385 | .docs article { 386 | padding: 40px 40px 30px; 387 | font-size: 21px; 388 | } 389 | } 390 | 391 | .docs aside { 392 | padding-top: 30px; 393 | } 394 | 395 | .docs aside h4 { 396 | text-transform: uppercase; 397 | font-size: 14px; 398 | font-weight: 700; 399 | padding: 0 0 10px 30px; 400 | margin-left: -30px; 401 | display: inline-block; 402 | border-bottom: 1px solid #c00; 403 | } 404 | 405 | .docs aside ul { 406 | padding-left: 0; 407 | } 408 | 409 | .docs aside li { 410 | list-style-type: none; 411 | } 412 | 413 | .docs aside li a { 414 | font-size: 16px; 415 | position: relative 416 | } 417 | 418 | .docs aside li.current a:before { 419 | content: ""; 420 | border-color: transparent transparent transparent #444; 421 | border-style: solid; 422 | border-width: 10px; 423 | width: 0; 424 | height: 0; 425 | position: absolute; 426 | top: 0; 427 | left: -30px; 428 | } 429 | 430 | .section-nav { 431 | text-align: center; 432 | padding-top: 40px; 433 | position: relative; 434 | background: url(../img/article-footer.png) top center no-repeat; 435 | margin: 40px -20px 10px; 436 | } 437 | 438 | .section-nav > div { 439 | width: 49.5%; 440 | } 441 | 442 | .section-nav a, .section-nav span { 443 | color: #fff; 444 | font-size: 16px; 445 | text-transform: uppercase; 446 | font-weight: 700; 447 | padding: 8px 12px 10px; 448 | border-radius: 5px; 449 | /*border: 1px solid #333;*/ 450 | box-shadow: 0 1px 3px rgba(0,0,0,.3), inset 0 1px 1px rgba(255,255,255,.5); 451 | background: #777; 452 | } 453 | 454 | .section-nav a:hover { 455 | color: #fff; 456 | background: #888; 457 | } 458 | 459 | .section-nav .next, .section-nav .prev { 460 | position: relative; 461 | } 462 | 463 | .section-nav .next:after, .section-nav .prev:before { 464 | font-size: 36px; 465 | color: #222; 466 | font-weight: 800; 467 | text-shadow: 0 1px 0 rgba(255,255,255,.4); 468 | position: absolute; 469 | top: -7px; 470 | } 471 | 472 | .section-nav .next:after { 473 | content: "›"; 474 | right: 10px; 475 | } 476 | 477 | .section-nav .prev:before { 478 | content: "‹"; 479 | left: 10px; 480 | } 481 | 482 | .section-nav .prev, .section-nav .prev:hover { 483 | /*float: left;*/ 484 | padding-left: 30px; 485 | } 486 | 487 | .section-nav .next, .section-nav .next:hover { 488 | /*float: right;*/ 489 | padding-right: 30px; 490 | } 491 | 492 | .section-nav .disabled { 493 | opacity: .5; 494 | /*filter: alpha*/ 495 | cursor: default; 496 | } 497 | 498 | .docs-nav-mobile select { 499 | width: 100%; 500 | } 501 | 502 | /* Code Highlighting */ 503 | 504 | 505 | pre, code { 506 | white-space: pre; 507 | display: inline-block; 508 | margin: 0; 509 | padding: 0; 510 | font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace; 511 | font-size: 14px; 512 | padding: 0 .5em; 513 | line-height: 1.8em; 514 | } 515 | 516 | @media (min-width: 768px){ 517 | pre, code { 518 | font-size: 16px; 519 | } 520 | } 521 | 522 | .highlight, p > pre, p > code, p > nobr > code, li > code, h5 > code, .note > code { 523 | background: #333; 524 | color: #fff; 525 | border-radius: 5px; 526 | box-shadow: inset 0 1px 10px rgba(0,0,0,.3), 527 | 0 1px 0 rgba(255,255,255,.1), 528 | 0 -1px 0 rgba(0,0,0,.5); 529 | } 530 | 531 | .note code { 532 | background-color: rgba(0,0,0,0.2); 533 | margin-left: 2.5px; 534 | margin-right: 2.5px; 535 | font-size: 0.8em; 536 | } 537 | 538 | .highlight { 539 | padding: 10px 0; 540 | width: 100%; 541 | overflow: auto; 542 | } 543 | 544 | /* HTML Elements */ 545 | 546 | h1, h2, h3, h4, h5, h6 { 547 | margin: 0; 548 | } 549 | 550 | a { 551 | color: #fc0; 552 | text-decoration: none; 553 | transition: all .25s; 554 | -moz-transition: all .25s; 555 | -webkit-transition: all .25s; 556 | } 557 | 558 | a:hover { 559 | color: #f90; 560 | } 561 | 562 | strong { 563 | font-weight: 700; 564 | } 565 | 566 | p { 567 | line-height: 1.5em; 568 | } 569 | 570 | .left { float: left; } 571 | .right { float: right; } 572 | .align-right { text-align: right; } 573 | .align-left { text-align: left; } 574 | .align-center { text-align: center; } 575 | 576 | /* Article HTML */ 577 | 578 | article h2, 579 | article h3, 580 | article h4, 581 | article h5, 582 | article h6 { 583 | margin: 1em 0; 584 | } 585 | 586 | article h4 { 587 | color: #fff; 588 | } 589 | 590 | h5, h6 { 591 | font-size: 1em; 592 | font-style: italic; 593 | } 594 | 595 | article ul li p { 596 | margin: 0; 597 | } 598 | 599 | article ul li, article ol li { 600 | line-height: 1.5em; 601 | margin-bottom: 0.5em; 602 | } 603 | 604 | article ul li blockquote { 605 | margin: 10px 0; 606 | } 607 | 608 | blockquote { 609 | border-left: 2px solid #777; 610 | padding-left: 20px; 611 | font-style: italic; 612 | font-size: 18px; 613 | font-weight: 500; 614 | } 615 | 616 | 617 | /* Tables */ 618 | 619 | table { 620 | width: 100%; 621 | background: #555; 622 | margin: .5em 0; 623 | border-radius: 5px; 624 | box-shadow: 0 1px 3px rgba(0,0,0,.3); 625 | } 626 | 627 | thead { 628 | border-top-left-radius: 5px; 629 | border-top-right-radius: 5px; 630 | color: #fff; 631 | background: #3a3a3a; 632 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzNhM2EzYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxZTFlMWUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 633 | background: -moz-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%); 634 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3a3a3a), color-stop(100%,#1e1e1e)); 635 | background: -webkit-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%); 636 | background: -o-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%); 637 | background: -ms-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%); 638 | background: linear-gradient(to bottom, #3a3a3a 0%,#1e1e1e 100%); 639 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a3a3a', endColorstr='#1e1e1e',GradientType=0 ); 640 | } 641 | 642 | thead th { 643 | position: relative; 644 | box-shadow: inset 0 1px 0 rgba(255,255,255,.1); 645 | } 646 | 647 | thead th:first-child { 648 | border-top-left-radius: 5px; 649 | } 650 | 651 | thead th:last-child { 652 | border-top-right-radius: 5px; 653 | } 654 | 655 | td { 656 | padding: .5em .75em; 657 | } 658 | 659 | td p { 660 | margin: 0; 661 | } 662 | 663 | th { 664 | text-transform: uppercase; 665 | font-size: 16px; 666 | padding: .5em .75em; 667 | text-shadow: 0 -1px 0 rgba(0,0,0,.9); 668 | color: #888; 669 | } 670 | 671 | tbody td { 672 | border-top: 1px solid rgba(0,0,0,.1); 673 | box-shadow: inset 0 1px 0 rgba(255,255,255,.1); 674 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); 675 | background: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); 676 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.1)), color-stop(100%,rgba(255,255,255,0))); 677 | background: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%); 678 | background: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%); 679 | background: -ms-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%); 680 | background: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%); 681 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1affffff', endColorstr='#00ffffff',GradientType=0 ); 682 | } 683 | 684 | td p { 685 | font-size: 16px; 686 | } 687 | 688 | td p code { 689 | font-size: 14px; 690 | } 691 | 692 | code.option, th .option, code.filter, th .filter { 693 | color: #50B600; 694 | } 695 | 696 | code.flag, th .flag, code.output, th .output { 697 | color: #049DCE; 698 | } 699 | 700 | code.option, code.flag, code.filter, code.output { 701 | margin-bottom: 2px; 702 | } 703 | 704 | /* Note types */ 705 | 706 | .note { 707 | margin: 30px 0; 708 | margin-left: -30px; 709 | padding: 20px 20px 24px; 710 | padding-left: 50px; 711 | border-radius: 0 5px 5px 0; 712 | position: relative; 713 | box-shadow: 0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3); 714 | background: #7e6d42; 715 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdlNmQ0MiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM1YzRlMzUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 716 | background: -moz-linear-gradient(top, #7e6d42 0%, #5c4e35 100%); 717 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7e6d42), color-stop(100%,#5c4e35)); 718 | background: -webkit-linear-gradient(top, #7e6d42 0%,#5c4e35 100%); 719 | background: -o-linear-gradient(top, #7e6d42 0%,#5c4e35 100%); 720 | background: -ms-linear-gradient(top, #7e6d42 0%,#5c4e35 100%); 721 | background: linear-gradient(to bottom, #7e6d42 0%,#5c4e35 100%); 722 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7e6d42', endColorstr='#5c4e35',GradientType=0 ); 723 | } 724 | 725 | @media (max-width: 568px){ 726 | .note { 727 | margin-right: -30px; 728 | } 729 | } 730 | 731 | @media (min-width: 768px){ 732 | .note { 733 | margin-left: -50px; 734 | } 735 | } 736 | 737 | .note:before { 738 | content: ""; 739 | position: absolute; 740 | top: -10px; 741 | left: 0px; 742 | border-color: transparent #222 #222 transparent; 743 | border-style: solid; 744 | border-width: 5px; 745 | width: 0; 746 | height: 0; 747 | } 748 | 749 | .note h5, .note p { 750 | margin: 0; 751 | color: #fff; 752 | } 753 | 754 | .note h5 { 755 | line-height: 1.5em; 756 | font-weight: 800; 757 | font-style: normal; 758 | } 759 | 760 | .note p { 761 | font-weight: 400; 762 | font-size: .75em; 763 | } 764 | 765 | .info { 766 | background: #0389aa; 767 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAzODlhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDYxN2YiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 768 | background: -moz-linear-gradient(top, #0389aa 0%, #00617f 100%); 769 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0389aa), color-stop(100%,#00617f)); 770 | background: -webkit-linear-gradient(top, #0389aa 0%,#00617f 100%); 771 | background: -o-linear-gradient(top, #0389aa 0%,#00617f 100%); 772 | background: -ms-linear-gradient(top, #0389aa 0%,#00617f 100%); 773 | background: linear-gradient(to bottom, #0389aa 0%,#00617f 100%); 774 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0389aa', endColorstr='#00617f',GradientType=0 ); 775 | } 776 | 777 | .warning { 778 | background: #9e2812; 779 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2ZjBkMGQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 780 | background: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%); 781 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9e2812), color-stop(100%,#6f0d0d)); 782 | background: -webkit-linear-gradient(top, #9e2812 0%,#6f0d0d 100%); 783 | background: -o-linear-gradient(top, #9e2812 0%,#6f0d0d 100%); 784 | background: -ms-linear-gradient(top, #9e2812 0%,#6f0d0d 100%); 785 | background: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%); 786 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 ); 787 | } 788 | 789 | .info:before { 790 | border-color: transparent #00617f #00617f transparent; 791 | } 792 | 793 | .warning:before { 794 | border-color: transparent #6f0d0d #6f0d0d transparent; 795 | } 796 | 797 | .note:after { 798 | content: "★"; 799 | color: #fc0; 800 | position: absolute; 801 | top: 14px; 802 | left: 14px; 803 | font-size: 28px; 804 | font-weight: bold; 805 | text-shadow: 0 -1px 0 rgba(0,0,0,.5); 806 | } 807 | 808 | .info:after { 809 | content: "ⓘ"; 810 | color: #fff; 811 | position: absolute; 812 | top: 15px; 813 | left: 15px; 814 | font-size: 28px; 815 | font-weight: bold; 816 | text-shadow: 0 -1px 0 rgba(0,0,0,.5); 817 | } 818 | 819 | .warning:after { 820 | content: "‼"; 821 | color: #fc0; 822 | position: absolute; 823 | top: 15px; 824 | left: 15px; 825 | font-size: 32px; 826 | font-weight: bold; 827 | text-shadow: 0 -1px 0 rgba(0,0,0,.5); 828 | } 829 | 830 | /* Responsive tables */ 831 | 832 | @media (max-width: 768px){ 833 | .mobile-side-scroller { 834 | overflow-x: scroll; 835 | margin: 0 -40px; 836 | padding: 0 10px; 837 | } 838 | } 839 | --------------------------------------------------------------------------------