See https://github.com/picocms/pico-theme for Pico's default theme and https://github.com/picocms/pico-deprecated for the PicoDeprecated plugin.pico-3.0-alpha
parent
a39bc38620
commit
cbb8ece579
@ -0,0 +1,3 @@ |
|||||||
|
# This directory is meant to be empty, except for config.yml.template |
||||||
|
* |
||||||
|
!config.yml.template |
@ -0,0 +1,3 @@ |
|||||||
|
# This directory is meant to be empty, except for DummyPlugin.php |
||||||
|
* |
||||||
|
!DummyPlugin.php |
@ -1,504 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* Maintain backward compatibility to older Pico releases |
|
||||||
* |
|
||||||
* This plugin exists for backward compatibility and is disabled by default. |
|
||||||
* It gets automatically enabled when a plugin which either doesn't implement |
|
||||||
* {@link PicoPluginInterface} (plugins for Pico 0.X) or define the |
|
||||||
* {@link PicoDeprecated::API_VERSION} (plugins for Pico 1.0) is loaded. |
|
||||||
* |
|
||||||
* The following deprecated events are triggered by this plugin: |
|
||||||
* |
|
||||||
* | Event | ... triggers the deprecated event | |
|
||||||
* | ------------------- | --------------------------------------------------------- | |
|
||||||
* | onPluginsLoaded | plugins_loaded() | |
|
||||||
* | onConfigLoaded | config_loaded($config) | |
|
||||||
* | onRequestUrl | request_url($url) | |
|
||||||
* | onContentLoading | before_load_content($file) | |
|
||||||
* | onContentLoaded | after_load_content($file, $rawContent) | |
|
||||||
* | on404ContentLoading | before_404_load_content($file) | |
|
||||||
* | on404ContentLoaded | after_404_load_content($file, $rawContent) | |
|
||||||
* | onMetaHeaders | before_read_file_meta($headers) | |
|
||||||
* | onMetaParsed | file_meta($meta) | |
|
||||||
* | onContentParsing | before_parse_content($rawContent) | |
|
||||||
* | onContentParsed | after_parse_content($content) | |
|
||||||
* | onContentParsed | content_parsed($content) | |
|
||||||
* | onSinglePageLoaded | get_page_data($pages, $meta) | |
|
||||||
* | onPagesLoaded | get_pages($pages, $currentPage, $previousPage, $nextPage) | |
|
||||||
* | onTwigRegistration | before_twig_register() | |
|
||||||
* | onPageRendering | before_render($twigVariables, $twig, $templateName) | |
|
||||||
* | onPageRendered | after_render($output) | |
|
||||||
* |
|
||||||
* Since Pico 2.0 the config is stored in `config/*.yml` files. This plugin |
|
||||||
* also tries to read {@path "config/config.php"} (Pico 1.0) and |
|
||||||
* {@path "config.php"} in Pico's root dir (Pico 0.X) and overwrites all |
|
||||||
* previously specified settings. |
|
||||||
* |
|
||||||
* @author Daniel Rudolf |
|
||||||
* @link http://picocms.org |
|
||||||
* @license http://opensource.org/licenses/MIT The MIT License |
|
||||||
* @version 2.0 |
|
||||||
*/ |
|
||||||
class PicoDeprecated extends AbstractPicoPlugin |
|
||||||
{ |
|
||||||
/** |
|
||||||
* This plugin is disabled by default |
|
||||||
* |
|
||||||
* @see AbstractPicoPlugin::$enabled |
|
||||||
*/ |
|
||||||
protected $enabled = false; |
|
||||||
|
|
||||||
/** |
|
||||||
* The requested file |
|
||||||
* |
|
||||||
* @see PicoDeprecated::getRequestFile() |
|
||||||
* @var string|null |
|
||||||
*/ |
|
||||||
protected $requestFile; |
|
||||||
|
|
||||||
/** |
|
||||||
* Enables this plugin on demand and triggers the deprecated event |
|
||||||
* plugins_loaded() |
|
||||||
* |
|
||||||
* @see DummyPlugin::onPluginsLoaded() |
|
||||||
*/ |
|
||||||
public function onPluginsLoaded(array &$plugins) |
|
||||||
{ |
|
||||||
if ($plugins) { |
|
||||||
foreach ($plugins as $plugin) { |
|
||||||
if (!($plugin instanceof PicoPluginInterface)) { |
|
||||||
// the plugin doesn't implement PicoPluginInterface; it uses deprecated events |
|
||||||
// enable PicoDeprecated if it hasn't be explicitly enabled/disabled yet |
|
||||||
if (!$this->isStatusChanged()) { |
|
||||||
$this->setEnabled(true, true, true); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} else { |
|
||||||
// no plugins were found, so it actually isn't necessary to call deprecated events |
|
||||||
// anyway, this plugin also ensures compatibility apart from events used by old plugins, |
|
||||||
// so enable PicoDeprecated if it hasn't be explicitly enabled/disabled yet |
|
||||||
if (!$this->isStatusChanged()) { |
|
||||||
$this->setEnabled(true, true, true); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if ($this->isEnabled()) { |
|
||||||
$this->triggerEvent('plugins_loaded'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event config_loaded($config) |
|
||||||
* |
|
||||||
* This method also defines deprecated constants, reads the `config.php` |
|
||||||
* in Pico's root dir, enables the plugins {@link PicoParsePagesContent} |
|
||||||
* and {@link PicoExcerpt} and makes `$config` globally accessible (the |
|
||||||
* latter was removed with Pico 0.9 and was added again as deprecated |
|
||||||
* feature with Pico 1.0) |
|
||||||
* |
|
||||||
* @see PicoDeprecated::defineConstants() |
|
||||||
* @see PicoDeprecated::loadRootDirConfig() |
|
||||||
* @see PicoDeprecated::enablePlugins() |
|
||||||
* @see DummyPlugin::onConfigLoaded() |
|
||||||
* @param array &$config array of config variables |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
public function onConfigLoaded(array &$config) |
|
||||||
{ |
|
||||||
$this->defineConstants(); |
|
||||||
$this->loadScriptedConfig($config); |
|
||||||
$this->loadRootDirConfig($config); |
|
||||||
$this->enablePlugins(); |
|
||||||
$GLOBALS['config'] = &$config; |
|
||||||
|
|
||||||
$this->triggerEvent('config_loaded', array(&$config)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Defines deprecated constants |
|
||||||
* |
|
||||||
* `ROOT_DIR`, `LIB_DIR`, `PLUGINS_DIR`, `THEMES_DIR` and `CONTENT_EXT` |
|
||||||
* are deprecated since v1.0, `CONTENT_DIR` existed just in v0.9, |
|
||||||
* `CONFIG_DIR` just for a short time between v0.9 and v1.0 and |
|
||||||
* `CACHE_DIR` was dropped with v1.0 without a replacement. |
|
||||||
* |
|
||||||
* @see PicoDeprecated::onConfigLoaded() |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
protected function defineConstants() |
|
||||||
{ |
|
||||||
if (!defined('ROOT_DIR')) { |
|
||||||
define('ROOT_DIR', $this->getRootDir()); |
|
||||||
} |
|
||||||
if (!defined('CONFIG_DIR')) { |
|
||||||
define('CONFIG_DIR', $this->getConfigDir()); |
|
||||||
} |
|
||||||
if (!defined('LIB_DIR')) { |
|
||||||
$picoReflector = new ReflectionClass('Pico'); |
|
||||||
define('LIB_DIR', dirname($picoReflector->getFileName()) . '/'); |
|
||||||
} |
|
||||||
if (!defined('PLUGINS_DIR')) { |
|
||||||
define('PLUGINS_DIR', $this->getPluginsDir()); |
|
||||||
} |
|
||||||
if (!defined('THEMES_DIR')) { |
|
||||||
define('THEMES_DIR', $this->getThemesDir()); |
|
||||||
} |
|
||||||
if (!defined('CONTENT_DIR')) { |
|
||||||
define('CONTENT_DIR', $this->getConfig('content_dir')); |
|
||||||
} |
|
||||||
if (!defined('CONTENT_EXT')) { |
|
||||||
define('CONTENT_EXT', $this->getConfig('content_ext')); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Read config.php in Pico's config dir (i.e. config/config.php) |
|
||||||
* |
|
||||||
* @see PicoDeprecated::onConfigLoaded() |
|
||||||
* @see Pico::loadConfig() |
|
||||||
* @param array &$realConfig array of config variables |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
protected function loadScriptedConfig(array &$realConfig) |
|
||||||
{ |
|
||||||
if (file_exists($this->getConfigDir() . 'config.php')) { |
|
||||||
// scope isolated require() |
|
||||||
$includeClosure = function ($configFile) { |
|
||||||
require($configFile); |
|
||||||
return (isset($config) && is_array($config)) ? $config : array(); |
|
||||||
}; |
|
||||||
if (PHP_VERSION_ID >= 50400) { |
|
||||||
$includeClosure = $includeClosure->bindTo(null); |
|
||||||
} |
|
||||||
|
|
||||||
// config.php in Pico::$configDir (i.e. config/config.php) is deprecated |
|
||||||
// use *.yml files in Pico::$configDir instead |
|
||||||
$config = $includeClosure($this->getConfigDir() . 'config.php'); |
|
||||||
|
|
||||||
if ($config) { |
|
||||||
if (!empty($config['base_url'])) { |
|
||||||
$config['base_url'] = rtrim($config['base_url'], '/') . '/'; |
|
||||||
} |
|
||||||
if (!empty($config['content_dir'])) { |
|
||||||
$config['content_dir'] = $this->getAbsolutePath($config['content_dir']); |
|
||||||
} |
|
||||||
if (!empty($config['theme_url'])) { |
|
||||||
if (preg_match('#^[A-Za-z][A-Za-z0-9+\-.]*://#', $config['theme_url'])) { |
|
||||||
$config['theme_url'] = rtrim($config['theme_url'], '/') . '/'; |
|
||||||
} else { |
|
||||||
$config['theme_url'] = $this->getBaseUrl() . rtrim($config['theme_url'], '/') . '/'; |
|
||||||
} |
|
||||||
} |
|
||||||
if (!empty($config['timezone'])) { |
|
||||||
date_default_timezone_set($config['timezone']); |
|
||||||
} |
|
||||||
|
|
||||||
$realConfig = $config + $realConfig; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Read config.php in Pico's root dir |
|
||||||
* |
|
||||||
* @see PicoDeprecated::onConfigLoaded() |
|
||||||
* @see Pico::loadConfig() |
|
||||||
* @param array &$realConfig array of config variables |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
protected function loadRootDirConfig(array &$realConfig) |
|
||||||
{ |
|
||||||
if (file_exists($this->getRootDir() . 'config.php')) { |
|
||||||
$config = null; |
|
||||||
|
|
||||||
// scope isolated require() |
|
||||||
$includeClosure = function ($configFile) use (&$config) { |
|
||||||
require($configFile); |
|
||||||
}; |
|
||||||
if (PHP_VERSION_ID >= 50400) { |
|
||||||
$includeClosure = $includeClosure->bindTo(null); |
|
||||||
} |
|
||||||
|
|
||||||
// config.php in Pico::$rootDir is deprecated |
|
||||||
// use config.php in Pico::$configDir instead |
|
||||||
$includeClosure($this->getRootDir() . 'config.php'); |
|
||||||
|
|
||||||
if (is_array($config)) { |
|
||||||
if (isset($config['base_url'])) { |
|
||||||
$config['base_url'] = rtrim($config['base_url'], '/') . '/'; |
|
||||||
} |
|
||||||
if (isset($config['content_dir'])) { |
|
||||||
$config['content_dir'] = rtrim($config['content_dir'], '/\\') . '/'; |
|
||||||
} |
|
||||||
|
|
||||||
$realConfig = $config + $realConfig; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Enables the plugins PicoParsePagesContent and PicoExcerpt |
|
||||||
* |
|
||||||
* @see PicoParsePagesContent |
|
||||||
* @see PicoExcerpt |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
protected function enablePlugins() |
|
||||||
{ |
|
||||||
// enable PicoParsePagesContent and PicoExcerpt |
|
||||||
// we can't enable them during onPluginsLoaded because we can't know |
|
||||||
// if the user disabled us (PicoDeprecated) manually in the config |
|
||||||
$plugins = $this->getPlugins(); |
|
||||||
if (isset($plugins['PicoParsePagesContent'])) { |
|
||||||
// parse all pages content if this plugin hasn't |
|
||||||
// be explicitly enabled/disabled yet |
|
||||||
if (!$plugins['PicoParsePagesContent']->isStatusChanged()) { |
|
||||||
$plugins['PicoParsePagesContent']->setEnabled(true, true, true); |
|
||||||
} |
|
||||||
} |
|
||||||
if (isset($plugins['PicoExcerpt'])) { |
|
||||||
// enable excerpt plugin if it hasn't be explicitly enabled/disabled yet |
|
||||||
if (!$plugins['PicoExcerpt']->isStatusChanged()) { |
|
||||||
$plugins['PicoExcerpt']->setEnabled(true, true, true); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event request_url($url) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onRequestUrl() |
|
||||||
*/ |
|
||||||
public function onRequestUrl(&$url) |
|
||||||
{ |
|
||||||
$this->triggerEvent('request_url', array(&$url)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Sets PicoDeprecated::$requestFile to trigger the deprecated |
|
||||||
* events after_load_content() and after_404_load_content() |
|
||||||
* |
|
||||||
* @see PicoDeprecated::onContentLoaded() |
|
||||||
* @see PicoDeprecated::on404ContentLoaded() |
|
||||||
* @see DummyPlugin::onRequestFile() |
|
||||||
*/ |
|
||||||
public function onRequestFile(&$file) |
|
||||||
{ |
|
||||||
$this->requestFile = &$file; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated before_load_content($file) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onContentLoading() |
|
||||||
*/ |
|
||||||
public function onContentLoading(&$file) |
|
||||||
{ |
|
||||||
$this->triggerEvent('before_load_content', array(&$file)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event after_load_content($file, $rawContent) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onContentLoaded() |
|
||||||
*/ |
|
||||||
public function onContentLoaded(&$rawContent) |
|
||||||
{ |
|
||||||
$this->triggerEvent('after_load_content', array(&$this->requestFile, &$rawContent)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated before_404_load_content($file) |
|
||||||
* |
|
||||||
* @see DummyPlugin::on404ContentLoading() |
|
||||||
*/ |
|
||||||
public function on404ContentLoading(&$file) |
|
||||||
{ |
|
||||||
$this->triggerEvent('before_404_load_content', array(&$file)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event after_404_load_content($file, $rawContent) |
|
||||||
* |
|
||||||
* @see DummyPlugin::on404ContentLoaded() |
|
||||||
*/ |
|
||||||
public function on404ContentLoaded(&$rawContent) |
|
||||||
{ |
|
||||||
$this->triggerEvent('after_404_load_content', array(&$this->requestFile, &$rawContent)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event before_read_file_meta($headers) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onMetaHeaders() |
|
||||||
*/ |
|
||||||
public function onMetaHeaders(array &$headers) |
|
||||||
{ |
|
||||||
$this->triggerEvent('before_read_file_meta', array(&$headers)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event file_meta($meta) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onMetaParsed() |
|
||||||
*/ |
|
||||||
public function onMetaParsed(array &$meta) |
|
||||||
{ |
|
||||||
$this->triggerEvent('file_meta', array(&$meta)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event before_parse_content($rawContent) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onContentParsing() |
|
||||||
*/ |
|
||||||
public function onContentParsing(&$rawContent) |
|
||||||
{ |
|
||||||
$this->triggerEvent('before_parse_content', array(&$rawContent)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated events after_parse_content($content) and |
|
||||||
* content_parsed($content) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onContentParsed() |
|
||||||
*/ |
|
||||||
public function onContentParsed(&$content) |
|
||||||
{ |
|
||||||
$this->triggerEvent('after_parse_content', array(&$content)); |
|
||||||
|
|
||||||
// deprecated since v0.8 |
|
||||||
$this->triggerEvent('content_parsed', array(&$content)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event get_page_data($pages, $meta) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onSinglePageLoaded() |
|
||||||
*/ |
|
||||||
public function onSinglePageLoaded(array &$pageData) |
|
||||||
{ |
|
||||||
$this->triggerEvent('get_page_data', array(&$pageData, $pageData['meta'])); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event |
|
||||||
* get_pages($pages, $currentPage, $previousPage, $nextPage) |
|
||||||
* |
|
||||||
* Please note that the `get_pages()` event gets `$pages` passed without a |
|
||||||
* array index. The index is rebuild later using either the `id` array key |
|
||||||
* or is derived from the `url` array key. Duplicates are prevented by |
|
||||||
* adding `~dup` when necessary. |
|
||||||
* |
|
||||||
* @see DummyPlugin::onPagesLoaded() |
|
||||||
*/ |
|
||||||
public function onPagesLoaded( |
|
||||||
array &$pages, |
|
||||||
array &$currentPage = null, |
|
||||||
array &$previousPage = null, |
|
||||||
array &$nextPage = null |
|
||||||
) { |
|
||||||
// remove keys of pages array |
|
||||||
$plainPages = array(); |
|
||||||
foreach ($pages as &$pageData) { |
|
||||||
$plainPages[] = &$pageData; |
|
||||||
} |
|
||||||
unset($pageData); |
|
||||||
|
|
||||||
$this->triggerEvent('get_pages', array(&$plainPages, &$currentPage, &$previousPage, &$nextPage)); |
|
||||||
|
|
||||||
// re-index pages array |
|
||||||
$pages = array(); |
|
||||||
foreach ($plainPages as &$pageData) { |
|
||||||
if (!isset($pageData['id'])) { |
|
||||||
$urlPrefixLength = strlen($this->getBaseUrl()) + intval(!$this->isUrlRewritingEnabled()); |
|
||||||
$pageData['id'] = substr($pageData['url'], $urlPrefixLength); |
|
||||||
} |
|
||||||
|
|
||||||
// prevent duplicates |
|
||||||
$id = $pageData['id']; |
|
||||||
for ($i = 1; isset($pages[$id]); $i++) { |
|
||||||
$id = $pageData['id'] . '~dup' . $i; |
|
||||||
} |
|
||||||
|
|
||||||
$pages[$id] = &$pageData; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event before_twig_register() |
|
||||||
* |
|
||||||
* @see DummyPlugin::onTwigRegistration() |
|
||||||
*/ |
|
||||||
public function onTwigRegistration() |
|
||||||
{ |
|
||||||
$this->triggerEvent('before_twig_register'); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Adds the deprecated variables rewrite_url and is_front_page, triggers |
|
||||||
* the deprecated event before_render($twigVariables, $twig, $templateName) |
|
||||||
* |
|
||||||
* Please note that the `before_render()` event gets `$templateName` passed |
|
||||||
* without its file extension. The file extension is later added again. |
|
||||||
* |
|
||||||
* @see DummyPlugin::onPageRendering() |
|
||||||
*/ |
|
||||||
public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName) |
|
||||||
{ |
|
||||||
// rewrite_url and is_front_page are deprecated since Pico 2.0 |
|
||||||
if (!isset($twigVariables['rewrite_url'])) { |
|
||||||
$twigVariables['rewrite_url'] = $this->isUrlRewritingEnabled(); |
|
||||||
} |
|
||||||
|
|
||||||
if (!isset($twigVariables['is_front_page'])) { |
|
||||||
$frontPage = $this->getConfig('content_dir') . 'index' . $this->getConfig('content_ext'); |
|
||||||
$twigVariables['is_front_page'] = ($this->getRequestFile() === $frontPage); |
|
||||||
} |
|
||||||
|
|
||||||
// template name contains file extension since Pico 1.0 |
|
||||||
$fileExtension = ''; |
|
||||||
if (($fileExtensionPos = strrpos($templateName, '.')) !== false) { |
|
||||||
$fileExtension = substr($templateName, $fileExtensionPos); |
|
||||||
$templateName = substr($templateName, 0, $fileExtensionPos); |
|
||||||
} |
|
||||||
|
|
||||||
$this->triggerEvent('before_render', array(&$twigVariables, &$twig, &$templateName)); |
|
||||||
|
|
||||||
// add original file extension |
|
||||||
$templateName = $templateName . $fileExtension; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers the deprecated event after_render($output) |
|
||||||
* |
|
||||||
* @see DummyPlugin::onPageRendered() |
|
||||||
*/ |
|
||||||
public function onPageRendered(&$output) |
|
||||||
{ |
|
||||||
$this->triggerEvent('after_render', array(&$output)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Triggers a deprecated event on all plugins |
|
||||||
* |
|
||||||
* Deprecated events are also triggered on plugins which implement |
|
||||||
* {@link PicoPluginInterface}. Please note that the methods are called |
|
||||||
* directly and not through {@link PicoPluginInterface::handleEvent()}. |
|
||||||
* |
|
||||||
* @param string $eventName event to trigger |
|
||||||
* @param array $params parameters to pass |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
protected function triggerEvent($eventName, array $params = array()) |
|
||||||
{ |
|
||||||
foreach ($this->getPlugins() as $plugin) { |
|
||||||
if (method_exists($plugin, $eventName)) { |
|
||||||
call_user_func_array(array($plugin, $eventName), $params); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,2 @@ |
|||||||
|
# This directory is meant to be empty |
||||||
|
* |
@ -1,23 +0,0 @@ |
|||||||
Icon fonts generator |
|
||||||
|
|
||||||
## Fontello |
|
||||||
|
|
||||||
Copyright (C) 2011 by Vitaly Puzrin |
|
||||||
|
|
||||||
Author: Vitaly Puzrin |
|
||||||
License: The MIT License <https://github.com/fontello/fontello/blob/master/LICENSE> |
|
||||||
Homepage: http://fontello.com/ |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Font license info |
|
||||||
|
|
||||||
## Font Awesome |
|
||||||
|
|
||||||
Copyright (C) 2012 by Dave Gandy |
|
||||||
|
|
||||||
Author: Dave Gandy |
|
||||||
License: SIL OFL 1.1 <http://scripts.sil.org/OFL> |
|
||||||
Homepage: http://fortawesome.github.com/Font-Awesome/ |
|
||||||
|
|
||||||
Icons: menu, github-circled ("octocat"), chat |
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,73 +0,0 @@ |
|||||||
<!DOCTYPE html> |
|
||||||
<html class="no-js"> |
|
||||||
<head> |
|
||||||
<meta charset="utf-8" /> |
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> |
|
||||||
|
|
||||||
<title>{% if meta.title %}{{ meta.title }} | {% endif %}{{ site_title }}</title> |
|
||||||
{% if meta.description %} |
|
||||||
<meta name="description" content="{{ meta.description|striptags }}" /> |
|
||||||
{% endif %}{% if meta.robots %} |
|
||||||
<meta name="robots" content="{{ meta.robots }}" /> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Droid+Sans:400,700|Droid+Sans+Mono" type="text/css" /> |
|
||||||
<link rel="stylesheet" href="{{ theme_url }}/style.css" type="text/css" /> |
|
||||||
<link rel="stylesheet" href="{{ theme_url }}/fontello.css" type="text/css" /> |
|
||||||
</head> |
|
||||||
<body{% if config.theme_config.widescreen %} class="widescreen"{% endif %}> |
|
||||||
|
|
||||||
<div id="header"> |
|
||||||
<div class="container"> |
|
||||||
<a id="nav-toggle" title="Toggle Menu" role="button" aria-controls="nav" aria-expanded="false" tabindex="1"> |
|
||||||
<span class="icon-menu" aria-hidden="true"></span> |
|
||||||
<span class="sr-only">Toggle Menu</span> |
|
||||||
</a> |
|
||||||
<h1> |
|
||||||
<a href="{{ "index"|link }}">{{ site_title }}</a> |
|
||||||
</h1> |
|
||||||
<div id="nav" role="region" tabindex="-1"> |
|
||||||
<ul> |
|
||||||
{% for page in pages if page.title and not page.hidden %} |
|
||||||
{% set pageDepth = page.id|split('/')|length %} |
|
||||||
{% if (pageDepth == 2) and (page.id ends with "/index") or (pageDepth == 1) %} |
|
||||||
<li{% if page.id == current_page.id %} class="active"{% endif %}> |
|
||||||
<a href="{{ page.url }}">{{ page.title }}</a> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
{% endfor %} |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div id="main"> |
|
||||||
<div class="container"> |
|
||||||
{{ content }} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div id="footer"> |
|
||||||
<div class="container"> |
|
||||||
<div class="social"> |
|
||||||
{% for social in pages._meta.meta.social %} |
|
||||||
<a href="{{ social.url }}" title="{{ social.title }}" role="button"> |
|
||||||
<span class="icon-{{ social.icon }}" aria-hidden="true"></span> |
|
||||||
<span class="sr-only">{{ social.title }}</span> |
|
||||||
</a> |
|
||||||
{% endfor %} |
|
||||||
</div> |
|
||||||
<p> |
|
||||||
<a href="http://picocms.org/">Pico</a> was made by <a href="http://gilbert.pellegrom.me">Gilbert Pellegrom</a> |
|
||||||
and is maintained by <a href="https://github.com/picocms/Pico/graphs/contributors">The Pico Community</a>. |
|
||||||
Released under the <a href="https://github.com/picocms/Pico/blob/master/LICENSE.md">MIT license</a>. |
|
||||||
</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<script src="{{ theme_url }}/js/modernizr-3.3.1-custom.min.js" type="text/javascript"></script> |
|
||||||
<script src="{{ theme_url }}/js/utils.js" type="text/javascript"></script> |
|
||||||
<script src="{{ theme_url }}/js/pico.js" type="text/javascript"></script> |
|
||||||
|
|
||||||
</body> |
|
||||||
</html> |
|
@ -1,3 +0,0 @@ |
|||||||
/*! modernizr 3.3.1 (Custom Build) | MIT * |
|
||||||
* https://modernizr.com/download/?-classlist-csstransitions-requestanimationframe !*/
|
|
||||||
!function(e,n,t){function r(e,n){return typeof e===n}function i(){var e,n,t,i,o,s,a;for(var f in y)if(y.hasOwnProperty(f)){if(e=[],n=y[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(i=r(n.fn,"function")?n.fn():n.fn,o=0;o<e.length;o++)s=e[o],a=s.split("."),1===a.length?Modernizr[a[0]]=i:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=i),C.push((i?"":"no-")+a.join("-"))}}function o(e){return e.replace(/([a-z])-([a-z])/g,function(e,n,t){return n+t.toUpperCase()}).replace(/^-/,"")}function s(e,n){return!!~(""+e).indexOf(n)}function a(e,n){return function(){return e.apply(n,arguments)}}function f(e,n,t){var i;for(var o in e)if(e[o]in n)return t===!1?e[o]:(i=n[e[o]],r(i,"function")?a(i,t||n):i);return!1}function l(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):T?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function u(e){return e.replace(/([A-Z])/g,function(e,n){return"-"+n.toLowerCase()}).replace(/^ms-/,"-ms-")}function d(){var e=n.body;return e||(e=l(T?"svg":"body"),e.fake=!0),e}function p(e,t,r,i){var o,s,a,f,u="modernizr",p=l("div"),c=d();if(parseInt(r,10))for(;r--;)a=l("div"),a.id=i?i[r]:u+(r+1),p.appendChild(a);return o=l("style"),o.type="text/css",o.id="s"+u,(c.fake?c:p).appendChild(o),c.appendChild(p),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(n.createTextNode(e)),p.id=u,c.fake&&(c.style.background="",c.style.overflow="hidden",f=w.style.overflow,w.style.overflow="hidden",w.appendChild(c)),s=t(p,e),c.fake?(c.parentNode.removeChild(c),w.style.overflow=f,w.offsetHeight):p.parentNode.removeChild(p),!!s}function c(n,r){var i=n.length;if("CSS"in e&&"supports"in e.CSS){for(;i--;)if(e.CSS.supports(u(n[i]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var o=[];i--;)o.push("("+u(n[i])+":"+r+")");return o=o.join(" or "),p("@supports ("+o+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return t}function m(e,n,i,a){function f(){d&&(delete P.style,delete P.modElem)}if(a=r(a,"undefined")?!1:a,!r(i,"undefined")){var u=c(e,i);if(!r(u,"undefined"))return u}for(var d,p,m,v,h,y=["modernizr","tspan","samp"];!P.style&&y.length;)d=!0,P.modElem=l(y.shift()),P.style=P.modElem.style;for(m=e.length,p=0;m>p;p++)if(v=e[p],h=P.style[v],s(v,"-")&&(v=o(v)),P.style[v]!==t){if(a||r(i,"undefined"))return f(),"pfx"==n?v:!0;try{P.style[v]=i}catch(g){}if(P.style[v]!=h)return f(),"pfx"==n?v:!0}return f(),!1}function v(e,n,t,i,o){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+_.join(s+" ")+s).split(" ");return r(n,"string")||r(n,"undefined")?m(a,n,i,o):(a=(e+" "+E.join(s+" ")+s).split(" "),f(a,n,t))}function h(e,n,r){return v(e,t,t,n,r)}var y=[],g={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){y.push({name:e,fn:n,options:t})},addAsyncTest:function(e){y.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=g,Modernizr=new Modernizr;var C=[],w=n.documentElement;Modernizr.addTest("classlist","classList"in w);var x="Moz O ms Webkit",_=g._config.usePrefixes?x.split(" "):[];g._cssomPrefixes=_;var S=function(n){var r,i=prefixes.length,o=e.CSSRule;if("undefined"==typeof o)return t;if(!n)return!1;if(n=n.replace(/^@/,""),r=n.replace(/-/g,"_").toUpperCase()+"_RULE",r in o)return"@"+n;for(var s=0;i>s;s++){var a=prefixes[s],f=a.toUpperCase()+"_"+r;if(f in o)return"@-"+a.toLowerCase()+"-"+n}return!1};g.atRule=S;var E=g._config.usePrefixes?x.toLowerCase().split(" "):[];g._domPrefixes=E;var T="svg"===w.nodeName.toLowerCase(),z={elem:l("modernizr")};Modernizr._q.push(function(){delete z.elem});var P={style:z.elem.style};Modernizr._q.unshift(function(){delete P.style}),g.testAllProps=v;var b=g.prefixed=function(e,n,t){return 0===e.indexOf("@")?S(e):(-1!=e.indexOf("-")&&(e=o(e)),n?v(e,n,t):v(e,"pfx"))};Modernizr.addTest("requestanimationframe",!!b("requestAnimationFrame",e),{aliases:["raf"]}),g.testAllProps=h,Modernizr.addTest("csstransitions",h("transition","all",!0)),i(),delete g.addTest,delete g.addAsyncTest;for(var L=0;L<Modernizr._q.length;L++)Modernizr._q[L]();e.Modernizr=Modernizr}(window,document); |
|
@ -1,70 +0,0 @@ |
|||||||
/** |
|
||||||
* Pico's Default Theme - JavaScript helper |
|
||||||
* |
|
||||||
* Pico is a stupidly simple, blazing fast, flat file CMS. |
|
||||||
* |
|
||||||
* @author Daniel Rudolf |
|
||||||
* @link http://picocms.org
|
|
||||||
* @license http://opensource.org/licenses/MIT The MIT License
|
|
||||||
* @version 2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
function main() |
|
||||||
{ |
|
||||||
// capability CSS classes
|
|
||||||
document.documentElement.className = 'js'; |
|
||||||
|
|
||||||
// wrap tables
|
|
||||||
var tables = document.querySelectorAll('#main > .container > table'); |
|
||||||
for (var i = 0; i < tables.length; i++) { |
|
||||||
if (!/\btable-responsive\b/.test(tables[i].parentElement.className)) { |
|
||||||
var tableWrapper = document.createElement('div'); |
|
||||||
tableWrapper.className = 'table-responsive'; |
|
||||||
|
|
||||||
tables[i].parentElement.insertBefore(tableWrapper, tables[i]); |
|
||||||
tableWrapper.appendChild(tables[i]); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// responsive menu
|
|
||||||
var menu = document.getElementById('nav'), |
|
||||||
menuToggle = document.getElementById('nav-toggle'), |
|
||||||
toggleMenuEvent = function (event) { |
|
||||||
if (event.type === 'keydown') { |
|
||||||
if ((event.keyCode != 13) && (event.keyCode != 32)) { |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
event.preventDefault(); |
|
||||||
|
|
||||||
if (menuToggle.getAttribute('aria-expanded') === 'false') { |
|
||||||
menuToggle.setAttribute('aria-expanded', 'true'); |
|
||||||
utils.slideDown(menu, null, function () { |
|
||||||
if (event.type === 'keydown') { |
|
||||||
menu.focus(); |
|
||||||
} |
|
||||||
}); |
|
||||||
} else { |
|
||||||
menuToggle.setAttribute('aria-expanded', 'false'); |
|
||||||
utils.slideUp(menu); |
|
||||||
} |
|
||||||
}, |
|
||||||
onResizeEvent = function () { |
|
||||||
if (utils.isElementVisible(menuToggle)) { |
|
||||||
menu.className = 'hidden'; |
|
||||||
menuToggle.addEventListener('click', toggleMenuEvent); |
|
||||||
menuToggle.addEventListener('keydown', toggleMenuEvent); |
|
||||||
} else { |
|
||||||
menu.className = ''; |
|
||||||
menu.removeAttribute('data-slide-id'); |
|
||||||
menuToggle.removeEventListener('click', toggleMenuEvent); |
|
||||||
menuToggle.removeEventListener('keydown', toggleMenuEvent); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
window.addEventListener('resize', onResizeEvent); |
|
||||||
onResizeEvent(); |
|
||||||
} |
|
||||||
|
|
||||||
main(); |
|
@ -1,135 +0,0 @@ |
|||||||
/** |
|
||||||
* Pico's Default Theme - JavaScript helper |
|
||||||
* |
|
||||||
* Pico is a stupidly simple, blazing fast, flat file CMS. |
|
||||||
* |
|
||||||
* @author Daniel Rudolf |
|
||||||
* @link http://picocms.org
|
|
||||||
* @license http://opensource.org/licenses/MIT The MIT License
|
|
||||||
* @version 2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
utils = {}; |
|
||||||
|
|
||||||
/** |
|
||||||
* Checks whether the client's browser is able to slide elements or not |
|
||||||
* |
|
||||||
* @return boolean TRUE when the browser supports sliding, FALSE otherwise |
|
||||||
*/ |
|
||||||
utils.canSlide = function () |
|
||||||
{ |
|
||||||
return (Modernizr.classlist && Modernizr.requestanimationframe && Modernizr.csstransitions); |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* Slides a element up (i.e. hide a element by changing its height to 0px) |
|
||||||
* |
|
||||||
* @param HTMLElement element the element to slide up |
|
||||||
* @param function finishCallback function to call when the animation has |
|
||||||
* been finished (i.e. the element is hidden) |
|
||||||
* @param function startCallback function to call when the animation starts |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
utils.slideUp = function (element, finishCallback, startCallback) |
|
||||||
{ |
|
||||||
if (!utils.canSlide()) { |
|
||||||
if (startCallback) startCallback(); |
|
||||||
element.className += (element.className !== '') ? ' hidden' : 'hidden'; |
|
||||||
if (finishCallback) window.requestAnimationFrame(finishCallback); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
element.style.height = element.clientHeight + 'px'; |
|
||||||
|
|
||||||
var slideId = parseInt(element.getAttribute('data-slide-id')) || 0; |
|
||||||
element.setAttribute('data-slide-id', ++slideId); |
|
||||||
|
|
||||||
window.requestAnimationFrame(function () { |
|
||||||
element.classList.add('slide'); |
|
||||||
|
|
||||||
window.requestAnimationFrame(function () { |
|
||||||
element.style.height = '0px'; |
|
||||||
|
|
||||||
if (startCallback) { |
|
||||||
startCallback(); |
|
||||||
} |
|
||||||
|
|
||||||
window.setTimeout(function () { |
|
||||||
if (parseInt(element.getAttribute('data-slide-id')) !== slideId) return; |
|
||||||
|
|
||||||
element.classList.add('hidden'); |
|
||||||
element.classList.remove('slide'); |
|
||||||
element.style.height = null; |
|
||||||
|
|
||||||
if (finishCallback) { |
|
||||||
window.requestAnimationFrame(finishCallback); |
|
||||||
} |
|
||||||
}, 500); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* Slides a element down (i.e. show a hidden element) |
|
||||||
* |
|
||||||
* @param HTMLElement element the element to slide down |
|
||||||
* @param function finishCallback function to call when the animation has |
|
||||||
* been finished (i.e. the element is visible) |
|
||||||
* @param function startCallback function to call when the animation starts |
|
||||||
* @return void |
|
||||||
*/ |
|
||||||
utils.slideDown = function (element, finishCallback, startCallback) |
|
||||||
{ |
|
||||||
if (!utils.canSlide()) { |
|
||||||
if (startCallback) startCallback(); |
|
||||||
element.className = element.className.replace(/\bhidden\b */g, ''); |
|
||||||
if (finishCallback) window.requestAnimationFrame(finishCallback); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
var cssRuleOriginalValue = element.clientHeight + 'px', |
|
||||||
slideId = parseInt(element.getAttribute('data-slide-id')) || 0; |
|
||||||
|
|
||||||
element.setAttribute('data-slide-id', ++slideId); |
|
||||||
|
|
||||||
element.style.height = null; |
|
||||||
element.classList.remove('hidden'); |
|
||||||
element.classList.remove('slide'); |
|
||||||
var cssRuleValue = element.clientHeight + 'px'; |
|
||||||
|
|
||||||
element.style.height = cssRuleOriginalValue; |
|
||||||
|
|
||||||
window.requestAnimationFrame(function () { |
|
||||||
element.classList.add('slide'); |
|
||||||
|
|
||||||
window.requestAnimationFrame(function () { |
|
||||||
element.style.height = cssRuleValue; |
|
||||||
|
|
||||||
if (startCallback) { |
|
||||||
startCallback(); |
|
||||||
} |
|
||||||
|
|
||||||
window.setTimeout(function () { |
|
||||||
if (parseInt(element.getAttribute('data-slide-id')) !== slideId) return; |
|
||||||
|
|
||||||
element.classList.remove('slide'); |
|
||||||
element.style.height = null; |
|
||||||
|
|
||||||
if (finishCallback) { |
|
||||||
window.requestAnimationFrame(finishCallback); |
|
||||||
} |
|
||||||
}, 500); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* Checks whether a element is visible or not |
|
||||||
* |
|
||||||
* @param HTMLElement element the element to check |
|
||||||
* @return boolean TRUE when the element is visible, FALSE otherwise |
|
||||||
*/ |
|
||||||
utils.isElementVisible = function (element) |
|
||||||
{ |
|
||||||
return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); |
|
||||||
}; |
|
@ -1,357 +0,0 @@ |
|||||||
/** |
|
||||||
* Pico's Default Theme |
|
||||||
* |
|
||||||
* Pico's default theme is a bit bare - but that's intentional! The default |
|
||||||
* theme isn't meant for production use, it's actually a template for you to |
|
||||||
* design your own theme around. |
|
||||||
* |
|
||||||
* Pico is a stupidly simple, blazing fast, flat file CMS. |
|
||||||
* |
|
||||||
* @author Gilbert Pellegrom |
|
||||||
* @author Daniel Rudolf |
|
||||||
* @link http://picocms.org |
|
||||||
* @license http://opensource.org/licenses/MIT The MIT License |
|
||||||
* @version 2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
* { |
|
||||||
box-sizing: border-box; |
|
||||||
border: 0 none; |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
} |
|
||||||
|
|
||||||
.hidden { display: none !important; } |
|
||||||
.sr-only { |
|
||||||
position: absolute; |
|
||||||
width: 1px; |
|
||||||
height: 1px; |
|
||||||
padding: 0; |
|
||||||
margin: -1px; |
|
||||||
overflow: hidden; |
|
||||||
clip: rect(0, 0, 0, 0); |
|
||||||
border: 0 none; |
|
||||||
} |
|
||||||
|
|
||||||
.slide { |
|
||||||
overflow-y: hidden !important; |
|
||||||
-webkit-transition: height .5s ease-in !important; |
|
||||||
transition: height .5s ease-in !important; |
|
||||||
} |
|
||||||
|
|
||||||
/*** BASIC LAYOUT ***/ |
|
||||||
|
|
||||||
html, body { height: 100%; } |
|
||||||
|
|
||||||
body { display: flex; flex-direction: column; } |
|
||||||
#main { flex: 1 0 auto; } |
|
||||||
#header, #footer { flex: 0 0 auto; } |
|
||||||
|
|
||||||
#main { |
|
||||||
padding: 5em 0 4em; |
|
||||||
} |
|
||||||
|
|
||||||
.container { |
|
||||||
max-width: 48em; |
|
||||||
padding: 0 0.5em; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
.widescreen .container { max-width: 72em; } |
|
||||||
|
|
||||||
/* very ugly overflow fix, avoid this whenever possible! */ |
|
||||||
#main .container { overflow-x: auto; } |
|
||||||
|
|
||||||
/*** BASIC LAYOUT: HEADER ***/ |
|
||||||
|
|
||||||
#header { background: #2EAE9B; } |
|
||||||
|
|
||||||
#header h1 { |
|
||||||
float: left; |
|
||||||
font-size: 2rem; |
|
||||||
margin: 0; |
|
||||||
padding: 1.5em 1em 1.5em 0; |
|
||||||
} |
|
||||||
#header h1 a, #header h1 a:hover { color: #fff; } |
|
||||||
|
|
||||||
#nav { |
|
||||||
text-align: right; |
|
||||||
padding: 3em 0; |
|
||||||
} |
|
||||||
#nav ul { |
|
||||||
list-style: none; |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
} |
|
||||||
#nav ul li { |
|
||||||
display: inline-block; |
|
||||||
margin-left: 1em; |
|
||||||
padding: 0; |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
|
|
||||||
#nav a, #nav-toggle { color: #afe1da; } |
|
||||||
#nav .active a, #nav a:hover, #nav-toggle:hover { color: #fff; } |
|
||||||
|
|
||||||
#nav-toggle { display: none; } |
|
||||||
|
|
||||||
/* IE8 + IE9 clearfix */ |
|
||||||
#header > .container:after { |
|
||||||
content: ''; |
|
||||||
display: block; |
|
||||||
clear: both; |
|
||||||
} |
|
||||||
|
|
||||||
/*** BASIC LAYOUT: FOOTER ***/ |
|
||||||
|
|
||||||
#footer { |
|
||||||
background: #707070; |
|
||||||
color: #C0C0C0; |
|
||||||
} |
|
||||||
|
|
||||||
#footer a { color: #ddd; } |
|
||||||
#footer a:hover { color: #fff; } |
|
||||||
|
|
||||||
#footer p { |
|
||||||
margin: 0; |
|
||||||
padding: 3em 0; |
|
||||||
} |
|
||||||
|
|
||||||
#footer .social { |
|
||||||
float: right; |
|
||||||
padding: 1.5em 0 1.5em 1em; |
|
||||||
font-size: 2rem; |
|
||||||
} |
|
||||||
|
|
||||||
/*** BASIC LAYOUT: EXTRA SMALL DEVICES ***/ |
|
||||||
|
|
||||||
@media (max-width: 767px) { |
|
||||||
#main { padding: 2em 0 1em; } |
|
||||||
|
|
||||||
#header h1 { |
|
||||||
float: none; |
|
||||||
padding: 0.5em 0; |
|
||||||
} |
|
||||||
|
|
||||||
#nav { |
|
||||||
clear: right; |
|
||||||
padding: 0; |
|
||||||
} |
|
||||||
#nav ul { |
|
||||||
padding-bottom: 1em; |
|
||||||
} |
|
||||||
#nav ul li { |
|
||||||
display: block; |
|
||||||
margin-left: 0; |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
#nav ul li a { |
|
||||||
display: block; |
|
||||||
padding: 0.5em 0; |
|
||||||
} |
|
||||||
|
|
||||||
.js #nav-toggle { |
|
||||||
display: block; |
|
||||||
float: right; |
|
||||||
width: 2em; |
|
||||||
margin: 0.6667em 0 0.6667em 1.3333em; |
|
||||||
font-size: 1.5rem; |
|
||||||
line-height: 2em; |
|
||||||
text-align: center; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
.js #nav-toggle > * { vertical-align: middle; } |
|
||||||
|
|
||||||
#footer p { padding: 1em 0; } |
|
||||||
#footer .social { padding: 0.5em 0 0.5em 1em; } |
|
||||||
} |
|
||||||
|
|
||||||
/*** TYPOGRAPHY ***/ |
|
||||||
|
|
||||||
html { font-size: 16px; } |
|
||||||
|
|
||||||
body { |
|
||||||
font-family: 'Droid Sans', 'Helvetica', 'Arial', sans-serif; |
|
||||||
font-size: 1rem; |
|
||||||
line-height: 1.6; |
|
||||||
font-variant-ligatures: common-ligatures; |
|
||||||
text-rendering: optimizeLegibility; |
|
||||||
font-kerning: normal; |
|
||||||
color: #444; |
|
||||||
} |
|
||||||
|
|
||||||
p, td, th, li, dd { |
|
||||||
text-align: justify; |
|
||||||
overflow-wrap: break-word; |
|
||||||
word-wrap: break-word; |
|
||||||
} |
|
||||||
|
|
||||||
p, hr, table, .table-responsive, ol, ul, dl, pre, blockquote, fieldset { |
|
||||||
margin-bottom: 1em; |
|
||||||
} |
|
||||||
|
|
||||||
a { |
|
||||||
color: #2EAE9B; |
|
||||||
text-decoration: none; |
|
||||||
-webkit-transition: color .2s ease-in; |
|
||||||
transition: color .2s ease-in; |
|
||||||
} |
|
||||||
a:hover { color: #444; } |
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 { |
|
||||||
margin-bottom: 0.6em; |
|
||||||
font-weight: bold; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
h1 { font-size: 2rem; } |
|
||||||
h2 { font-size: 1.7rem; } |
|
||||||
h3 { font-size: 1.4rem; } |
|
||||||
h4 { font-size: 1.1rem; } |
|
||||||
h5 { font-size: 1rem; } |
|
||||||
h6 { font-size: 1rem; font-weight: normal; font-style: italic; } |
|
||||||
|
|
||||||
img { max-width: 100%; } |
|
||||||
|
|
||||||
hr { |
|
||||||
border: 0.15em solid #f5f5f5; |
|
||||||
border-radius: 0.3em; |
|
||||||
background: #f5f5f5; |
|
||||||
} |
|
||||||
|
|
||||||
abbr { text-decoration: underline dotted; } |
|
||||||
|
|
||||||
/*** TABLES ***/ |
|
||||||
|
|
||||||
table { border-spacing: 0; } |
|
||||||
|
|
||||||
td, th { |
|
||||||
padding: 0.4em 1em; |
|
||||||
vertical-align: top; |
|
||||||
} |
|
||||||
th { |
|
||||||
font-weight: bold; |
|
||||||
text-align: center; |
|
||||||
background: #f5f5f5; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
|
|
||||||
td, th { border: solid 1px #ccc; } |
|
||||||
tr:not(:last-child) td, tr:not(:last-child) th { border-bottom: 0 none; } |
|
||||||
thead tr:last-child th { border-bottom: 0 none; } |
|
||||||
td:not(:last-child), th:not(:last-child) { border-right: 0 none; } |
|
||||||
|
|
||||||
tr:first-child td:first-child, tr:first-child th:first-child { border-top-left-radius: 0.3em; } |
|
||||||
tr:first-child td:last-child, tr:first-child th:last-child { border-top-right-radius: 0.3em; } |
|
||||||
tbody tr:last-child td:first-child { border-bottom-left-radius: 0.3em; } |
|
||||||
tbody tr:last-child td:last-child { border-bottom-right-radius: 0.3em; } |
|
||||||
table thead + tbody tr:first-child td { border-radius: 0 !important; } |
|
||||||
|
|
||||||
.table-responsive { overflow-x: auto; } |
|
||||||
.table-responsive > table { margin-bottom: 0; } |
|
||||||
|
|
||||||
/*** LISTS ***/ |
|
||||||
|
|
||||||
ol, ul { |
|
||||||
list-style-position: outside; |
|
||||||
padding-left: 1.5em; |
|
||||||
} |
|
||||||
ol { padding-left: 2.5em; } |
|
||||||
li { padding-left: 0.5em; } |
|
||||||
|
|
||||||
dt { font-weight: bold; } |
|
||||||
dd { margin-left: 2em; } |
|
||||||
|
|
||||||
/*** CODE ***/ |
|
||||||
|
|
||||||
code { |
|
||||||
margin: 0 0.1em; |
|
||||||
padding: 0.1em 0.2em; |
|
||||||
border: 1px solid #ccc; |
|
||||||
border-radius: 0.3em; |
|
||||||
background: #f5f5f5; |
|
||||||
font-family: 'Droid Sans Mono', 'Courier New', 'Courier', monospace; |
|
||||||
font-size: 0.9rem; |
|
||||||
} |
|
||||||
|
|
||||||
pre { |
|
||||||
padding: 0 1em; |
|
||||||
border: 1px solid #ccc; |
|
||||||
border-radius: 0.3em; |
|
||||||
background: #f5f5f5; |
|
||||||
line-height: 1.4; |
|
||||||
} |
|
||||||
pre code { |
|
||||||
display: block; |
|
||||||
margin: 0; |
|
||||||
padding: 1.1111em 0; |
|
||||||
border: 0 none; |
|
||||||
background: transparent; |
|
||||||
overflow-x: auto; |
|
||||||
} |
|
||||||
|
|
||||||
/*** BLOCKQUOTE ***/ |
|
||||||
|
|
||||||
blockquote { |
|
||||||
font-style: italic; |
|
||||||
margin-left: 1em; |
|
||||||
padding-left: 1em; |
|
||||||
border-left: 0.5em solid #f5f5f5; |
|
||||||
} |
|
||||||
|
|
||||||
/*** FORMS ***/ |
|
||||||
|
|
||||||
label, fieldset legend { font-weight: bold; } |
|
||||||
|
|
||||||
input:not([type="checkbox"]):not([type="radio"]), button, select, textarea, fieldset, fieldset legend { |
|
||||||
border: solid 1px #ccc; |
|
||||||
border-radius: 0.3em; |
|
||||||
background: #fff; |
|
||||||
-webkit-transition: none .2s ease-in; |
|
||||||
transition: none .2s ease-in; |
|
||||||
-webkit-transition-property: border-color, background, box-shadow; |
|
||||||
transition-property: border-color, background, box-shadow; |
|
||||||
} |
|
||||||
|
|
||||||
input:not([type="checkbox"]):not([type="radio"]), button, select, textarea { |
|
||||||
padding: 0.5em 1em; |
|
||||||
outline: 0 none; |
|
||||||
font-size: 1rem; |
|
||||||
} |
|
||||||
input:focus:not([type="checkbox"]):not([type="radio"]), button:focus, select:focus, textarea:focus { |
|
||||||
border-color: #2EAE9B; |
|
||||||
box-shadow: 0 0 8px #2EAE9B; |
|
||||||
} |
|
||||||
input[type="button"]:focus, input[type="submit"]:focus, input[type="reset"]:focus, button:focus, |
|
||||||
input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover, button:hover { |
|
||||||
background: #f5f5f5; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
|
|
||||||
textarea, select[multiple] { |
|
||||||
vertical-align: bottom; |
|
||||||
overflow: auto; |
|
||||||
} |
|
||||||
|
|
||||||
fieldset { |
|
||||||
padding: 1em; |
|
||||||
background: #f5f5f5; |
|
||||||
} |
|
||||||
fieldset legend { padding: 0 0.5em; } |
|
||||||
|
|
||||||
fieldset label, fieldset input, fieldset button, |
|
||||||
fieldset select, fieldset textarea { |
|
||||||
margin: 0.2em 0.5em; |
|
||||||
} |
|
||||||
fieldset label:first-child, fieldset input:first-child, fieldset button:first-child, |
|
||||||
fieldset select:first-child, fieldset textarea:first-child { |
|
||||||
margin-left: 0; |
|
||||||
} |
|
||||||
fieldset label:last-child, fieldset input:last-child, fieldset button:last-child, |
|
||||||
fieldset select:last-child, fieldset textarea:last-child { |
|
||||||
margin-right: 0; |
|
||||||
} |
|
||||||
|
|
||||||
/* Firefox input size fix */ |
|
||||||
input::-moz-focus-inner, button::-moz-focus-inner { |
|
||||||
border: 0; |
|
||||||
padding: 0; |
|
||||||
} |
|
Loading…
Reference in new issue