Browse Source

Site data

Alexandre MOTTIER 3 years ago
parent
commit
4ee1701ee2
100 changed files with 10530 additions and 0 deletions
  1. 0 0
      images/.gitkeep
  2. 35 0
      system/config/site.yaml
  3. 204 0
      system/config/system.yaml
  4. 20 0
      user/pages/01.bienvenue/default.md
  5. 27 0
      user/pages/02.a-propos/default.md
  6. 5 0
      user/pages/03.blog/default.md
  7. 43 0
      user/pages/04.services/default.md
  8. 5 0
      user/pages/05.liste des services/01.privatebin/default.md
  9. 5 0
      user/pages/05.liste des services/02.gitlab/default.md
  10. 5 0
      user/pages/05.liste des services/03.element/default.md
  11. 5 0
      user/pages/05.liste des services/04.i-hate-money/default.md
  12. 5 0
      user/pages/05.liste des services/05.nextcloud/default.md
  13. 5 0
      user/pages/05.liste des services/06.bitwarden/default.md
  14. 5 0
      user/pages/05.liste des services/07.webmail/default.md
  15. 38 0
      user/pages/06.mentions-legales/default.md
  16. 0 0
      user/themes/.gitkeep
  17. 177 0
      user/themes/quark/CHANGELOG.md
  18. 21 0
      user/themes/quark/LICENSE
  19. 152 0
      user/themes/quark/README.md
  20. BIN
      user/themes/quark/assets/quark-screenshots.jpg
  21. 176 0
      user/themes/quark/blueprints.yaml
  22. 94 0
      user/themes/quark/blueprints/blog.yaml
  23. 15 0
      user/themes/quark/blueprints/default.yaml
  24. 113 0
      user/themes/quark/blueprints/item.yaml
  25. 38 0
      user/themes/quark/blueprints/modular/features.yaml
  26. 23 0
      user/themes/quark/blueprints/modular/hero.yaml
  27. 19 0
      user/themes/quark/blueprints/modular/text.yaml
  28. 64 0
      user/themes/quark/blueprints/partials/blog-bits.yaml
  29. 369 0
      user/themes/quark/css-compiled/spectre-exp.css
  30. 1 0
      user/themes/quark/css-compiled/spectre-exp.min.css
  31. 172 0
      user/themes/quark/css-compiled/spectre-icons.css
  32. 1 0
      user/themes/quark/css-compiled/spectre-icons.min.css
  33. 1257 0
      user/themes/quark/css-compiled/spectre.css
  34. 1 0
      user/themes/quark/css-compiled/spectre.min.css
  35. 406 0
      user/themes/quark/css-compiled/theme.css
  36. 1 0
      user/themes/quark/css-compiled/theme.min.css
  37. 49 0
      user/themes/quark/css/bricklayer.css
  38. 0 0
      user/themes/quark/css/custom.css
  39. 4 0
      user/themes/quark/css/line-awesome.min.css
  40. BIN
      user/themes/quark/fonts/line-awesome.eot
  41. 2954 0
      user/themes/quark/fonts/line-awesome.svg
  42. BIN
      user/themes/quark/fonts/line-awesome.ttf
  43. BIN
      user/themes/quark/fonts/line-awesome.woff
  44. BIN
      user/themes/quark/fonts/line-awesome.woff2
  45. 43 0
      user/themes/quark/gulpfile.js
  46. BIN
      user/themes/quark/images/favicon-old.png
  47. BIN
      user/themes/quark/images/favicon.png
  48. 1 0
      user/themes/quark/images/grav-logo.svg
  49. 0 0
      user/themes/quark/images/logo/.gitkeep
  50. BIN
      user/themes/quark/images/logo/cropped-90E192D6-7E17-421D-B6C7-A9A615C3B734-1-1.png
  51. BIN
      user/themes/quark/images/logo/cropped-90E192D6-7E17-421D-B6C7-A9A615C3B734-1.png
  52. 1 0
      user/themes/quark/js/bricklayer.min.js
  53. 87 0
      user/themes/quark/js/jquery.treemenu.js
  54. 9 0
      user/themes/quark/js/scopedQuerySelectorShim.min.js
  55. 8 0
      user/themes/quark/js/singlepagenav.min.js
  56. 59 0
      user/themes/quark/js/site.js
  57. 6 0
      user/themes/quark/js/smooth-scroll.min.js
  58. 288 0
      user/themes/quark/languages.yaml
  59. 49 0
      user/themes/quark/package.json
  60. 56 0
      user/themes/quark/quark.php
  61. 12 0
      user/themes/quark/quark.yaml
  62. BIN
      user/themes/quark/screenshot.jpg
  63. 19 0
      user/themes/quark/scss/spectre-exp.scss
  64. 11 0
      user/themes/quark/scss/spectre-icons.scss
  65. 53 0
      user/themes/quark/scss/spectre.scss
  66. 38 0
      user/themes/quark/scss/spectre/_accordions.scss
  67. 20 0
      user/themes/quark/scss/spectre/_animations.scss
  68. 43 0
      user/themes/quark/scss/spectre/_asian.scss
  69. 47 0
      user/themes/quark/scss/spectre/_autocomplete.scss
  70. 77 0
      user/themes/quark/scss/spectre/_avatars.scss
  71. 60 0
      user/themes/quark/scss/spectre/_badges.scss
  72. 71 0
      user/themes/quark/scss/spectre/_bars.scss
  73. 44 0
      user/themes/quark/scss/spectre/_base.scss
  74. 29 0
      user/themes/quark/scss/spectre/_breadcrumbs.scss
  75. 193 0
      user/themes/quark/scss/spectre/_buttons.scss
  76. 222 0
      user/themes/quark/scss/spectre/_calendars.scss
  77. 43 0
      user/themes/quark/scss/spectre/_cards.scss
  78. 136 0
      user/themes/quark/scss/spectre/_carousels.scss
  79. 33 0
      user/themes/quark/scss/spectre/_chips.scss
  80. 31 0
      user/themes/quark/scss/spectre/_codes.scss
  81. 115 0
      user/themes/quark/scss/spectre/_comparison-sliders.scss
  82. 36 0
      user/themes/quark/scss/spectre/_dropdowns.scss
  83. 21 0
      user/themes/quark/scss/spectre/_empty.scss
  84. 37 0
      user/themes/quark/scss/spectre/_filters.scss
  85. 555 0
      user/themes/quark/scss/spectre/_forms.scss
  86. 22 0
      user/themes/quark/scss/spectre/_hero.scss
  87. 5 0
      user/themes/quark/scss/spectre/_icons.scss
  88. 34 0
      user/themes/quark/scss/spectre/_labels.scss
  89. 444 0
      user/themes/quark/scss/spectre/_layout.scss
  90. 75 0
      user/themes/quark/scss/spectre/_media.scss
  91. 66 0
      user/themes/quark/scss/spectre/_menus.scss
  92. 57 0
      user/themes/quark/scss/spectre/_meters.scss
  93. 10 0
      user/themes/quark/scss/spectre/_mixins.scss
  94. 87 0
      user/themes/quark/scss/spectre/_modals.scss
  95. 28 0
      user/themes/quark/scss/spectre/_navbar.scss
  96. 34 0
      user/themes/quark/scss/spectre/_navs.scss
  97. 446 0
      user/themes/quark/scss/spectre/_normalize.scss
  98. 95 0
      user/themes/quark/scss/spectre/_off-canvas.scss
  99. 60 0
      user/themes/quark/scss/spectre/_pagination.scss
  100. 0 0
      user/themes/quark/scss/spectre/_panels.scss

+ 0 - 0
images/.gitkeep


+ 35 - 0
system/config/site.yaml

@@ -0,0 +1,35 @@
+title: Grav                                 # Name of the site
+default_lang: en                            # Default language for site (potentially used by theme)
+
+author:
+  name: John Appleseed                      # Default author name
+  email: 'john@example.com'                 # Default author email
+
+taxonomies: [category,tag]                  # Arbitrary list of taxonomy types
+
+metadata:
+  description: 'My Grav Site'               # Site description
+
+summary:
+  enabled: true                             # enable or disable summary of page
+  format: short                             # long = summary delimiter will be ignored; short = use the first occurrence of delimiter or size
+  size: 300                                 # Maximum length of summary (characters)
+  delimiter: ===                            # The summary delimiter
+
+redirects:
+#  '/redirect-test': '/'                    # Redirect test goes to home page
+#  '/old/(.*)': '/new/$1'                   # Would redirect /old/my-page to /new/my-page
+
+routes:
+#  '/something/else': '/blog/sample-3'      # Alias for /blog/sample-3
+#  '/new/(.*)': '/blog/$1'                  # Regex any /new/my-page URL to /blog/my-page Route
+
+blog:
+  route: '/blog'                            # Custom value added (accessible via system.blog.route)
+
+#menu:                                      # Menu Example
+#    - text: Source
+#      icon: github
+#      url: https://github.com/getgrav/grav
+#    - icon: twitter
+#      url: http://twitter.com/getgrav

+ 204 - 0
system/config/system.yaml

@@ -0,0 +1,204 @@
+absolute_urls: false                             # Absolute or relative URLs for `base_url`
+timezone: ''                                     # Valid values: http://php.net/manual/en/timezones.php
+default_locale:                                  # Default locale (defaults to system)
+param_sep: ':'                                   # Parameter separator, use ';' for Apache on windows
+wrapped_site: false                              # For themes/plugins to know if Grav is wrapped by another platform
+reverse_proxy_setup: false                       # Running in a reverse proxy scenario with different webserver ports than proxy
+force_ssl: false                                 # If enabled, Grav forces to be accessed via HTTPS (NOTE: Not an ideal solution)
+force_lowercase_urls: true                       # If you want to support mixed cased URLs set this to false
+custom_base_url: ''                              # Set the base_url manually, e.g. http://yoursite.com/yourpath
+username_regex: '^[a-z0-9_-]{3,16}$'             # Only lowercase chars, digits, dashes, underscores. 3 - 16 chars
+pwd_regex: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' # At least one number, one uppercase and lowercase letter, and be at least 8+ chars
+intl_enabled: true                               # Special logic for PHP International Extension (mod_intl)
+http_x_forwarded:                                # Configuration options for the various HTTP_X_FORWARD headers
+  protocol: true
+  host: false
+  port: true
+  ip: true
+
+languages:
+  supported: []                                  # List of languages supported. eg: [en, fr, de]
+  default_lang:                                  # Default is the first supported language. Must be one of the supported languages
+  include_default_lang: true                     # Include the default lang prefix in all URLs
+  include_default_lang_file_extension: true      # If true, include language code for the default language in file extension: default.en.md
+  translations: true                             # If false, translation keys are used instead of translated strings
+  translations_fallback: true                    # Fallback through supported translations if active lang doesn't exist
+  session_store_active: false                    # Store active language in session
+  http_accept_language: false                    # Attempt to set the language based on http_accept_language header in the browser
+  override_locale: false                         # Override the default or system locale with language specific one
+  content_fallback: {}                           # Custom language fallbacks. eg: {fr: ['fr', 'en']}
+  pages_fallback_only: false                     # DEPRECATED: Use `content_fallback` instead
+
+home:
+  alias: '/home'                                 # Default path for home, ie /
+  hide_in_urls: false                            # Hide the home route in URLs
+
+pages:
+  type: regular                                  # EXPERIMENTAL: Page type: regular or flex
+  theme: quark                                   # Default theme (defaults to "quark" theme)
+  order:
+    by: default                                  # Order pages by "default", "alpha" or "date"
+    dir: asc                                     # Default ordering direction, "asc" or "desc"
+  list:
+    count: 20                                    # Default item count per page
+  dateformat:
+    default:                                     # The default date format Grav expects in the `date: ` field
+    short: 'jS M Y'                              # Short date format
+    long: 'F jS \a\t g:ia'                       # Long date format
+  publish_dates: true                            # automatically publish/unpublish based on dates
+  process:
+    markdown: true                               # Process Markdown
+    twig: false                                  # Process Twig
+  twig_first: false                              # Process Twig before markdown when processing both on a page
+  never_cache_twig: false                        # Only cache content, never cache twig processed in content (incompatible with `twig_first: true`)
+  events:
+    page: true                                   # Enable page level events
+    twig: true                                   # Enable Twig level events
+  markdown:
+    extra: false                                 # Enable support for Markdown Extra support (GFM by default)
+    auto_line_breaks: false                      # Enable automatic line breaks
+    auto_url_links: false                        # Enable automatic HTML links
+    escape_markup: false                         # Escape markup tags into entities
+    special_chars:                               # List of special characters to automatically convert to entities
+      '>': 'gt'
+      '<': 'lt'
+    valid_link_attributes:                       # Valid attributes to pass through via markdown links
+      - rel
+      - target
+      - id
+      - class
+      - classes
+  types: [html,htm,xml,txt,json,rss,atom]        # list of valid page types
+  append_url_extension: ''                       # Append page's extension in Page urls (e.g. '.html' results in /path/page.html)
+  expires: 604800                                # Page expires time in seconds (604800 seconds = 7 days)
+  cache_control:                                 # Can be blank for no setting, or a valid `cache-control` text value
+  last_modified: false                           # Set the last modified date header based on file modification timestamp
+  etag: true                                     # Set the etag header tag
+  vary_accept_encoding: false                    # Add `Vary: Accept-Encoding` header
+  redirect_default_route: false                  # Automatically redirect to a page's default route
+  redirect_default_code: 302                     # Default code to use for redirects
+  redirect_trailing_slash: true                  # Handle automatically or 302 redirect a trailing / URL
+  ignore_files: [.DS_Store]                      # Files to ignore in Pages
+  ignore_folders: [.git, .idea]                  # Folders to ignore in Pages
+  ignore_hidden: true                            # Ignore all Hidden files and folders
+  hide_empty_folders: false                      # If folder has no .md file, should it be hidden
+  url_taxonomy_filters: true                     # Enable auto-magic URL-based taxonomy filters for page collections
+  frontmatter:
+    process_twig: false                          # Should the frontmatter be processed to replace Twig variables?
+    ignore_fields: ['form','forms']              # Fields that might contain Twig variables and should not be processed
+
+cache:
+  enabled: true                                  # Set to true to enable caching
+  check:
+    method: file                                 # Method to check for updates in pages: file|folder|hash|none
+  driver: auto                                   # One of: auto|file|apcu|memcache|wincache
+  prefix: 'g'                                    # Cache prefix string (prevents cache conflicts)
+  purge_at: '0 4 * * *'                          # How often to purge old file cache (using new scheduler)
+  clear_at: '0 3 * * *'                           # How often to clear cache (using new scheduler)
+  clear_job_type: 'standard'                     # Type to clear when processing the scheduled clear job `standard`|`all`
+  clear_images_by_default: true                  # By default grav will include processed images in cache clear, this can be disabled
+  cli_compatibility: false                       # Ensures only non-volatile drivers are used (file, redis, memcache, etc.)
+  lifetime: 604800                               # Lifetime of cached data in seconds (0 = infinite)
+  gzip: false                                    # GZip compress the page output
+  allow_webserver_gzip: false                    # If true, `content-encoding: identity` but connection isn't closed before `onShutDown()` event
+  redis:
+    socket: false                                # Path to redis unix socket (e.g. /var/run/redis/redis.sock), false = use server and port to connect
+    password:                                    # Optional password
+    database:                                    # Optional database ID
+
+twig:
+  cache: true                                    # Set to true to enable Twig caching
+  debug: true                                    # Enable Twig debug
+  auto_reload: true                              # Refresh cache on changes
+  autoescape: true                               # Autoescape Twig vars (DEPRECATED, always enabled in strict mode)
+  undefined_functions: true                      # Allow undefined functions
+  undefined_filters: true                        # Allow undefined filters
+  umask_fix: false                               # By default Twig creates cached files as 755, fix switches this to 775
+
+assets:                                          # Configuration for Assets Manager (JS, CSS)
+  css_pipeline: false                            # The CSS pipeline is the unification of multiple CSS resources into one file
+  css_pipeline_include_externals: true           # Include external URLs in the pipeline by default
+  css_pipeline_before_excludes: true             # Render the pipeline before any excluded files
+  css_minify: true                               # Minify the CSS during pipelining
+  css_minify_windows: false                      # Minify Override for Windows platforms. False by default due to ThreadStackSize
+  css_rewrite: true                              # Rewrite any CSS relative URLs during pipelining
+  js_pipeline: false                             # The JS pipeline is the unification of multiple JS resources into one file
+  js_pipeline_include_externals: true            # Include external URLs in the pipeline by default
+  js_pipeline_before_excludes: true              # Render the pipeline before any excluded files
+  js_minify: true                                # Minify the JS during pipelining
+  enable_asset_timestamp: false                  # Enable asset timestamps
+  collections:
+    jquery: system://assets/jquery/jquery-2.x.min.js
+
+errors:
+  display: 0                                     # Display either (1) Full backtrace | (0) Simple Error | (-1) System Error
+  log: true                                      # Log errors to /logs folder
+
+log:
+  handler: file                                 # Log handler. Currently supported: file | syslog
+  syslog:
+    facility: local6                            # Syslog facilities output
+
+debugger:
+  enabled: false                                 # Enable Grav debugger and following settings
+  provider: clockwork                            # Debugger provider: debugbar | clockwork
+  censored: false                                # Censor potentially sensitive information (POST parameters, cookies, files, configuration and most array/object data in log messages)
+  shutdown:
+    close_connection: true                       # Close the connection before calling onShutdown(). false for debugging
+
+images:
+  default_image_quality: 85                      # Default image quality to use when resampling images (85%)
+  cache_all: false                               # Cache all image by default
+  cache_perms: '0755'                            # MUST BE IN QUOTES!! Default cache folder perms. Usually '0755' or '0775'
+  debug: false                                   # Show an overlay over images indicating the pixel depth of the image when working with retina for example
+  auto_fix_orientation: true                     # Automatically fix the image orientation based on the Exif data
+  seofriendly: false                             # SEO-friendly processed image names
+  defaults:
+    loading: auto                                # Let browser pick [auto|lazy|eager]
+
+media:
+  enable_media_timestamp: false                  # Enable media timestamps
+  unsupported_inline_types: []                   # Array of supported media types to try to display inline
+  allowed_fallback_types: []                     # Array of allowed media types of files found if accessed via Page route
+  auto_metadata_exif: false                      # Automatically create metadata files from Exif data where possible
+
+session:
+  enabled: true                                  # Enable Session support
+  initialize: true                               # Initialize session from Grav (if false, plugin needs to start the session)
+  timeout: 1800                                  # Timeout in seconds
+  name: grav-site                                # Name prefix of the session cookie. Use alphanumeric, dashes or underscores only. Do not use dots in the session name
+  uniqueness: path                               # Should sessions be `path` based or `security.salt` based
+  secure: false                                  # Set session secure. If true, indicates that communication for this cookie must be over an encrypted transmission. Enable this only on sites that run exclusively on HTTPS
+  httponly: true                                 # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed.
+  samesite: Lax                                  # Set session SameSite. Possible values are Lax, Strict and None. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
+  split: true                                    # Sessions should be independent between site and plugins (such as admin)
+  domain:                                        # Domain used by sessions.
+  path:                                          # Path used by sessions.
+
+gpm:
+  releases: stable                               # Set to either 'stable' or 'testing'
+  proxy_url:                                     # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128)
+  method: 'auto'                                 # Either 'curl', 'fopen' or 'auto'. 'auto' will try fopen first and if not available cURL
+  verify_peer: true                              # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help.
+  official_gpm_only: true                        # By default GPM direct-install will only allow URLs via the official GPM proxy to ensure security
+
+accounts:
+  type: regular                                  # EXPERIMENTAL: Account type: regular or flex
+  storage: file                                  # EXPERIMENTAL: Flex storage type: file or folder
+
+flex:
+  cache:
+    index:
+      enabled: true                             # Set to true to enable Flex index caching. Is used to cache timestamps in files
+      lifetime: 60                              # Lifetime of cached index in seconds (0 = infinite)
+    object:
+      enabled: true                             # Set to true to enable Flex object caching. Is used to cache object data
+      lifetime: 600                             # Lifetime of cached objects in seconds (0 = infinite)
+    render:
+      enabled: true                             # Set to true to enable Flex render caching. Is used to cache rendered output
+      lifetime: 600                             # Lifetime of cached HTML in seconds (0 = infinite)
+
+strict_mode:
+  yaml_compat: false                            # Set to true to enable YAML backwards compatibility
+  twig_compat: false                            # Set to true to enable deprecated Twig settings (autoescape: false)
+  blueprint_compat: false                       # Set to true to enable backward compatible strict support for blueprints

+ 20 - 0
user/pages/01.bienvenue/default.md

@@ -0,0 +1,20 @@
+---
+title: Bienvenue
+---
+
+## Bonjour, je suis Alexandre et je vous souhaite la bienvenue ! 🙂
+
+Technicien systèmes et réseaux et administrateur de ce site web, j’ai créé ce blog dans le but de partager des informations propres au métier d’administrateur systèmes et réseaux et mettre à disposition des services libres « validés » par Framasoft via ma plateforme [YunoHost](https://yunohost.org) ([YunoHost c’est quoi ?](https://blog.am-networks.fr/lhebergement-avec-yunohost/)).
+
+Pour profiter au maximum du site, laissez-vous guider par les menus.
+Besoin d’infos supplémentaires concernant les services ? [Cliquez-ici](/services) !
+
+Bonne visite !
+
+PS : Je défends la liberté d’internet en communiquant de manière chiffrée via PGP, pourquoi ne pas [en faire autant](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8e4f6e9fa5363bd13c453d0af5bf6f50334c605) ?
+
+## Suivez-moi !
+
+[![GitLab](https://cdn1.iconfinder.com/data/icons/feather-2/24/gitlab-64.png)](https://gitlab.am-networks.fr/am)
+[![Mastodon](https://cdn1.iconfinder.com/data/icons/logos-and-brands-3/512/207_Mastodon_logo_logos-64.png)](https://mamot.fr/@alexandremtr)
+[![Diaspora](https://cdn2.iconfinder.com/data/icons/social-media-vol-1-8/64/media_network_social_internet_web_mobile_27-64.png)](https://framasphere.org/u/alexandremtr)

+ 27 - 0
user/pages/02.a-propos/default.md

@@ -0,0 +1,27 @@
+---
+title: 'À propos'
+---
+
+# À propos de l'auteur
+
+Je suis Alexandre, SysAdmin vivant en Normandie près de Caen. Je voue pour l’informatique une passion qui n’a de limite que mon budget 😉
+
+## Mon parcours professionnel
+
+Depuis octobre 2019, je suis technicien support chez Alticap, où j’ai effectué deux ans en alternance de 2016 à 2018.
+Entre mon alternance et mon poste actuel, j’ai occupé deux postes qui n’ont pas collé avec mon tempérament et mes compétences :
+
+* Poste : Développeur infrastructure Linux (Mars-Mai 2019) chez GFI World
+* Poste : Technicien support (Mai-Septembre 2019) chez NormHost – VOIP Télécom
+
+## Mes études
+
+* 2016-2018 : Titre de niveau II « Administrateur Systèmes et Réseaux » à l'ENI Ecole Informatique – Chartres-de-Bretagne.
+* 2014-2016 : BTS « Services informatiques aux Organisations » au Lycée Jean Rostand de Caen.
+* 2011-2014 : Baccalauréat Professionnel « Systèmes Électroniques Numériques » option « Télécommunications et Réseaux » aux lycées Jean Jooris de Dives-sur-Mer (2011-2013) et Charles Tellier de Condé-sur-Noireau (2013-2014)
+
+## Mes loisirs
+
+* Sorties en pleine nature
+* Musique (écoute uniquement)
+* Informatique (notamment le développement [PowerShell](https://gitlab.am-networks.fr/users/am/projects))

+ 5 - 0
user/pages/03.blog/default.md

@@ -0,0 +1,5 @@
+---
+title: Blog
+redirect: 'https://blog.am-networks.fr'
+---
+

+ 43 - 0
user/pages/04.services/default.md

@@ -0,0 +1,43 @@
+---
+title: Services
+---
+
+# Services mis à votre disposition
+
+## 1. Les services non authentifiés
+
+### 1.a. Présentation
+
+Sont considérés comme services non authentifiés les services ne nécessitant pas une authentification sur le réseau AM Networks.
+L'authentification peut cependant se faire auprès d'une autre plateforme indépendante.
+
+### 1.b. Liste de services non authentifiés fournis par AM Networks
+
+* PrivateBin (Framalibre) : Presse-papier chiffré et stocké sur le serveur. Possibilité de définir la date d'expiration, un mot de passe d'accès ou encore si le presse-papier n'est accessible qu'une seule fois.
+* Forge GitLab (Framalibre): Il s'agit de l'emplacement où mes morceaux de codes sont mis à disposition. Possibilité d'ouvrir un compte librement et d'envoyer du code.
+* Jirafeau (Framalibre) : Partage de fichier simple.
+* Bibliogram : Client Instagram sans authentification. Permet d'ouvrir un profil ou une publication d'après son nom d'utilisateur (profil) ou identifiant (publication).
+* I Hate Money (Framalibre) : Gestion de comptes à plusieurs, pour ceux qui détestent se rembourser les uns les autres.
+* Element (Framalibre) : Client web du logiciel Matrix (logiciel de discussion semblable à Slack).
+
+## 2. Les services authentifiés
+
+### 2.a. Présentation
+
+Ces services nécessitent d'avoir un compte sur l'infrastructure AM Networks.  Si vous ne disposez pas d'accès sur notre plateforme, je vous suggère d'ignorer ces services.
+
+### 2.b. Liste de services authentifiés fournis par AM Networks
+
+* Movim (Framalibre) : Client XMPP (discussion et blog), fonctionne uniquement sur le domaine am-networks.fr.
+* NextCloud (Framalibre) : Gestionnaire de fichiers dans le cloud (alternative à iCloud, Google Drive, Dropbox).
+* AirSonic : Serveur de streaming musical.
+* Bitwarden (Framalibre) : Gestionnaire de mots de passe open-source.
+* Hubzilla (Framalibre) : Réseau social décentralisé (n'étant pas stocké dans une grosse entreprise de l'Internet).
+* Wallabag (Framalibre) : Application "Read-It-Later". Alternative libre à Pocket et Instapaper.
+
+## 3. Gestion de vos données
+
+Vos données stockées sur nos serveurs peuvent être supprimées ou modifiées sur demande expresse à l'adresse [contact@am-networks.fr](mailto:contact@am-networks.fr).
+Ces données sont stockées uniquement sur notre serveur. Aucun tiers n'a accès à ces données.
+
+Pour toute question, faire une demande à l'adresse mail ci-dessus.

+ 5 - 0
user/pages/05.liste des services/01.privatebin/default.md

@@ -0,0 +1,5 @@
+---
+title: PrivateBin
+redirect: 'https://zerobin.am-networks.fr/'
+---
+

+ 5 - 0
user/pages/05.liste des services/02.gitlab/default.md

@@ -0,0 +1,5 @@
+---
+title: GitLab
+redirect: 'https://gitlab.am-networks.fr/explore'
+---
+

+ 5 - 0
user/pages/05.liste des services/03.element/default.md

@@ -0,0 +1,5 @@
+---
+title: Element
+redirect: 'https://element.am-networks.fr/'
+---
+

+ 5 - 0
user/pages/05.liste des services/04.i-hate-money/default.md

@@ -0,0 +1,5 @@
+---
+title: 'I Hate Money'
+redirect: 'https://services.am-networks.fr/ihatemoney'
+---
+

+ 5 - 0
user/pages/05.liste des services/05.nextcloud/default.md

@@ -0,0 +1,5 @@
+---
+title: NextCloud
+redirect: 'https://files.am-networks.fr/'
+---
+

+ 5 - 0
user/pages/05.liste des services/06.bitwarden/default.md

@@ -0,0 +1,5 @@
+---
+title: Bitwarden
+redirect: 'https://bitwarden.am-networks.fr/'
+---
+

+ 5 - 0
user/pages/05.liste des services/07.webmail/default.md

@@ -0,0 +1,5 @@
+---
+title: Webmail
+redirect: 'https://webmail.am-networks.fr'
+---
+

+ 38 - 0
user/pages/06.mentions-legales/default.md

@@ -0,0 +1,38 @@
+---
+title: 'Mentions légales'
+---
+
+# Mentions légales AM Networks
+
+## Hébergement du site
+
+Le présent site est hébergé à mon domicile et ne dépend donc pas d’un hébergeur. Site hébergé en France, plus précisément en Normandie.
+Le registrar du domaine am-networks.fr est OVH. Les certificats SSL sont fournis par Let’s Encrypt.
+
+## Propriétaire du site / responsable de la publication
+
+Alexandre MOTTIER
+
+Mél : [contact@am-networks.fr](mailto:contact@am-networks.fr)
+
+## Hébergement des données
+
+Des données peuvent être stockées sur la base du volontariat des utilisateurs et sur autorisation expresse de ceux-ci.
+Conformément à la loi informatique et libertés, vous pouvez effectuer une réclamation quant aux données conservées vous concernant à l’adresse mail ci-dessus.
+Actuellement, le système ne dispose d’aucun système de sauvegarde et de restauration sur incident. Veillez donc à bien garder des copies de vos données sur une clé USB, un disque dur ou bien un autre hébergeur.
+
+**Vous inscrire sur l’une des applications le permettant équivaut à un consentement au stockage des données vous concernant ainsi qu’au risque de les perdre.**
+
+### Données vous concernant pouvant être collectées pour l’accès aux services :
+
+Nom, prénom, adresse e-mail. Une adresse mail sur le domaine AM Networks (am-networks.fr) vous sera alors allouée pour l’accès aux services.
+
+## Sécurité de vos données
+
+Vos données ne sont collectées par aucune entité tierce, si ce n’est les moteurs de recherche pour améliorer la pertinence des résultats de recherche.
+Nous n’utilisons pas de cookies, pas d’analyseur de connexions du type Analytics (Google), parce que nous estimons que cela n’est pas essentiel.
+
+## Outils utilisés pour le site et le blog
+
+Le site que vous visitez actuellement fonctionne sur GRAV avec le thème Quark.
+Le blog fonctionne sous le CMS Ghost avec le thème Massively.

+ 0 - 0
user/themes/.gitkeep


+ 177 - 0
user/themes/quark/CHANGELOG.md

@@ -0,0 +1,177 @@
+# v2.0.3
+## 06/08/2020
+
+1. [](#improved)
+    * Updated some JS libraries
+    * Simplified navigation macro
+    * Use `site.title` in logo alt text [#139](https://github.com/getgrav/grav-theme-quark/pull/109)
+
+# v2.0.2
+## 08/09/2019
+
+1. [](#improved)
+    * Allow for overriding of `{% block content %}{% endblock %}`
+    * Improved default `.table` styling
+    * Simplified navigation macro
+1. [](#bugfix)
+    * Fixed issue with Prism Highlight [prism-highlight#1](https://github.com/trilbymedia/grav-plugin-prism-highlight/issues/1)
+    * Use slug for onpage links [#115](https://github.com/getgrav/grav-theme-quark/issues/115)
+    * Fixed 2 minor YAML linting issues
+
+# v2.0.1
+## 05/09/2019
+
+1. [](#improved)
+    * Typo in blueprints [#109](https://github.com/getgrav/grav-theme-quark/pull/109)
+    * Added convenience scripts to `package.json` [#110](https://github.com/getgrav/grav-theme-quark/pull/110)
+    * Added Czech translation [#106](https://github.com/getgrav/grav-theme-quark/pull/106)
+    * Added Chinese translation [#114](https://github.com/getgrav/grav-theme-quark/pull/114)
+    * Removed redundant code [#104](https://github.com/getgrav/grav-theme-quark/pull/104)
+    * Updated to match Archives plugin translation output
+1. [](#bugfix)
+    * Bugfix to class in macro [#105](https://github.com/getgrav/grav-theme-quark/pull/105)
+    * Bugfix a z-index issue [#75](https://github.com/getgrav/grav-theme-quark/pull/75)
+
+# v2.0.0
+## 04/11/2019
+
+1. [](#improved)
+    * Updated to use new `GRAV` core language prefix
+    * Updated [Spectre.css](https://picturepan2.github.io/spectre/) to latest `0.5.8` version
+    * Support for 2FA panel styling
+    * Updated to Yarn 4.0 syntax
+    * Restructured SCSS to ensure easier Spectre updates in future
+1. [](#bugfix)
+    * Some checkboxes fixes for Forms 3.0
+    * More Twig 2.0 compatibility fixes
+    * Fixed a Twig 2.0 issue with assets rendering
+    
+# v1.2.6
+## 03/21/2019
+
+1. [](#new)
+    * Set Dependency of Grav 1.5.10+ which has support for new **Deferred Block** Twig extension
+    * Implement assets rendering using **Deferred Block** Twig extension 
+
+# v1.2.5
+## 12/07/2018
+
+1. [](#improved)
+    * Updated [Spectre.css](https://picturepan2.github.io/spectre/) to latest `0.5.7` version
+1. [](#bugfix)
+    * Fixed missing `</html>` close tag in bae template [#76](https://github.com/getgrav/grav-theme-quark/pull/76)    
+
+# v1.2.4
+## 11/12/2018
+
+1. [](#improved)
+    * Updated [Spectre.css](https://picturepan2.github.io/spectre/) to latest `0.5.5` version
+    * Added link support to modular `features` [#39](https://github.com/getgrav/grav-theme-quark/pull/39/)
+    * Remove desktop menu when in mobile mode [#59](https://github.com/getgrav/grav-theme-quark/pull/59/)
+    * Support modular `text` full-width if no image [#70](https://github.com/getgrav/grav-theme-quark/issues/70)
+    * Shim for IE support of BrickLayer.js [#64](https://github.com/getgrav/grav-theme-quark/issues/64)
+1. [](#bugfix)
+    * Fixed `continue_link:` showing up as toggled [#65](https://github.com/getgrav/grav-theme-quark/issues/65)
+    * Fixed issue with modular pages not hidden in on-page menu with `visible: false` [#71](https://github.com/getgrav/grav-theme-quark/issues/71)
+
+
+# v1.2.3
+## 11/05/2018
+
+1. [](#improved)
+    * Moved footer into standalone twig to allow for easier extensibility [#63](https://github.com/getgrav/grav-theme-quark/pull/63)
+1. [](#bugfix)
+    * Fix variable name for prouction mode [#61](https://github.com/getgrav/grav-theme-quark/pull/61)
+    * Fix layout size in features blueprint [#67](https://github.com/getgrav/grav-theme-quark/pull/67)
+    * Fix active page logic in `nav` so there's no empty class attributes [#68](https://github.com/getgrav/grav-theme-quark/pull/68)
+    * Fix for features blueprint because `class` didn't work [#69](https://github.com/getgrav/grav-theme-quark/pull/69)
+
+# v1.2.2
+## 10/24/2018
+
+1. [](#improved)
+    * Changed nav macro to format supported by Twig 2.0
+    * Updated `partials/form-messages.html.twig` to be more inline with latest Forms plugin
+1. [](#bugfix)
+    * Make the theme to work with Twig auto-escaping turned on
+    * Moved language strings under `THEME_QUARK`
+
+# v1.2.1
+## 08/23/2018
+
+1. [](#improved)
+    * Added additional "mobile custom logo" support
+1. [](#bugfix)
+    * Addressed some CSS issues by forcing logo height
+
+# v1.2.0
+## 08/23/2018
+
+1. [](#new)
+    * Added new "custom logo" support [#3](https://github.com/getgrav/grav-theme-quark/issues/3)
+    * Added option JSON feed syndication support in sidebar [#47](https://github.com/getgrav/grav-theme-quark/pull/47)
+    * Added basic form field `array` styling
+
+# v1.1.0
+## 07/25/2018
+
+1. [](#new)
+    * Responsive font sizing [#28](https://github.com/getgrav/grav-theme-quark/issues/28)
+1. [](#improved)
+    * Updated [Spectre.css](https://picturepan2.github.io/spectre/) to latest `0.5.3` version
+    * Make blog settings toggleable [#38](https://github.com/getgrav/grav-theme-quark/pull/38)
+1. [](#bugfix)
+    * Proper fix for sticky footer in IE10 and IE11 [#21](https://github.com/getgrav/grav-theme-quark/issues/21)
+    * Fix for lists wrapping weirdly due to `outside` attribute
+    * Updated checkbox + radio to take into account `client_side_validation` form option
+    * Fixes for fallback values [#37](https://github.com/getgrav/grav-theme-quark/pull/37)
+    * Fix inheritance for images folder [#30](https://github.com/getgrav/grav-theme-quark/pull/30)
+    * Added blueprint option for `continue_link` [#45](https://github.com/getgrav/grav-theme-quark/issues/45)
+    * Added blueprint option for Feature `class` [#14](https://github.com/getgrav/grav-theme-quark/issues/14)
+    * Fixed `Duplicate ID` issues with modular sections.  Might break CSS on first load, need to refresh to pick up new CSS [#24](https://github.com/getgrav/grav-theme-quark/issues/24)
+    * Fixed Text feature alignment issue [#4](https://github.com/getgrav/grav-theme-quark/issues/4)
+    * Overlapping menu and mobile button [#7](https://github.com/getgrav/grav-theme-quark/issues/7)
+
+# v1.0.3
+## 05/11/2018
+
+1. [](#new)
+    * Added new primary button mixin
+1. [](#improved)
+    * Updated [Spectre.css](https://picturepan2.github.io/spectre/) to latest `0.5.1` version
+    * Improved default login styling
+    * Removed core Spectre.css override to make upgrading Spectre easier
+    * Added screenshot to README.md
+    * Override focus to prevent overzealous blue blurs
+1. [](#bugfix)
+    * Fix for `highlight` plugin not changing background of code blocks
+    * Removed extraneous `dump()` in Twig output
+
+# v1.0.2
+## 02/19/2018
+
+1. [](#new)
+    * Added toggle options to enable Spectre.css _experimentals_ and _icons_ CSS files
+    * Switched to a fork of LineAwesome icons compatible with FontAwesome 4.7.0
+1. [](#improved)
+    * Font tweaks
+1. [](#bugfix)
+    * Pagination fixes
+
+# v1.0.1
+##  01/22/2018
+
+1. [](#new)
+    * Added blueprints for admin editing
+1. [](#improved)
+    * Use default lang from `site.yaml`
+1. [](#bugfix)
+    * Fixed Current path to address issues with extending Quark
+    * Fixed parallax to start in same position as standard
+    * Fixed modular image size
+
+# v1.0.0
+##  12/28/2017
+
+1. [](#new)
+    * ChangeLog started...

+ 21 - 0
user/themes/quark/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2018 Trilby Media
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 152 - 0
user/themes/quark/README.md

@@ -0,0 +1,152 @@
+# Quark Theme
+
+![](assets/quark-screenshots.jpg)
+
+**Quark** is the new default theme for [Grav CMS](http://github.com/getgrav/grav).  This theme is built with the [Spectre.css](https://picturepan2.github.io/spectre/) framework and provides a powerful base for developing your own themes. Quark uses functionality that is only available in Grav 1.4+, as such you cannot run Quark on earlier versions of Grav.
+
+## Features
+
+* Lightweight and minimal for optimal performance
+* Spectre CSS Framework
+* Fully responsive with full-page mobile navigation
+* SCSS based CSS source files for easy customization
+* Built-in support for on-page navigation
+* Multiple page template types
+* Fontawesome icon support
+
+### Supported Page Templates
+
+* Default view template `default.md`
+* Error view template `error.md`
+* Blog view template `blog.md`
+* Blog item view template `item.md`
+* Modular view templates: `modular.md`
+  * Features Modular view template `features.md`
+  * Hero Modular view template `hero.md`
+  * Text Modular view template `text.md`
+
+# Installation
+
+Installing the Quark theme can be done in one of two ways. Our GPM (Grav Package Manager) installation method enables you to quickly and easily install the theme with a simple terminal command, while the manual method enables you to do so via a zip file. 
+
+The theme by itself is useful, but you may have an easier time getting up and running by installing a skeleton. The Quark theme can be found in both the [One-page](https://github.com/getgrav/grav-skeleton-onepage-site) and [Blog Site](https://github.com/getgrav/grav-skeleton-blog-site) which are self-contained repositories for a complete sites which include: sample content, configuration, theme, and plugins.
+
+## GPM Installation (Preferred)
+
+The simplest way to install this theme is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's Terminal (also called the command line).  From the root of your Grav install type:
+
+    bin/gpm install quark
+
+This will install the Quark theme into your `/user/themes` directory within Grav. Its files can be found under `/your/site/grav/user/themes/quark`.
+
+## Manual Installation
+
+To install this theme, just download the zip version of this repository and unzip it under `/your/site/grav/user/themes`. Then, rename the folder to `quark`. You can find these files either on [GitHub](https://github.com/getgrav/grav-theme-quark) or via [GetGrav.org](http://getgrav.org/downloads/themes).
+
+You should now have all the theme files under
+
+    /your/site/grav/user/themes/quark
+
+## Default Options
+
+Quark comes with a few default options that can be set site-wide.  These options are:
+
+```yaml
+enabled: true                 # Enable the theme
+production-mode: true         # In production mode, only minified CSS is used. When disabled, nested CSS with sourcemaps are enabled
+grid-size: grid-lg            # The max-width of the theme, options include: `grid-xl`, `grid-lg`, and `grid-md`
+header-fixed: true            # Cause the header to be fixed at the top of the browser
+header-animated: true         # Allows the fixed header to resize to a smaller header when scrolled
+header-dark: false            # Inverts the text/logo to work better on dark backgrounds
+header-transparent: false     # Allows the fixed header to be transparent over the page
+sticky-footer: true           # Causes the footer to be sticky at the bottom of the page
+blog-page: '/blog'            # The route to the blog listing page, useful for a blog style layout with sidebar
+custom_logo:                  # A custom logo rather than the default (see below)  
+custom_logo_mobile:           # A custom logo to use for mobile navigation
+```
+
+To make modifications, you can copy the `user/themes/quark/quark.yaml` file to `user/config/themes/` folder and modify, or you can use the admin plugin.
+
+> NOTE: Do not modify the `user/themes/quark/quark.yaml` file directly or your changes will be lost with any updates
+
+## Custom Logos
+
+To add a custom logo, you should put the log into the `user/themes/quark/images/logo` folder.  Standard image formats are support (`.png`,`.jpg`, `.gif`, `.svg`, etc.).  Then reference the logo via the YAML like so:
+
+```yaml
+custom_logo:
+    - name: 'my-logo.png'
+custom_logo_mobile:
+    - name: 'my-mobile-logo.png'    
+```
+
+Alternatively, you can you use the drag-n-drop "Custom Logo" field in the Quark theme options.
+
+## Page Overrides
+
+Quark has the ability to allow pages to override some of the default options by letting the user set `body_classes` for any page.  The theme will merge the combination of the defaults with any `body_classes` set. For example:
+
+```yaml
+body_classes: "header-dark header-transparent"
+```
+
+On a particular page will ensure that page has those options enabled (assuming they are false by default).
+
+## Hero Options
+
+The hero template allows some options to be set in the page frontmatter. This is used by the modular `hero` as well as the blog and item templates to provide a more dynamic header.
+
+```yaml
+hero_classes: text-light title-h1h2 parallax overlay-dark-gradient hero-large
+hero_image: road.jpg
+hero_align: center
+```
+
+The `hero_classes` option allows a variety of hero classes to be set dynamically these include:
+
+* `text-light` | `text-dark` - Controls if the text should be light or dark depending on the content
+* `title-h1h2` - Enforced a close matched h1/h2 title pairing
+* `parallax` - Enables a CSS-powered parallax effect
+* `overlay-dark-gradient` - Displays a transparent gradient which further darkens the underlying image
+* `overlay-light-gradient` - Displays a transparent gradient which further lightens the underlying image
+* `overlay-dark` - Displays a solid transparent overlay which further darkens the underlying image
+* `overlay-light` - Displays a solid transparent overlay which further darkens the underlying image
+* `hero-fullscreen` | `hero-large` | `hero-medium` | `hero-small` | `hero-tiny` - Size of the hero block
+
+The `hero_image` should point to an image file in the current page folder.
+
+## Features Modular Options
+
+The features modular template provides the ability to set a class on the features, as well as an array of feature items.  For example:
+
+```yaml
+class: offset-box
+features:
+    - header: Crazy Fast
+      text: "Performance is not just an afterthought, we baked it in from the start!"
+      icon: fighter-jet
+    - header: Easy to build
+      text: "Simple text files means Grav is trivial to install, and easy to maintain"
+      icon: database
+    - header: Awesome Technology
+      text: "Grav employs best-in-class technologies such as Twig, Markdown &amp; Yaml"
+      icon: cubes
+    - header: Super Flexible
+      text: "From the ground up, with many plugin hooks, Grav is extremely extensible"
+      icon: object-ungroup
+    - header: Abundant Plugins
+      text: "A vibrant developer community means over 200 themes available to download"
+      icon: puzzle-piece
+    - header: Free / Open Source
+      text: "Grav is an open source project, so you can spend your money on other stuff"
+      icon: money 
+```
+
+## Text Modular Options
+
+The text box provides a single option to control if any image found in the page folder should be left or right aligned:
+
+```yaml
+image_align: right
+```
+

BIN
user/themes/quark/assets/quark-screenshots.jpg


+ 176 - 0
user/themes/quark/blueprints.yaml

@@ -0,0 +1,176 @@
+name: Quark
+slug: quark
+type: theme
+version: 2.0.3
+description: New Grav Default Theme
+icon:  microchip
+author:
+  name: Team Grav
+  email: devs@getgrav.org
+  url: http://getgrav.org
+homepage: https://github.com/getgrav/grav-theme-quark
+demo: https://demo.getgrav.org/onepage-skeleton
+keywords: quark, spectre, theme, core, modern, fast, responsive, html5, css3
+bugs: https://github.com/getgrav/grav-theme-quark/issues
+license: MIT
+
+dependencies:
+  - { name: grav, version: '>=1.6.0' }
+
+form:
+  validation: loose
+
+  fields:
+    production-mode:
+      type: toggle
+      label: Production mode
+      help: When enabled, Quark will render with minified CSS
+      highlight: 1
+      default: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    grid-size:
+      type: select
+      label: Grid size
+      help: The maximum width of the theme
+      size: small
+      options:
+        '': None (full width)
+        grid-xl: Extra Large
+        grid-lg: Large
+        grid-md: Medium
+
+    header_section:
+      type: section
+      title: Header Defaults
+      underline: true
+
+    custom_logo:
+      type: file
+      label: Custom Logo
+      size: large
+      destination: 'theme://images/logo'
+      multiple: false
+      markdown: true
+      description: Will be used instead of default logo `theme://images/grav-logo.svg`
+      accept:
+        - image/*
+
+    custom_logo_mobile:
+      type: file
+      label: Mobile Custom Logo
+      size: large
+      destination: 'theme://images/logo'
+      multiple: false
+      accept:
+        - image/*
+
+    header-fixed:
+      type: toggle
+      label: Fixed header
+      help: When enabled, the header will be fixed at the top of the browser
+      highlight: 1
+      default: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    header-animated:
+      type: toggle
+      label: Animated
+      help: When enabled, the header will animate to a smaller header when scrolling
+      highlight: 1
+      default: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    header-dark:
+      type: toggle
+      label: Dark Style
+      help: When enabled, a dark-friendly style will be used
+      highlight: 0
+      default: 0
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    header-transparent:
+      type: toggle
+      label: Transparent
+      help: When enabled, a transparent style will be used
+      highlight: 0
+      default: 0
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    footer_section:
+      type: section
+      title: Footer Defaults
+      underline: true
+
+    sticky-footer:
+      type: toggle
+      label: Sticky footer
+      help: When enabled, the footer will be sticky at the bottom of the browser
+      highlight: 1
+      default: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    blog_section:
+      type: section
+      title: Blog Defaults
+      underline: true
+
+    blog-page:
+      type: text
+      label: Blog Page
+      help: The route to the blog page when working with blog sidebar
+      size: medium
+      default: '/blog'
+
+    spectre_section:
+      type: section
+      title: Spectre.css Options
+      underline: true
+
+    spectre.exp:
+      type: toggle
+      label: Experimentals CSS
+      help: When enabled, the `spectre-exp.css` file will be included
+      highlight: 0
+      default: 0
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    spectre.icons:
+      type: toggle
+      label: Icons CSS
+      help: When enabled, the `spectre-icons.css` file will be included
+      highlight: 0
+      default: 0
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool

+ 94 - 0
user/themes/quark/blueprints/blog.yaml

@@ -0,0 +1,94 @@
+extends@: default
+child_type: item
+
+rules:
+  slug:
+    pattern: "[a-z][a-z0-9_-]+"
+    min: 2
+    max: 80
+
+form:
+  fields:
+    tabs:
+      type: tabs
+      active: 1
+
+      fields:
+        advanced:
+          fields:
+            overrides:
+              fields:
+                header.child_type:
+                  default: item
+        blog:
+          type: tab
+          title: Blog Config
+
+          fields:
+
+            content_title:
+              type: spacer
+              title: Content Definition
+
+            header.content.items:
+              type: textarea
+              yaml: true
+              label: Items
+              default: '@self.children'
+              validate:
+                type: yaml
+
+            header.content.limit:
+              type: text
+              label: Max Item Count
+              default: 5
+              validate:
+                required: true
+                type: int
+                min: 1
+
+            header.content.order.by:
+              type: select
+              label: Order By
+              default: date
+              options:
+                folder: Folder
+                title: Title
+                date: Date
+                default: Default
+
+            header.content.order.dir:
+              type: select
+              label: Order
+              default: desc
+              options:
+                asc: Ascending
+                desc: Descending
+
+            header.content.pagination:
+              type: toggle
+              label: Pagination
+              highlight: 1
+              default: 1
+              options:
+                1: PLUGIN_ADMIN.ENABLED
+                0: PLUGIN_ADMIN.DISABLED
+              validate:
+                type: bool
+
+            header.content.url_taxonomy_filters:
+              type: toggle
+              label: URL Taxonomy Filters
+              highlight: 1
+              default: 1
+              options:
+                1: PLUGIN_ADMIN.ENABLED
+                0: PLUGIN_ADMIN.DISABLED
+              validate:
+                type: bool
+
+          import@:
+            type: partials/blog-bits
+            context: blueprints://pages
+
+

+ 15 - 0
user/themes/quark/blueprints/default.yaml

@@ -0,0 +1,15 @@
+extends@: default
+
+form:
+  fields:
+    tabs:
+      fields:
+        advanced:
+          fields:
+            columns:
+              fields:
+                column1:
+                   fields:
+                     header.body_classes:
+                       markdown: true
+                       description: 'Available classes in Quark Theme (space separated):<br />`header-fixed`, `header-animated`, `header-dark`, `header-transparent`, `sticky-footer`'

+ 113 - 0
user/themes/quark/blueprints/item.yaml

@@ -0,0 +1,113 @@
+extends@: default
+
+form:
+  fields:
+    tabs:
+
+      fields:
+        blog:
+          type: tab
+          title: Blog Item
+
+          fields:
+
+            header_options:
+              type: section
+              title: Header Options
+              underline: true
+
+            header.continue_link:
+              type: toggle
+              toggleable: true
+              label: DF Style Link
+              help: Daring Fireball style title link
+              highlight: 1
+              options:
+                1: PLUGIN_ADMIN.ENABLED
+                0: PLUGIN_ADMIN.DISABLED
+              validate:
+                type: bool
+
+            header.header_image:
+              type: toggle
+              toggleable: true
+              label: Display Header Image
+              help: Enabled displaying of a header image
+              highlight: 1
+              options:
+                1: PLUGIN_ADMIN.ENABLED
+                0: PLUGIN_ADMIN.DISABLED
+
+            header.header_image_file:
+              type: text
+              toggleable: true
+              label: Image File
+              help: image filename that exists in the page folder. If not provided, will use the first image found.
+              placeholder: "For example: myimage.jpg"
+
+            header.header_image_width:
+              type: text
+              toggleable: true
+              label: Image Width
+              size: small
+              help: Header width in px
+              placeholder: Default is 900
+              validate:
+                type: int
+                min: 0
+                max: 5000
+
+            header.header_image_height:
+              type: text
+              toggleable: true
+              label: Image Height
+              size: small
+              help: Header height in px
+              placeholder: Default is 300
+              validate:
+                type: int
+                min: 0
+                max: 5000
+
+            summary:
+              type: section
+              title: Summary
+              underline: true
+
+            header.summary.enabled:
+              type: toggle
+              toggleable: true
+              label: Summary
+              highlight: 1
+              options:
+                1: PLUGIN_ADMIN.ENABLED
+                0: PLUGIN_ADMIN.DISABLED
+
+            header.summary.format:
+              type: select
+              toggleable: true
+              label: Format
+              classes: fancy
+              options:
+                'short': 'Use the first occurence of delimiter or size'
+                'long': 'Summary delimiter will be ignored'
+
+            header.summary.size:
+              type: text
+              toggleable: true
+              label: Size
+              classes: large
+              placeholder: 300
+              validate:
+                type: int
+                min: 1
+
+            header.summary.delimiter:
+              type: text
+              toggleable: true
+              label: Summary delimiter
+              classes: large
+              placeholder: ===
+
+          import@:
+            type: partials/blog-bits

+ 38 - 0
user/themes/quark/blueprints/modular/features.yaml

@@ -0,0 +1,38 @@
+title: Features
+'@extends': default
+
+form:
+  fields:
+    tabs:
+      fields:
+        features:
+          type: tab
+          title: Features
+          fields:
+            header.class:
+              type: select
+              label: Layout
+              default: small
+              size: medium
+              options:
+                small: Small   = 4 / 3 / 2 columns
+                standard: Standard  = 3 / 2 / 1 columns
+
+            header.features:
+              name: features
+              type: list
+              label: Features
+
+              fields:
+                .icon:
+                  type: iconpicker
+                  label: Icon
+                .header:
+                  type: text
+                  label: Header
+                .text:
+                  type: text
+                  label: Text
+                .url:
+                  type: text
+                  label: Link

+ 23 - 0
user/themes/quark/blueprints/modular/hero.yaml

@@ -0,0 +1,23 @@
+title: Hero
+'@extends': default
+
+form:
+  fields:
+    tabs:
+      fields:
+        buttons:
+          type: tab
+          title: Hero
+          fields:
+            header.hero_classes:
+              type: text
+              label: Hero Classes
+              markdown: true
+              description: 'There are several Hero class options that can be listed here (space separated):<br />`text-light`, `text-dark`, `title-h1h2`, `parallax`, `overlay-dark-gradient`, `overlay-light-gradient`, `overlay-dark`, `overlay-light`, `hero-fullscreen`, `hero-large`, `hero-medium`, `hero-small`, `hero-tiny`<br />Please consult the [Quark documentation](https://github.com/getgrav/grav-theme-quark#hero-options) for more details.'
+            header.hero_image:
+              type: filepicker
+              label: Hero Image
+              preview_images: true
+              description: 'If not specified, this defaults to the first image found in the page''s folder'
+
+

+ 19 - 0
user/themes/quark/blueprints/modular/text.yaml

@@ -0,0 +1,19 @@
+title: Text
+'@extends': default
+
+form:
+  fields:
+    tabs:
+      fields:
+        content:
+          fields:
+            header.media_order:
+              label: Page Media (first one will be displayed next to your content)
+            header.image_align:
+              type: select
+              label: Image position
+              classes: fancy
+              default: left
+              options:
+                'left': 'Left'
+                'right': 'Right'

+ 64 - 0
user/themes/quark/blueprints/partials/blog-bits.yaml

@@ -0,0 +1,64 @@
+form:
+  fields:
+
+    hero_title:
+      type: spacer
+      title: Hero Section
+
+    header.hero_classes:
+      type: text
+      label: Hero Classes
+      markdown: true
+      description: 'There are several Hero class options that can be listed here (space separated):<br />`text-light`, `text-dark`, `title-h1h2`, `parallax`, `overlay-dark-gradient`, `overlay-light-gradient`, `overlay-dark`, `overlay-light`, `hero-fullscreen`, `hero-large`, `hero-medium`, `hero-small`, `hero-tiny`<br />Please consult the [Quark documentation](https://github.com/getgrav/grav-theme-quark#hero-options) for more details.'
+
+    header.hero_image:
+      type: filepicker
+      label: Hero Image
+      preview_images: true
+      description: 'If not specified, this defaults to the first image found in the page''s folder'
+
+    toggles_title:
+      type: spacer
+      title: Configuration
+
+    header.blog_url:
+      type: text
+      toggleable: true
+      label: Blog Route
+      help: The route to the main blog page that contains the "Show ..." configuration
+      default: '/blog'
+      placeholder: '/blog'
+      size: medium
+
+    header.show_sidebar:
+      type: toggle
+      toggleable: true
+      label: Show Sidebar
+      highlight: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    header.show_breadcrumbs:
+      type: toggle
+      toggleable: true
+      label: Show Breadcrumbs
+      highlight: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool
+
+    header.show_pagination:
+      type: toggle
+      toggleable: true
+      label: Show Pagination
+      highlight: 1
+      options:
+        1: PLUGIN_ADMIN.ENABLED
+        0: PLUGIN_ADMIN.DISABLED
+      validate:
+        type: bool

File diff suppressed because it is too large
+ 369 - 0
user/themes/quark/css-compiled/spectre-exp.css


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/css-compiled/spectre-exp.min.css


File diff suppressed because it is too large
+ 172 - 0
user/themes/quark/css-compiled/spectre-icons.css


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/css-compiled/spectre-icons.min.css


File diff suppressed because it is too large
+ 1257 - 0
user/themes/quark/css-compiled/spectre.css


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/css-compiled/spectre.min.css


File diff suppressed because it is too large
+ 406 - 0
user/themes/quark/css-compiled/theme.css


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/css-compiled/theme.min.css


+ 49 - 0
user/themes/quark/css/bricklayer.css

@@ -0,0 +1,49 @@
+.bricklayer {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-align: start;
+    -webkit-align-items: flex-start;
+    -ms-flex-align: start;
+    align-items: flex-start;
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+    -webkit-flex-wrap: wrap;
+    -ms-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+
+.bricklayer-column-sizer {
+    width: 100%;
+    display: none;
+}
+
+@media screen and (min-width: 640px) {
+    .bricklayer-column-sizer {
+        width: 100%;
+    }
+}
+
+@media screen and (min-width: 980px) {
+    .bricklayer-column-sizer {
+        width: 50%;
+    }
+}
+
+/*@media screen and (min-width: 1200px) {*/
+    /*.bricklayer-column-sizer {*/
+        /*width: 33.33333%;*/
+    /*}*/
+/*}*/
+
+.bricklayer-column {
+    -webkit-box-flex: 1;
+    -webkit-flex: 1;
+    -ms-flex: 1;
+    flex: 1;
+    padding-left: 5px;
+    padding-right: 5px;
+}

+ 0 - 0
user/themes/quark/css/custom.css


File diff suppressed because it is too large
+ 4 - 0
user/themes/quark/css/line-awesome.min.css


BIN
user/themes/quark/fonts/line-awesome.eot


File diff suppressed because it is too large
+ 2954 - 0
user/themes/quark/fonts/line-awesome.svg


BIN
user/themes/quark/fonts/line-awesome.ttf


BIN
user/themes/quark/fonts/line-awesome.woff


BIN
user/themes/quark/fonts/line-awesome.woff2


+ 43 - 0
user/themes/quark/gulpfile.js

@@ -0,0 +1,43 @@
+var gulp = require('gulp');
+var sass = require('gulp-sass');
+var cleancss = require('gulp-clean-css');
+var csscomb = require('gulp-csscomb');
+var rename = require('gulp-rename');
+var autoprefixer = require('gulp-autoprefixer');
+var sourcemaps = require('gulp-sourcemaps');
+
+// configure the paths
+var watch_dir = './scss/**/*.scss';
+var src_dir = './scss/*.scss';
+var dest_dir = './css-compiled';
+
+var paths = {
+    source: src_dir
+};
+
+function watch() {
+  return gulp.watch(watch_dir, build);
+}
+
+function build() {
+  return gulp.src(paths.source)
+      .pipe(sourcemaps.init())
+      .pipe(sass({
+            outputStyle: 'compact',
+            precision: 10
+          }).on('error', sass.logError)
+      )
+      .pipe(sourcemaps.write())
+      .pipe(autoprefixer())
+      .pipe(gulp.dest(dest_dir))
+      .pipe(csscomb())
+      .pipe(cleancss())
+      .pipe(rename({
+        suffix: '.min'
+      }))
+      .pipe(gulp.dest(dest_dir));
+}
+
+exports.watch = watch;
+exports.build = build;
+exports.default = build;

BIN
user/themes/quark/images/favicon-old.png


BIN
user/themes/quark/images/favicon.png


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/images/grav-logo.svg


+ 0 - 0
user/themes/quark/images/logo/.gitkeep


BIN
user/themes/quark/images/logo/cropped-90E192D6-7E17-421D-B6C7-A9A615C3B734-1-1.png


BIN
user/themes/quark/images/logo/cropped-90E192D6-7E17-421D-B6C7-A9A615C3B734-1.png


File diff suppressed because it is too large
+ 1 - 0
user/themes/quark/js/bricklayer.min.js


+ 87 - 0
user/themes/quark/js/jquery.treemenu.js

@@ -0,0 +1,87 @@
+/*
+ treeMenu - jQuery plugin
+ version: 0.6
+
+ Copyright 2014 Stepan Krapivin
+
+*/
+(function($){
+    $.fn.treemenu = function(options) {
+        options = options || {};
+        options.delay = options.delay || 0;
+        options.openActive = options.openActive || false;
+        options.closeOther = options.closeOther || false;
+        options.activeSelector = options.activeSelector || ".active";
+
+        this.addClass("treemenu");
+
+        if (!options.nonroot) {
+            this.addClass("treemenu-root");
+        }
+
+        options.nonroot = true;
+
+        this.find("> li").each(function() {
+            e = $(this);
+            var subtree = e.find('> ul');
+            var button = e.find('.toggler').eq(0);
+
+            if(button.length == 0) {
+                // create toggler
+                var button = $('<span>');
+                button.addClass('toggler');
+                e.prepend(button);
+            }
+
+            if(subtree.length > 0) {
+                subtree.hide();
+
+                e.addClass('tree-closed');
+
+                e.find(button).click(function() {
+                    var li = $(this).parent('li');
+
+                    if (options.closeOther && li.hasClass('tree-closed')) {
+                        var siblings = li.parent('ul').find("li:not(.tree-empty)");
+                        siblings.removeClass("tree-opened");
+                        siblings.addClass("tree-closed");
+                        siblings.removeClass(options.activeSelector);
+                        siblings.find('> ul').slideUp(options.delay);
+                    }
+
+                    li.find('> ul').slideToggle(options.delay);
+                    li.toggleClass('tree-opened');
+                    li.toggleClass('tree-closed');
+                    li.toggleClass(options.activeSelector);
+                });
+
+                $(this).find('> ul').treemenu(options);
+            } else {
+                $(this).addClass('tree-empty');
+            }
+        });
+
+        if (options.openActive) {
+            var cls = this.attr("class");
+
+            this.find(options.activeSelector).each(function(){
+                var el = $(this).parent();
+
+                while (el.attr("class") !== cls) {
+                    el.find('> ul').show();
+                    if(el.prop("tagName") === 'UL') {
+                        el.show();
+                    } else if (el.prop("tagName") === 'LI') {
+                        el.removeClass('tree-closed');
+                        el.addClass("tree-opened");
+                        el.show();
+                    }
+
+                    el = el.parent();
+                }
+            });
+        }
+
+        return this;
+    }
+})(jQuery);

File diff suppressed because it is too large
+ 9 - 0
user/themes/quark/js/scopedQuerySelectorShim.min.js


File diff suppressed because it is too large
+ 8 - 0
user/themes/quark/js/singlepagenav.min.js


+ 59 - 0
user/themes/quark/js/site.js

@@ -0,0 +1,59 @@
+var isTouch = window.DocumentTouch && document instanceof DocumentTouch;
+
+function scrollHeader() {
+    // Has scrolled class on header
+    var zvalue = $(document).scrollTop();
+    if ( zvalue > 75 )
+        $("#header").addClass("scrolled");
+    else
+        $("#header").removeClass("scrolled");
+}
+
+function parallaxBackground() {
+    $('.parallax').css('background-positionY', ($(window).scrollTop() * 0.3) + 'px');
+}
+
+jQuery(document).ready(function($){
+
+    scrollHeader();
+
+    // Scroll Events
+    if (!isTouch){
+        $(document).scroll(function() {
+            scrollHeader();
+            parallaxBackground();
+        });
+    };
+
+    // Touch scroll
+    $(document).on({
+        'touchmove': function(e) {
+            scrollHeader(); // Replace this with your code.
+        }
+    });
+
+    //Smooth scroll to start
+    $('#to-start').click(function(){
+        var start_y = $('#start').position().top;
+        var header_offset = 45;
+        window.scroll({ top: start_y - header_offset, left: 0, behavior: 'smooth' });
+        return false;
+    });
+
+    //Smooth scroll to top
+    $('#to-top').click(function(){
+        window.scroll({ top: 0, left: 0, behavior: 'smooth' });
+        return false;
+    });
+
+    // Responsive Menu
+    $('#toggle').click(function () {
+        $(this).toggleClass('active');
+        $('#overlay').toggleClass('open');
+        $('body').toggleClass('mobile-nav-open');
+    });
+
+    // Tree Menu
+    $(".tree").treemenu({delay:300});
+
+});

File diff suppressed because it is too large
+ 6 - 0
user/themes/quark/js/smooth-scroll.min.js


+ 288 - 0
user/themes/quark/languages.yaml

@@ -0,0 +1,288 @@
+en:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Continue reading...
+        NEXT_POST: Next Post
+        PREV_POST: Previous Post
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Search
+      RELATED_POSTS:
+        HEADLINE: Related Posts
+      RANDOM_ARTICLE:
+        HEADLINE: Random Article
+        FEELING_LUCKY: I'm Feeling Lucky!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Some Text Widget
+      POPULAR_TAGS:
+        HEADLINE: Popular Tags
+      ARCHIVES:
+        HEADLINE: Archives
+      SYNDICATE:
+        HEADLINE: Syndicate
+
+de:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Weiterlesen...
+        NEXT_POST: Nächster Beitrag
+        PREV_POST: Vorheriger Beitrag
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: SimpleSearch
+      RELATED_POSTS:
+        HEADLINE: Ähnliche Beiträge
+      RANDOM_ARTICLE:
+        HEADLINE: Zufälliger Artikel
+        FEELING_LUCKY: Auf gut Glück!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Text Widget Beispiel
+      POPULAR_TAGS:
+        HEADLINE: Häufigste Tags
+      ARCHIVES:
+        HEADLINE: Archiv
+      SYNDICATE:
+        HEADLINE: Abonnements
+
+es:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Continuar leyendo...
+        NEXT_POST: Siguiente Entrada
+        PREV_POST: Entrada Anterior
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Buscar
+      RELATED_POSTS:
+        HEADLINE: Entradas Relacionadas
+      RANDOM_ARTICLE:
+        HEADLINE: Artículo Aleatorio
+        FEELING_LUCKY: Voy a tener suerte!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Algunos Widget de Texto
+      POPULAR_TAGS:
+        HEADLINE: Etiquetas Populares
+      ARCHIVES:
+        HEADLINE: Archivos
+      SYNDICATE:
+        HEADLINE: Distribuir
+
+fr:
+  THEME_QUARK:
+    TRANSLATION_TEST: Quark !
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Continuer la lecture...
+        NEXT_POST: Article suivant
+        PREV_POST: Article précédent
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Recherche simple
+      RELATED_POSTS:
+        HEADLINE: Articles en relation
+      RANDOM_ARTICLE:
+        HEADLINE: Article aléatoire
+        FEELING_LUCKY: J'ai de la chance !
+      SOME_TEXT_WIDGET:
+        HEADLINE: Du texte gadget
+      POPULAR_TAGS:
+        HEADLINE: Tags populaires
+      ARCHIVES:
+        HEADLINE: Archives
+      SYNDICATE:
+        HEADLINE: Syndication
+
+it:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Continua a leggere...
+        NEXT_POST: Prossimo articolo
+        PREV_POST: Articolo precedente
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: SimpleSearch
+      RELATED_POSTS:
+        HEADLINE: Articoli correlati
+      RANDOM_ARTICLE:
+        HEADLINE: Articolo a caso
+        FEELING_LUCKY: Mi sento fortunato!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Widget di testo
+      POPULAR_TAGS:
+        HEADLINE: Tag popolari
+      ARCHIVES:
+        HEADLINE: Archivio
+      SYNDICATE:
+        HEADLINE: Feed
+
+ro:
+  THEME_QUARK:
+    BLOG:
+     ITEM:
+        CONTINUE_READING: Mai multe...
+        NEXT_POST: Următorul articol
+        PREV_POST: Articolul anterior
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Căutare
+      RELATED_POSTS:
+        HEADLINE: Articole corelate
+      RANDOM_ARTICLE:
+       HEADLINE: Articol aleator
+      FEELING_LUCKY: Mă simt norocos
+      SOME_TEXT_WIDGET:
+        HEADLINE: Text modular
+      POPULAR_TAGS:
+        HEADLINE: Etichete populare
+      ARCHIVES:
+        HEADLINE: Arhive
+      SYNDICATE:
+        HEADLINE: Abonați-vă
+
+ru:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Читать далее...
+        NEXT_POST: Следующая запись
+        PREV_POST: Предыдущая запись
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Поиск
+      RELATED_POSTS:
+        HEADLINE: Также читайте
+      RANDOM_ARTICLE:
+        HEADLINE: Случайная запись
+        FEELING_LUCKY: Мне повезёт!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Текстовой виджет
+      POPULAR_TAGS:
+        HEADLINE: Популярные теги
+      ARCHIVES:
+        HEADLINE: Архив
+      SYNDICATE:
+        HEADLINE: Синдикация
+
+uk:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Читати далі...
+        NEXT_POST: Наступний запис
+        PREV_POST: Попередній запис
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Пошук
+      RELATED_POSTS:
+        HEADLINE: Також читайте
+      RANDOM_ARTICLE:
+        HEADLINE: Випадковий запис
+        FEELING_LUCKY: Мені пощастить!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Текстовий віджет
+      POPULAR_TAGS:
+        HEADLINE: Популярні теги
+      ARCHIVES:
+        HEADLINE: Архів
+      SYNDICATE:
+        HEADLINE: Синдикація
+
+hr:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Nastavi s čitanjem...
+        NEXT_POST: Slijedeća objava
+        PREV_POST: Prethodna objava
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Pretraživanje
+      RELATED_POSTS:
+        HEADLINE: Povezane objave
+      RANDOM_ARTICLE:
+        HEADLINE: Slučajni članak
+        FEELING_LUCKY: Osjećam se sretno!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Neki tekst widget
+      POPULAR_TAGS:
+        HEADLINE: Popularni tagovi
+      ARCHIVES:
+        HEADLINE: Arhiva
+      SYNDICATE:
+        HEADLINE: Kanali
+
+nl:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Lees Meer...
+        NEXT_POST: Volgende Bericht
+        PREV_POST: Vorige Bericht
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Zoek
+      RELATED_POSTS:
+        HEADLINE: Gerelateerde Berichten
+      RANDOM_ARTICLE:
+        HEADLINE: Willekeurig Artikel
+        FEELING_LUCKY: Ik Voel Me Gelukkig!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Een Tekst Widget
+      POPULAR_TAGS:
+        HEADLINE: Populaire Labels
+      ARCHIVES:
+        HEADLINE: Archieven
+      SYNDICATE:
+        HEADLINE: Syndicatie
+
+cs:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: Pokračovat ve čtení...
+        NEXT_POST: Následující příspěvek
+        PREV_POST: Předchozí příspěvek
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: Vyhledávání
+      RELATED_POSTS:
+        HEADLINE: Související příspěvky
+      RANDOM_ARTICLE:
+        HEADLINE: Náhodný článek
+        FEELING_LUCKY: Zkusím štěstí!
+      SOME_TEXT_WIDGET:
+        HEADLINE: Textový widget
+      POPULAR_TAGS:
+        HEADLINE: Oblíbené štítky
+      ARCHIVES:
+        HEADLINE: Archiv
+      SYNDICATE:
+        HEADLINE: Syndikace
+
+zh:
+  THEME_QUARK:
+    BLOG:
+      ITEM:
+        CONTINUE_READING: 继续阅读...
+        NEXT_POST: 下一篇
+        PREV_POST: 上一篇
+    SIDEBAR:
+      SIMPLE_SEARCH:
+        HEADLINE: 搜索
+      RELATED_POSTS:
+        HEADLINE: 相关内容
+      RANDOM_ARTICLE:
+        HEADLINE: 随机一篇
+        FEELING_LUCKY: 手气不错!
+      SOME_TEXT_WIDGET:
+        HEADLINE: 一个文本小部件
+      POPULAR_TAGS:
+        HEADLINE: 热门标签
+      ARCHIVES:
+        HEADLINE: 归档
+      SYNDICATE:
+        HEADLINE: 订阅流

+ 49 - 0
user/themes/quark/package.json

@@ -0,0 +1,49 @@
+{
+  "name": "spectre.css",
+  "version": "0.5.1",
+  "homepage": "http://picturepan2.github.io/spectre",
+  "author": "Yan Zhu <picturepan2@hotmail.com>",
+  "description": "Spectre.css: a lightweight, responsive and modern CSS framework",
+  "main": "docs/dist/spectre.css",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/picturepan2/spectre.git"
+  },
+  "license": "MIT",
+  "keywords": [
+    "css",
+    "framework",
+    "flexbox",
+    "responsive",
+    "mobile-friendly",
+    "front-end",
+    "sass",
+    "modern"
+  ],
+  "bugs": {
+    "url": "https://github.com/picturepan2/spectre/issues"
+  },
+  "devDependencies": {
+    "gulp": "^4.0.0",
+    "gulp-autoprefixer": "^6.1.0",
+    "gulp-clean-css": "^3.9.4",
+    "gulp-csscomb": "^3.0.8",
+    "gulp-rename": "^1.2.2",
+    "gulp-sass": "^4.0.1"
+  },
+  "browserslist": [
+    "last 4 Chrome versions",
+    "Edge >= 12",
+    "Firefox ESR",
+    "last 4 Safari versions",
+    "last 4 Opera versions",
+    "Explorer >= 10"
+  ],
+  "scripts": {
+    "dev": "gulp watch",
+    "build": "gulp build"
+  },
+  "dependencies": {
+    "gulp-sourcemaps": "^2.6.4"
+  }
+}

+ 56 - 0
user/themes/quark/quark.php

@@ -0,0 +1,56 @@
+<?php
+namespace Grav\Theme;
+
+use Grav\Common\Grav;
+use Grav\Common\Theme;
+
+class Quark extends Theme
+{
+    public static function getSubscribedEvents()
+    {
+        return [
+            'onThemeInitialized'    => ['onThemeInitialized', 0],
+            'onTwigLoader'          => ['onTwigLoader', 0],
+            'onTwigInitialized'     => ['onTwigInitialized', 0],
+        ];
+    }
+
+    public function onThemeInitialized()
+    {
+
+    }
+
+    // Add images to twig template paths to allow inclusion of SVG files
+    public function onTwigLoader()
+    {
+        $theme_paths = Grav::instance()['locator']->findResources('theme://images');
+        foreach($theme_paths as $images_path) {
+            $this->grav['twig']->addPath($images_path, 'images');
+        }
+    }
+
+    public function onTwigInitialized()
+    {
+        $twig = $this->grav['twig'];
+
+        $form_class_variables = [
+//            'form_outer_classes' => 'form-horizontal',
+            'form_button_outer_classes' => 'button-wrapper',
+            'form_button_classes' => 'btn',
+            'form_errors_classes' => '',
+            'form_field_outer_classes' => 'form-group',
+            'form_field_outer_label_classes' => 'form-label-wrapper',
+            'form_field_label_classes' => 'form-label',
+//            'form_field_outer_data_classes' => 'col-9',
+            'form_field_input_classes' => 'form-input',
+            'form_field_textarea_classes' => 'form-input',
+            'form_field_select_classes' => 'form-select',
+            'form_field_radio_classes' => 'form-radio',
+            'form_field_checkbox_classes' => 'form-checkbox',
+        ];
+
+        $twig->twig_vars = array_merge($twig->twig_vars, $form_class_variables);
+
+    }
+
+}

+ 12 - 0
user/themes/quark/quark.yaml

@@ -0,0 +1,12 @@
+enabled: true
+production-mode: true
+grid-size: grid-lg
+header-fixed: true
+header-animated: true
+header-dark: false
+header-transparent: false
+sticky-footer: true
+blog-page: '/blog'
+spectre:
+  exp: false
+  icons: false

BIN
user/themes/quark/screenshot.jpg


+ 19 - 0
user/themes/quark/scss/spectre-exp.scss

@@ -0,0 +1,19 @@
+// Variables and mixins
+@import "theme/variables";
+@import "spectre/variables";
+@import "spectre/mixins";
+
+/*! Spectre.css Experimentals v#{$version} | MIT License | github.com/picturepan2/spectre */
+// Experimentals
+@import "spectre/autocomplete";
+@import "spectre/calendars";
+@import "spectre/carousels";
+@import "spectre/comparison-sliders";
+@import "spectre/filters";
+@import "spectre/meters";
+@import "spectre/off-canvas";
+@import "spectre/parallax";
+@import "spectre/progress";
+@import "spectre/sliders";
+@import "spectre/timelines";
+@import "spectre/viewer-360";

+ 11 - 0
user/themes/quark/scss/spectre-icons.scss

@@ -0,0 +1,11 @@
+// Variables and mixins
+@import "theme/variables";
+@import "spectre/variables";
+@import "spectre/mixins";
+
+/*! Spectre.css Icons v#{$version} | MIT License | github.com/picturepan2/spectre */
+// Icons
+@import "spectre/icons/icons-core";
+@import "spectre/icons/icons-navigation";
+@import "spectre/icons/icons-action";
+@import "spectre/icons/icons-object";

+ 53 - 0
user/themes/quark/scss/spectre.scss

@@ -0,0 +1,53 @@
+// Variables and mixins
+@import "theme/variables";
+@import "spectre/variables";
+@import "spectre/mixins";
+
+/*! Spectre.css v#{$version} | MIT License | github.com/picturepan2/spectre */
+// Reset and dependencies
+@import "spectre/normalize";
+@import "spectre/base";
+
+// Elements
+@import "spectre/typography";
+@import "spectre/asian";
+@import "spectre/tables";
+@import "spectre/buttons";
+@import "spectre/forms";
+@import "spectre/labels";
+@import "spectre/codes";
+@import "spectre/media";
+
+// Layout
+@import "spectre/layout";
+@import "spectre/hero";
+@import "spectre/navbar";
+
+// Components
+@import "spectre/accordions";
+@import "spectre/avatars";
+@import "spectre/badges";
+@import "spectre/breadcrumbs";
+@import "spectre/bars";
+@import "spectre/cards";
+@import "spectre/chips";
+@import "spectre/dropdowns";
+@import "spectre/empty";
+@import "spectre/menus";
+@import "spectre/modals";
+@import "spectre/navs";
+@import "spectre/pagination";
+@import "spectre/panels";
+@import "spectre/popovers";
+@import "spectre/steps";
+@import "spectre/tabs";
+@import "spectre/tiles";
+@import "spectre/toasts";
+@import "spectre/tooltips";
+
+// Utility classes
+@import "spectre/animations";
+@import "spectre/utilities";
+
+// Extras
+@import "theme/extensions";

+ 38 - 0
user/themes/quark/scss/spectre/_accordions.scss

@@ -0,0 +1,38 @@
+// Accordions
+.accordion {
+  input:checked ~,
+  &[open] {
+    & .accordion-header {
+      .icon {
+        transform: rotate(90deg);
+      }
+    }
+
+    & .accordion-body {
+      max-height: 50rem;
+    }
+  }
+
+  .accordion-header {
+    display: block;
+    padding: $unit-1 $unit-2;
+
+    .icon {
+      transition: transform .25s;
+    }
+  }
+
+  .accordion-body {
+    margin-bottom: $layout-spacing;
+    max-height: 0;
+    overflow: hidden;
+    transition: max-height .25s;
+  }
+}
+
+// Remove default details marker in Webkit
+summary.accordion-header {
+  &::-webkit-details-marker {
+    display: none;
+  }
+}

+ 20 - 0
user/themes/quark/scss/spectre/_animations.scss

@@ -0,0 +1,20 @@
+// Animations
+@keyframes loading {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
+
+@keyframes slide-down {
+  0% {
+    opacity: 0;
+    transform: translateY(-$unit-8);
+  }
+  100% {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}

+ 43 - 0
user/themes/quark/scss/spectre/_asian.scss

@@ -0,0 +1,43 @@
+// Optimized for East Asian CJK
+html:lang(zh),
+html:lang(zh-Hans),
+.lang-zh,
+.lang-zh-hans {
+  font-family: $cjk-zh-hans-font-family;
+}
+
+html:lang(zh-Hant),
+.lang-zh-hant {
+  font-family: $cjk-zh-hant-font-family;
+}
+
+html:lang(ja),
+.lang-ja {
+  font-family: $cjk-jp-font-family;
+}
+
+html:lang(ko),
+.lang-ko {
+  font-family: $cjk-ko-font-family;
+}
+
+:lang(zh),
+:lang(ja),
+.lang-cjk {
+  ins,
+  u {
+    border-bottom: $border-width solid;
+    text-decoration: none;
+  }
+
+  del + del,
+  del + s,
+  ins + ins,
+  ins + u,
+  s + del,
+  s + s,
+  u + ins,
+  u + u {
+    margin-left: .125em;
+  }
+}

+ 47 - 0
user/themes/quark/scss/spectre/_autocomplete.scss

@@ -0,0 +1,47 @@
+// Autocomplete
+.form-autocomplete {
+  position: relative;
+
+  .form-autocomplete-input {
+    align-content: flex-start;
+    display: flex;
+    flex-wrap: wrap;
+    height: auto;
+    min-height: $unit-8;
+    padding: $unit-h;
+
+    &.is-focused {
+      @include control-shadow();
+      border-color: $primary-color;
+    }
+
+    .form-input {
+      border-color: transparent;
+      box-shadow: none;
+      display: inline-block;
+      flex: 1 0 auto;
+      height: $unit-6;
+      line-height: $unit-4;
+      margin: $unit-h;
+      width: auto;
+    }
+  }
+
+  .menu {
+    left: 0;
+    position: absolute;
+    top: 100%;
+    width: 100%;
+  }
+
+  &.autocomplete-oneline {
+    .form-autocomplete-input {
+      flex-wrap: nowrap;
+      overflow-x: auto;
+    }
+
+    .chip {
+      flex: 1 0 auto;
+    }
+  }
+}

+ 77 - 0
user/themes/quark/scss/spectre/_avatars.scss

@@ -0,0 +1,77 @@
+// Avatars
+.avatar {
+  @include avatar-base();
+  background: $primary-color;
+  border-radius: 50%;
+  color: rgba($light-color, .85);
+  display: inline-block;
+  font-weight: 300;
+  line-height: 1.25;
+  margin: 0;
+  position: relative;
+  vertical-align: middle;
+
+  &.avatar-xs {
+    @include avatar-base($unit-4);
+  }
+  &.avatar-sm {
+    @include avatar-base($unit-6);
+  }
+  &.avatar-lg {
+    @include avatar-base($unit-12);
+  }
+  &.avatar-xl {
+    @include avatar-base($unit-16);
+  }
+
+  img {
+    border-radius: 50%;
+    height: 100%;
+    position: relative;
+    width: 100%;
+    z-index: $zindex-0;
+  }
+
+  .avatar-icon,
+  .avatar-presence {
+    background: $bg-color-light;
+    bottom: 14.64%;
+    height: 50%;
+    padding: $border-width-lg;
+    position: absolute;
+    right: 14.64%;
+    transform: translate(50%, 50%);
+    width: 50%;
+    z-index: $zindex-0 + 1;
+  }
+
+  .avatar-presence {
+    background: $gray-color;
+    box-shadow: 0 0 0 $border-width-lg $light-color;
+    border-radius: 50%;
+    height: .5em;
+    width: .5em;
+
+    &.online {
+      background: $success-color;
+    }
+
+    &.busy {
+      background: $error-color;
+    }
+
+    &.away {
+      background: $warning-color;
+    }
+  }
+
+  &[data-initial]::before {
+    color: currentColor;
+    content: attr(data-initial);
+    left: 50%;
+    position: absolute;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    z-index: $zindex-0;
+  }
+}

+ 60 - 0
user/themes/quark/scss/spectre/_badges.scss

@@ -0,0 +1,60 @@
+// Badges
+.badge {
+  position: relative;
+  white-space: nowrap;
+
+  &[data-badge],
+  &:not([data-badge]) {
+    &::after {
+      background: $primary-color;
+      background-clip: padding-box;
+      border-radius: .5rem;
+      box-shadow: 0 0 0 .1rem $bg-color-light;
+      color: $light-color;
+      content: attr(data-badge);
+      display: inline-block;
+      transform: translate(-.05rem, -.5rem);
+    }
+  }
+  &[data-badge] {
+    &::after {
+      font-size: $font-size-sm;
+      height: .9rem;
+      line-height: 1;
+      min-width: .9rem;
+      padding: .1rem .2rem;
+      text-align: center;
+      white-space: nowrap;
+    }
+  }
+  &:not([data-badge]),
+  &[data-badge=""] {
+    &::after {
+      height: 6px;
+      min-width: 6px;
+      padding: 0;
+      width: 6px;
+    }
+  }
+
+  // Badges for Buttons
+  &.btn {
+    &::after {
+      position: absolute;
+      top: 0;
+      right: 0;
+      transform: translate(50%, -50%);
+    }
+  }
+
+  // Badges for Avatars
+  &.avatar {
+    &::after {
+      position: absolute;
+      top: 14.64%;
+      right: 14.64%;
+      transform: translate(50%, -50%);
+      z-index: $zindex-1;
+    }
+  }
+}

+ 71 - 0
user/themes/quark/scss/spectre/_bars.scss

@@ -0,0 +1,71 @@
+// Bars
+.bar {
+  background: $bg-color-dark;
+  border-radius: $border-radius;
+  display: flex;
+  flex-wrap: nowrap;
+  height: $unit-4;
+  width: 100%;
+
+  &.bar-sm {
+    height: $unit-1;
+  }
+
+  // TODO: attr() support
+  .bar-item {
+    background: $primary-color;
+    color: $light-color;
+    display: block;
+    font-size: $font-size-sm;
+    flex-shrink: 0;
+    line-height: $unit-4;
+    height: 100%;
+    position: relative;
+    text-align: center;
+    width: 0;
+
+    &:first-child {
+      border-bottom-left-radius: $border-radius;
+      border-top-left-radius: $border-radius;
+    }
+    &:last-child {
+      border-bottom-right-radius: $border-radius;
+      border-top-right-radius: $border-radius;
+      flex-shrink: 1;
+    }
+  }
+}
+
+// Slider bar
+.bar-slider {
+  height: $border-width-lg;
+  margin: $layout-spacing 0;
+  position: relative;
+
+  .bar-item {
+    left: 0;
+    padding: 0;
+    position: absolute;
+    &:not(:last-child):first-child {
+      background: $bg-color-dark;
+      z-index: $zindex-0;
+    }
+  }
+
+  .bar-slider-btn {
+    background: $primary-color;
+    border: 0;
+    border-radius: 50%;
+    height: $unit-3;
+    padding: 0;
+    position: absolute;
+    right: 0;
+    top: 50%;
+    transform: translate(50%, -50%);
+    width: $unit-3;
+
+    &:active {
+      box-shadow: 0 0 0 .1rem $primary-color;
+    }
+  }
+}

+ 44 - 0
user/themes/quark/scss/spectre/_base.scss

@@ -0,0 +1,44 @@
+// Base
+*,
+*::before,
+*::after {
+  box-sizing: inherit;
+}
+
+html {
+  box-sizing: border-box;
+  font-size: $html-font-size;
+  line-height: $html-line-height;
+  -webkit-tap-highlight-color: transparent;
+}
+
+body {
+  background: $body-bg;
+  color: $body-font-color;
+  font-family: $body-font-family;
+  font-size: $font-size;
+  overflow-x: hidden;
+  text-rendering: optimizeLegibility;
+}
+
+a {
+  color: $link-color;
+  outline: none;
+  text-decoration: none;
+
+  &:focus {
+    @include control-shadow();
+  }
+
+  &:focus,
+  &:hover,
+  &:active,
+  &.active {
+    color: $link-color-dark;
+    text-decoration: underline;
+  }
+
+  &:visited {
+    color: $link-color-light;
+  }
+}

+ 29 - 0
user/themes/quark/scss/spectre/_breadcrumbs.scss

@@ -0,0 +1,29 @@
+// Breadcrumbs
+.breadcrumb {
+  list-style: none;
+  margin: $unit-1 0;
+  padding: $unit-1 0;
+
+  .breadcrumb-item {
+    color: $gray-color-dark;
+    display: inline-block;
+    margin: 0;
+    padding: $unit-1 0;
+
+    &:not(:last-child) {
+      margin-right: $unit-1;
+
+      a {
+        color: $gray-color-dark;
+      }
+    }
+
+    &:not(:first-child) {
+      &::before {
+        color: $gray-color-dark;
+        content: "/";
+        padding-right: $unit-2;
+      }
+    }
+  }
+}

+ 193 - 0
user/themes/quark/scss/spectre/_buttons.scss

@@ -0,0 +1,193 @@
+// Buttons
+.btn {
+  appearance: none;
+  background: $bg-color-light;
+  border: $border-width solid $primary-color;
+  border-radius: $border-radius;
+  color: $primary-color;
+  cursor: pointer;
+  display: inline-block;
+  font-size: $font-size;
+  height: $control-size;
+  line-height: $line-height;
+  outline: none;
+  padding: $control-padding-y $control-padding-x;
+  text-align: center;
+  text-decoration: none;
+  transition: background .2s, border .2s, box-shadow .2s, color .2s;
+  user-select: none;
+  vertical-align: middle;
+  white-space: nowrap;
+  &:focus {
+    @include control-shadow();
+  }
+  &:focus,
+  &:hover {
+    background: $secondary-color;
+    border-color: $primary-color-dark;
+    text-decoration: none;
+  }
+  &:active,
+  &.active {
+    background: $primary-color-dark;
+    border-color: darken($primary-color-dark, 5%);
+    color: $light-color;
+    text-decoration: none;
+    &.loading {
+      &::after {
+        border-bottom-color: $light-color;
+        border-left-color: $light-color;
+      }
+    }
+  }
+  &[disabled],
+  &:disabled,
+  &.disabled {
+    cursor: default;
+    opacity: .5;
+    pointer-events: none;
+  }
+
+  // Button Primary
+  &.btn-primary {
+    background: $primary-color;
+    border-color: $primary-color-dark;
+    color: $light-color;
+    &:focus,
+    &:hover {
+      background: darken($primary-color-dark, 2%);
+      border-color: darken($primary-color-dark, 5%);
+      color: $light-color;
+    }
+    &:active,
+    &.active {
+      background: darken($primary-color-dark, 4%);
+      border-color: darken($primary-color-dark, 7%);
+      color: $light-color;
+    }
+    &.loading {
+      &::after {
+        border-bottom-color: $light-color;
+        border-left-color: $light-color;
+      }
+    }
+  }
+
+  // Button Colors
+  &.btn-success {
+    @include button-variant($success-color);
+  }
+
+  &.btn-error {
+    @include button-variant($error-color);
+  }
+
+  // Button Link
+  &.btn-link {
+    background: transparent;
+    border-color: transparent;
+    color: $link-color;
+    &:focus,
+    &:hover,
+    &:active,
+    &.active {
+      color: $link-color-dark;
+    }
+  }
+
+  // Button Sizes
+  &.btn-sm {
+    font-size: $font-size-sm;
+    height: $control-size-sm;
+    padding: $control-padding-y-sm $control-padding-x-sm;
+  }
+
+  &.btn-lg {
+    font-size: $font-size-lg;
+    height: $control-size-lg;
+    padding: $control-padding-y-lg $control-padding-x-lg;
+  }
+
+  // Button Block
+  &.btn-block {
+    display: block;
+    width: 100%;
+  }
+
+  // Button Action
+  &.btn-action {
+    width: $control-size;
+    padding-left: 0;
+    padding-right: 0;
+
+    &.btn-sm {
+      width: $control-size-sm;
+    }
+
+    &.btn-lg {
+      width: $control-size-lg;
+    }
+  }
+
+  // Button Clear
+  &.btn-clear {
+    background: transparent;
+    border: 0;
+    color: currentColor;
+    height: $unit-5;
+    line-height: $unit-4;
+    margin-left: $unit-1;
+    margin-right: -2px;
+    opacity: 1;
+    padding: $unit-h;
+    text-decoration: none;
+    width: $unit-5;
+
+    &:focus,
+    &:hover {
+      background: rgba($bg-color, .5);
+      opacity: .95;
+    }
+
+    &::before {
+      content: "\2715";
+    }
+  }
+}
+
+// Button groups
+.btn-group {
+  display: inline-flex;
+  flex-wrap: wrap;
+
+  .btn {
+    flex: 1 0 auto;
+    &:first-child:not(:last-child) {
+      border-bottom-right-radius: 0;
+      border-top-right-radius: 0;
+    }
+    &:not(:first-child):not(:last-child) {
+      border-radius: 0;
+      margin-left: -$border-width;
+    }
+    &:last-child:not(:first-child) {
+      border-bottom-left-radius: 0;
+      border-top-left-radius: 0;
+      margin-left: -$border-width;
+    }
+    &:focus,
+    &:hover,
+    &:active,
+    &.active {
+      z-index: $zindex-0;
+    }
+  }
+
+  &.btn-group-block {
+    display: flex;
+
+    .btn {
+      flex: 1 0 0;
+    }
+  }
+}

+ 222 - 0
user/themes/quark/scss/spectre/_calendars.scss

@@ -0,0 +1,222 @@
+// Calendars
+.calendar {
+  border: $border-width solid $border-color;
+  border-radius: $border-radius;
+  display: block;
+  min-width: 280px;
+
+  .calendar-nav {
+    align-items: center;
+    background: $bg-color;
+    border-top-left-radius: $border-radius;
+    border-top-right-radius: $border-radius;
+    display: flex;
+    font-size: $font-size-lg;
+    padding: $layout-spacing;
+  }
+
+  .calendar-header,
+  .calendar-body {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: center;
+    padding: $layout-spacing 0;
+
+    .calendar-date {
+      flex: 0 0 14.28%; // 7 calendar-items each row
+      max-width: 14.28%;
+    }
+  }
+
+  .calendar-header {
+    background: $bg-color;
+    border-bottom: $border-width solid $border-color;
+    color: $gray-color;
+    font-size: $font-size-sm;
+    text-align: center;
+  }
+
+  .calendar-body {
+    color: $gray-color-dark;
+  }
+
+  .calendar-date {
+    border: 0;
+    padding: $unit-1;
+
+    .date-item {
+      appearance: none;
+      background: transparent;
+      border: $border-width solid transparent;
+      border-radius: 50%;
+      color: $gray-color-dark;
+      cursor: pointer;
+      font-size: $font-size-sm;
+      height: $unit-7;
+      line-height: $unit-5;
+      outline: none;
+      padding: $unit-h;
+      position: relative;
+      text-align: center;
+      text-decoration: none;
+      transition: background .2s, border .2s, box-shadow .2s, color .2s;
+      vertical-align: middle;
+      white-space: nowrap;
+      width: $unit-7;
+
+      &.date-today {
+        border-color: $secondary-color-dark;
+        color: $primary-color;
+      }
+
+      &:focus {
+        @include control-shadow();
+      }
+
+      &:focus,
+      &:hover {
+        background: $secondary-color-light;
+        border-color: $secondary-color-dark;
+        color: $primary-color;
+        text-decoration: none;
+      }
+      &:active,
+      &.active {
+        background: $primary-color-dark;
+        border-color: darken($primary-color-dark, 5%);
+        color: $light-color;
+      }
+
+      // Calendar badge support
+      &.badge {
+        &::after {
+          position: absolute;
+          top: 3px;
+          right: 3px;
+          transform: translate(50%, -50%);
+        }
+      }
+    }
+
+    .date-item,
+    .calendar-event {
+      &:disabled,
+      &.disabled {
+        cursor: default;
+        opacity: .25;
+        pointer-events: none;
+      }
+    }
+
+    &.prev-month,
+    &.next-month {
+      .date-item,
+      .calendar-event {
+        opacity: .25;
+      }
+    }
+  }
+
+  .calendar-range {
+    position: relative;
+
+    &::before {
+      background: $secondary-color;
+      content: "";
+      height: $unit-7;
+      left: 0;
+      position: absolute;
+      right: 0;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+    &.range-start {
+      &::before {
+        left: 50%;
+      }
+    }
+    &.range-end {
+      &::before {
+        right: 50%;
+      }
+    }
+
+    &.range-start,
+    &.range-end {
+      .date-item {
+        background: $primary-color-dark;
+        border-color: darken($primary-color-dark, 5%);
+        color: $light-color;
+      }
+    }
+
+    .date-item {
+      color: $primary-color;
+    }
+  }
+
+  // Calendars size
+  &.calendar-lg {
+    .calendar-body {
+      padding: 0;
+
+      .calendar-date {
+        border-bottom: $border-width solid $border-color;
+        border-right: $border-width solid $border-color;
+        display: flex;
+        flex-direction: column;
+        height: 5.5rem;
+        padding: 0;
+
+        &:nth-child(7n) {
+          border-right: 0;
+        }
+        &:nth-last-child(-n+7) {
+          border-bottom: 0;
+        }
+      }
+    }
+
+    .date-item {
+      align-self: flex-end;
+      height: $unit-7;
+      margin-right: $layout-spacing-sm;
+      margin-top: $layout-spacing-sm;
+    }
+
+    .calendar-range {
+      &::before {
+        top: 19px;
+      }
+      &.range-start {
+        &::before {
+          left: auto;
+          width: 19px;
+        }
+      }
+      &.range-end {
+        &::before {
+          right: 19px;
+        }
+      }
+    }
+
+    .calendar-events {
+      flex-grow: 1;
+      line-height: 1;
+      overflow-y: auto;
+      padding: $layout-spacing-sm;
+    }
+
+    .calendar-event {
+      border-radius: $border-radius;
+      font-size: $font-size-sm;
+      display: block;
+      margin: $unit-h auto;
+      overflow: hidden;
+      padding: 3px 4px;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  }
+}

+ 43 - 0
user/themes/quark/scss/spectre/_cards.scss

@@ -0,0 +1,43 @@
+// Cards
+.card {
+  background: $bg-color-light;
+  border: $border-width solid $border-color;
+  border-radius: $border-radius;
+  display: flex;
+  flex-direction: column;
+
+  .card-header,
+  .card-body,
+  .card-footer {
+    padding: $layout-spacing-lg;
+    padding-bottom: 0;
+
+    &:last-child {
+      padding-bottom: $layout-spacing-lg;
+    }
+  }
+
+  .card-body {
+    flex: 1 1 auto;
+  }
+
+  .card-image {
+    padding-top: $layout-spacing-lg;
+
+    &:first-child {
+      padding-top: 0;
+
+      img {
+        border-top-left-radius: $border-radius;
+        border-top-right-radius: $border-radius;
+      }
+    }
+
+    &:last-child {
+      img {
+        border-bottom-left-radius: $border-radius;
+        border-bottom-right-radius: $border-radius;
+      }
+    }
+  }
+}

+ 136 - 0
user/themes/quark/scss/spectre/_carousels.scss

@@ -0,0 +1,136 @@
+// Carousels
+// The number of carousel images
+$carousel-number: 8;
+
+%carousel-image-checked { 
+  animation: carousel-slidein .75s ease-in-out 1;
+  opacity: 1;
+  z-index: $zindex-1;
+}
+
+%carousel-nav-checked { 
+  color: $gray-color-light;
+}
+
+.carousel {
+  background: $bg-color;
+  display: block;
+  overflow: hidden;
+  position: relative;
+  width: 100%;
+  -webkit-overflow-scrolling: touch;
+  z-index: $zindex-0;
+
+  .carousel-container {
+    height: 100%;
+    left: 0;
+    position: relative;
+    &::before {
+      content: "";
+      display: block;
+      padding-bottom: 56.25%;
+    }
+
+    .carousel-item {
+      animation: carousel-slideout 1s ease-in-out 1;
+      height: 100%;
+      left: 0;
+      margin: 0;
+      opacity: 0;
+      position: absolute;
+      top: 0;
+      width: 100%;
+
+      &:hover {
+        .item-prev,
+        .item-next {
+          opacity: 1;
+        }
+      }
+    }
+
+    .item-prev,
+    .item-next {
+      background: rgba($gray-color-light, .25);
+      border-color: rgba($gray-color-light, .5);
+      color: $gray-color-light;
+      opacity: 0;
+      position: absolute;
+      top: 50%;
+      transition: all .4s;
+      transform: translateY(-50%);
+      z-index: $zindex-1;
+    }
+    .item-prev {
+      left: 1rem;
+    }
+    .item-next {
+      right: 1rem;
+    }
+  }
+
+  .carousel-locator {
+    @for $i from 1 through ($carousel-number) {
+      &:nth-of-type(#{$i}):checked ~ .carousel-container .carousel-item:nth-of-type(#{$i}) {
+        @extend %carousel-image-checked;
+      }
+    }
+
+    @for $i from 1 through ($carousel-number) {
+      &:nth-of-type(#{$i}):checked ~ .carousel-nav .nav-item:nth-of-type(#{$i}) {
+        @extend %carousel-nav-checked;
+      }
+    }
+  }
+
+  .carousel-nav {
+    bottom: $layout-spacing;
+    display: flex;
+    justify-content: center;
+    left: 50%;
+    position: absolute;
+    transform: translateX(-50%);
+    width: 10rem;
+    z-index: $zindex-1;
+
+    .nav-item {
+      color: rgba($gray-color-light, .5);
+      display: block;
+      flex: 1 0 auto;
+      height: $unit-8;
+      margin: $unit-1;
+      max-width: 2.5rem;
+      position: relative;
+
+      &::before {
+        background: currentColor;
+        content: "";
+        display: block;
+        height: $unit-h;
+        position: absolute;
+        top: .5rem;
+        width: 100%;
+      }
+    }
+  }
+}
+
+@keyframes carousel-slidein {
+  0% {
+    transform: translateX(100%);
+  }
+  100% {
+    transform: translateX(0);
+  }
+}
+
+@keyframes carousel-slideout {
+  0% {
+    opacity: 1;
+    transform: translateX(0);
+  }
+  100% {
+    opacity: 1;
+    transform: translateX(-50%);
+  }
+}

+ 33 - 0
user/themes/quark/scss/spectre/_chips.scss

@@ -0,0 +1,33 @@
+// Chips
+.chip {
+  align-items: center;
+  background: $bg-color-dark;
+  border-radius: 5rem;
+  display: inline-flex;
+  font-size: 90%;
+  height: $unit-6;
+  line-height: $unit-4;
+  margin: $unit-h;
+  max-width: $control-width-sm;
+  overflow: hidden;
+  padding: $unit-1 $unit-2;
+  text-decoration: none;
+  text-overflow: ellipsis;
+  vertical-align: middle;
+  white-space: nowrap;
+
+  &.active {
+    background: $primary-color;
+    color: $light-color;
+  }
+
+  .avatar {
+    margin-left: -$unit-2;
+    margin-right: $unit-1;
+  }
+
+  .btn-clear {
+    border-radius: 50%;
+    transform: scale(.75);
+  }
+}

+ 31 - 0
user/themes/quark/scss/spectre/_codes.scss

@@ -0,0 +1,31 @@
+// Codes
+code {
+  @include label-base();
+  @include label-variant($code-color, lighten($code-color, 42.5%));
+  font-size: 85%;
+}
+
+.code {
+  border-radius: $border-radius;
+  color: $body-font-color;
+  position: relative;
+
+  &::before {
+    color: $gray-color;
+    content: attr(data-lang);
+    font-size: $font-size-sm;
+    position: absolute;
+    right: $layout-spacing;
+    top: $unit-h;
+  }
+
+  code {
+    background: $bg-color;
+    color: inherit;
+    display: block;
+    line-height: 1.5;
+    overflow-x: auto;
+    padding: 1rem;
+    width: 100%;
+  }
+}

+ 115 - 0
user/themes/quark/scss/spectre/_comparison-sliders.scss

@@ -0,0 +1,115 @@
+// Image comparison slider
+// Credit: http://codepen.io/solipsistacp/pen/Gpmaq
+.comparison-slider {
+  height: 50vh;
+  overflow: hidden;
+  position: relative;
+  width: 100%;
+  -webkit-overflow-scrolling: touch;
+
+  .comparison-before,
+  .comparison-after {
+    height: 100%;
+    left: 0;
+    margin: 0;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+
+    img {
+      height: 100%;
+      object-fit: cover;
+      object-position: left center;
+      position: absolute;
+      width: 100%;
+    }
+  }
+
+  .comparison-before {
+    width: 100%;
+    z-index: 1;
+
+    .comparison-label {
+      right: $unit-4;
+    }
+  }
+
+  .comparison-after {
+    max-width: 100%;
+    min-width: 0;
+    z-index: 2;
+
+    &::before {
+      background: transparent;
+      content: "";
+      cursor: default;
+      height: 100%;
+      left: 0;
+      position: absolute;
+      right: $unit-4;
+      top: 0;
+      z-index: $zindex-0;
+    }
+
+    &::after {
+      background: currentColor;
+      border-radius: 50%;
+      box-shadow: 0 -5px, 0 5px;
+      color: $light-color;
+      content: "";
+      height: 3px;
+      position: absolute;
+      right: $unit-2;
+      top: 50%;
+      transform: translate(50%, -50%);
+      width: 3px;
+    }
+
+    .comparison-label {
+      left: $unit-4;
+    }
+  }
+
+  .comparison-resizer {
+    animation: first-run 1.5s 1 ease-in-out;
+    cursor: ew-resize;
+    height: $unit-4;
+    left: 0;
+    max-width: 100%;
+    min-width: $unit-4;
+    opacity: 0;
+    outline: none;
+    position: relative;
+    resize: horizontal;
+    top: 50%;
+    transform: translateY(-50%) scaleY(30);
+    width: 0;
+  }
+
+  .comparison-label {
+    background: rgba($dark-color, .5);
+    bottom: $unit-4;
+    color: $light-color;
+    padding: $unit-1 $unit-2;
+    position: absolute;
+    user-select: none;
+  }
+}
+
+@keyframes first-run {
+  0% {
+    width: 0;
+  }
+  25% {
+    width: $unit-12;
+  }
+  50% {
+    width: $unit-4;
+  }
+  75% {
+    width: $unit-6;
+  }
+  100% {
+    width: 0;
+  }
+}

+ 36 - 0
user/themes/quark/scss/spectre/_dropdowns.scss

@@ -0,0 +1,36 @@
+// Dropdown
+.dropdown {
+  display: inline-block;
+  position: relative;
+
+  .menu {
+    animation: slide-down .15s ease 1;
+    display: none;
+    left: 0;
+    max-height: 50vh;
+    overflow-y: auto;
+    position: absolute;
+    top: 100%;
+  }
+
+  &.dropdown-right {
+    .menu {
+      left: auto;
+      right: 0;
+    }
+  }
+
+  &.active .menu,
+  .dropdown-toggle:focus + .menu,
+  .menu:hover {
+    display: block;
+  }
+
+  // Fix dropdown-toggle border radius in button groups
+  .btn-group {
+    .dropdown-toggle:nth-last-child(2) {
+      border-bottom-right-radius: $border-radius;
+      border-top-right-radius: $border-radius;
+    }
+  }
+}

+ 21 - 0
user/themes/quark/scss/spectre/_empty.scss

@@ -0,0 +1,21 @@
+// Empty states (or Blank slates)
+.empty {
+  background: $bg-color;
+  border-radius: $border-radius;
+  color: $gray-color-dark;
+  text-align: center;
+  padding: $unit-16 $unit-8;
+
+  .empty-icon {
+    margin-bottom: $layout-spacing-lg;
+  }
+
+  .empty-title,
+  .empty-subtitle {
+    margin: $layout-spacing auto;
+  }
+
+  .empty-action {
+    margin-top: $layout-spacing-lg;
+  }
+}

+ 37 - 0
user/themes/quark/scss/spectre/_filters.scss

@@ -0,0 +1,37 @@
+// Filters 
+// The number of filter options 
+$filter-number: 8 !default;
+
+%filter-checked-nav { 
+  background: $primary-color;
+  color: $light-color;
+}
+
+%filter-checked-body { 
+  display: none;
+}
+
+.filter {
+  .filter-nav {
+    margin: $layout-spacing 0;
+  }
+
+  .filter-body {
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  .filter-tag {
+    @for $i from 0 through ($filter-number) {
+      &#tag-#{$i}:checked ~ .filter-nav .chip[for="tag-#{$i}"] {
+        @extend %filter-checked-nav;
+      }
+    }
+
+    @for $i from 1 through ($filter-number) {
+      &#tag-#{$i}:checked ~ .filter-body .filter-item:not([data-tag~="tag-#{$i}"]) {
+        @extend %filter-checked-body;
+      }
+    }
+  }
+}

+ 555 - 0
user/themes/quark/scss/spectre/_forms.scss

@@ -0,0 +1,555 @@
+// Forms
+.form-group {
+  &:not(:last-child) {
+    margin-bottom: $layout-spacing;
+  }
+}
+
+fieldset {
+  margin-bottom: $layout-spacing-lg;
+}
+
+legend {
+  font-size: $font-size-lg;
+  font-weight: 500;
+  margin-bottom: $layout-spacing-lg;
+}
+
+// Form element: Label
+.form-label {
+  display: block;
+  line-height: $line-height;
+  padding: $control-padding-y + $border-width 0;
+
+  &.label-sm {
+    font-size: $font-size-sm;
+    padding: $control-padding-y-sm + $border-width 0;
+  }
+
+  &.label-lg {
+    font-size: $font-size-lg;
+    padding: $control-padding-y-lg + $border-width 0;
+  }
+}
+
+// Form element: Input
+.form-input {
+  appearance: none;
+  background: $bg-color-light;
+  background-image: none;
+  border: $border-width solid $border-color-dark;
+  border-radius: $border-radius;
+  color: $body-font-color;
+  display: block;
+  font-size: $font-size;
+  height: $control-size;
+  line-height: $line-height;
+  max-width: 100%;
+  outline: none;
+  padding: $control-padding-y $control-padding-x;
+  position: relative;
+  transition: background .2s, border .2s, box-shadow .2s, color .2s;
+  width: 100%;
+  &:focus {
+    @include control-shadow();
+    border-color: $primary-color;
+  }
+  &::placeholder {
+    color: $gray-color;
+  }
+
+  // Input sizes
+  &.input-sm {
+    font-size: $font-size-sm;
+    height: $control-size-sm;
+    padding: $control-padding-y-sm $control-padding-x-sm;
+  }
+
+  &.input-lg {
+    font-size: $font-size-lg;
+    height: $control-size-lg;
+    padding: $control-padding-y-lg $control-padding-x-lg;
+  }
+
+  &.input-inline {
+    display: inline-block;
+    vertical-align: middle;
+    width: auto;
+  }
+
+  // Input types
+  &[type="file"] {
+    height: auto;
+  }
+}
+
+// Form element: Textarea
+textarea.form-input {
+  &,
+  &.input-lg,
+  &.input-sm {
+    height: auto;
+  }
+}
+
+// Form element: Input hint
+.form-input-hint {
+  color: $gray-color;
+  font-size: $font-size-sm;
+  margin-top: $unit-1;
+
+  .has-success &,
+  .is-success + & {
+    color: $success-color;
+  }
+
+  .has-error &,
+  .is-error + & {
+    color: $error-color;
+  }
+}
+
+// Form element: Select
+.form-select {
+  appearance: none;
+  border: $border-width solid $border-color-dark;
+  border-radius: $border-radius;
+  color: inherit;
+  font-size: $font-size;
+  height: $control-size;
+  line-height: $line-height;
+  outline: none;
+  padding: $control-padding-y $control-padding-x;
+  vertical-align: middle;
+  width: 100%;
+  background: $bg-color-light; 
+  &:focus {
+    @include control-shadow();
+    border-color: $primary-color;
+  }
+  &::-ms-expand {
+    display: none;
+  }
+
+  // Select sizes
+  &.select-sm {
+    font-size: $font-size-sm;
+    height: $control-size-sm;
+    padding: $control-padding-y-sm ($control-icon-size + $control-padding-x-sm) $control-padding-y-sm $control-padding-x-sm;
+  }
+
+  &.select-lg {
+    font-size: $font-size-lg;
+    height: $control-size-lg;
+    padding: $control-padding-y-lg ($control-icon-size + $control-padding-x-lg) $control-padding-y-lg $control-padding-x-lg;
+  }
+
+  // Multiple select
+  &[size],
+  &[multiple] {
+    height: auto;
+    padding: $control-padding-y $control-padding-x;
+
+    option {
+      padding: $unit-h $unit-1;
+    }
+  }
+  &:not([multiple]):not([size]) {
+    background: $bg-color-light url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%204%205'%3E%3Cpath%20fill='%23667189'%20d='M2%200L0%202h4zm0%205L0%203h4z'/%3E%3C/svg%3E") no-repeat right .35rem center / .4rem .5rem;
+    padding-right: $control-icon-size + $control-padding-x;
+  }
+}
+
+// Form Icons
+.has-icon-left,
+.has-icon-right {
+  position: relative;
+
+  .form-icon {
+    height: $control-icon-size;
+    margin: 0 $control-padding-y;
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    width: $control-icon-size;
+    z-index: $zindex-0 + 1;
+  }
+}
+
+.has-icon-left {
+  .form-icon {
+    left: $border-width;
+  }
+
+  .form-input {
+    padding-left: $control-icon-size + $control-padding-y * 2;
+  }
+}
+
+.has-icon-right {
+  .form-icon {
+    right: $border-width;
+  }
+
+  .form-input {
+    padding-right: $control-icon-size + $control-padding-y * 2;
+  }
+}
+
+// Form element: Checkbox and Radio
+.form-checkbox,
+.form-radio,
+.form-switch {
+  display: block;
+  line-height: $line-height;
+  margin: ($control-size - $control-size-sm) / 2 0;
+  min-height: $control-size-sm;
+  padding: (($control-size-sm - $line-height) / 2) $control-padding-x (($control-size-sm - $line-height) / 2) ($control-icon-size + $control-padding-x);
+  position: relative;
+
+  input {
+    clip: rect(0, 0, 0, 0);
+    height: 1px;
+    margin: -1px;
+    overflow: hidden;
+    position: absolute;
+    width: 1px;
+    &:focus + .form-icon {
+      @include control-shadow();
+      border-color: $primary-color;
+    }
+    &:checked + .form-icon {
+      background: $primary-color;
+      border-color: $primary-color;
+    }
+  }
+
+  .form-icon {
+    border: $border-width solid $border-color-dark;
+    cursor: pointer;
+    display: inline-block;
+    position: absolute;
+    transition: background .2s, border .2s, box-shadow .2s, color .2s;
+  }
+
+  // Input checkbox, radio and switch sizes
+  &.input-sm {
+    font-size: $font-size-sm;
+    margin: 0;
+  }
+
+  &.input-lg {
+    font-size: $font-size-lg;
+    margin: ($control-size-lg - $control-size-sm) / 2 0;
+  }
+}
+
+.form-checkbox,
+.form-radio {
+  .form-icon {
+    background: $bg-color-light;
+    height: $control-icon-size;
+    left: 0;
+    top: ($control-size-sm - $control-icon-size) / 2;
+    width: $control-icon-size;
+  }
+
+  input {
+    &:active + .form-icon {
+      background: $bg-color-dark;
+    }
+  }
+}
+.form-checkbox {
+  .form-icon {
+    border-radius: $border-radius;
+  }
+
+  input {
+    &:checked + .form-icon {
+      &::before {
+        background-clip: padding-box;
+        border: $border-width-lg solid $light-color;
+        border-left-width: 0;
+        border-top-width: 0;
+        content: "";
+        height: 9px;
+        left: 50%;
+        margin-left: -3px;
+        margin-top: -6px;
+        position: absolute;
+        top: 50%;
+        transform: rotate(45deg);
+        width: 6px;
+      }
+    }
+    &:indeterminate + .form-icon {
+      background: $primary-color;
+      border-color: $primary-color;
+      &::before {
+        background: $bg-color-light;
+        content: "";
+        height: 2px;
+        left: 50%;
+        margin-left: -5px;
+        margin-top: -1px;
+        position: absolute;
+        top: 50%;
+        width: 10px;
+      }
+    }
+  }
+}
+.form-radio {
+  .form-icon {
+    border-radius: 50%;
+  }
+
+  input {
+    &:checked + .form-icon {
+      &::before {
+        background: $bg-color-light;
+        border-radius: 50%;
+        content: "";
+        height: 6px;
+        left: 50%;
+        position: absolute;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        width: 6px;
+      }
+    }
+  }
+}
+
+// Form element: Switch
+.form-switch {
+  padding-left: ($unit-8 + $control-padding-x);
+
+  .form-icon {
+    background: $gray-color;
+    background-clip: padding-box;
+    border-radius: $unit-2 + $border-width;
+    height: $unit-4 + $border-width * 2;
+    left: 0;
+    top: ($control-size-sm - $unit-4) / 2 - $border-width;
+    width: $unit-8;
+    &::before {
+      background: $bg-color-light;
+      border-radius: 50%;
+      content: "";
+      display: block;
+      height: $unit-4;
+      left: 0;
+      position: absolute;
+      top: 0;
+      transition: background .2s, border .2s, box-shadow .2s, color .2s, left .2s;
+      width: $unit-4;
+    }
+  }
+
+  input {
+    &:checked + .form-icon {
+      &::before {
+        left: 14px;
+      }
+    }
+    &:active + .form-icon {
+      &::before {
+        background: $bg-color;
+      }
+    }
+  }
+}
+
+// Form element: Input groups
+.input-group {
+  display: flex;
+
+  .input-group-addon {
+    background: $bg-color;
+    border: $border-width solid $border-color-dark;
+    border-radius: $border-radius;
+    line-height: $line-height;
+    padding: $control-padding-y $control-padding-x;
+    white-space: nowrap;
+
+    &.addon-sm {
+      font-size: $font-size-sm;
+      padding: $control-padding-y-sm $control-padding-x-sm;
+    }
+
+    &.addon-lg {
+      font-size: $font-size-lg;
+      padding: $control-padding-y-lg $control-padding-x-lg;
+    }
+  }
+
+  .form-input,
+  .form-select {
+    flex: 1 1 auto;
+    width: 1%;
+  }
+
+  .input-group-btn {
+    z-index: $zindex-0;
+  }
+
+  .form-input,
+  .form-select,
+  .input-group-addon,
+  .input-group-btn {
+    &:first-child:not(:last-child) {
+      border-bottom-right-radius: 0;
+      border-top-right-radius: 0;
+    }
+    &:not(:first-child):not(:last-child) {
+      border-radius: 0;
+      margin-left: -$border-width;
+    }
+    &:last-child:not(:first-child) {
+      border-bottom-left-radius: 0;
+      border-top-left-radius: 0;
+      margin-left: -$border-width;
+    }
+    &:focus {
+      z-index: $zindex-0 + 1;
+    }
+  }
+
+  .form-select {
+    width: auto;
+  }
+
+  &.input-inline {
+    display: inline-flex;
+  }
+}
+
+// Form validation states
+.form-input,
+.form-select {
+  .has-success &,
+  &.is-success {
+    background: lighten($success-color, 53%);
+    border-color: $success-color;
+    &:focus {
+      @include control-shadow($success-color);
+    }
+  }
+
+  .has-error &,
+  &.is-error {
+    background: lighten($error-color, 53%);
+    border-color: $error-color;
+    &:focus {
+      @include control-shadow($error-color);
+    }
+  }
+}
+
+.form-checkbox,
+.form-radio,
+.form-switch {
+  .has-error &,
+  &.is-error {
+    .form-icon {
+      border-color: $error-color;
+    }
+
+    input {
+      &:checked + .form-icon {
+        background: $error-color;
+        border-color: $error-color;
+      }
+
+      &:focus + .form-icon {
+        @include control-shadow($error-color);
+        border-color: $error-color;
+      }
+    }
+  }
+}
+
+.form-checkbox {
+  .has-error &,
+  &.is-error {
+    input {
+      &:indeterminate + .form-icon {
+        background: $error-color;
+        border-color: $error-color;
+      }
+    }
+  }
+}
+
+// validation based on :placeholder-shown (Edge doesn't support it yet)
+.form-input {
+  &:not(:placeholder-shown) {
+    &:invalid {
+      border-color: $error-color;
+      &:focus {
+        @include control-shadow($error-color);
+        background: lighten($error-color, 53%);
+      }
+
+      & + .form-input-hint {
+        color: $error-color;
+      }
+    }
+  }
+}
+
+// Form disabled and readonly
+.form-input,
+.form-select {
+  &:disabled,
+  &.disabled {
+    background-color: $bg-color-dark;
+    cursor: not-allowed;
+    opacity: .5;
+  }
+}
+
+.form-input {
+  &[readonly] {
+    background-color: $bg-color;
+  }
+}
+
+input {
+  &:disabled,
+  &.disabled {
+    & + .form-icon {
+      background: $bg-color-dark;
+      cursor: not-allowed;
+      opacity: .5;
+    }
+  }
+}
+
+.form-switch {
+  input {
+    &:disabled,
+    &.disabled {
+      & + .form-icon::before {
+        background: $bg-color-light;
+      }
+    }
+  }
+}
+
+// Form horizontal
+.form-horizontal {
+  padding: $layout-spacing 0;
+
+  .form-group {
+    display: flex;
+    flex-wrap: wrap;
+  }
+}
+
+// Form inline
+.form-inline {
+  display: inline-block;
+}

+ 22 - 0
user/themes/quark/scss/spectre/_hero.scss

@@ -0,0 +1,22 @@
+// Hero
+.hero {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  padding-bottom: 4rem;
+  padding-top: 4rem;
+
+  &.hero-sm {
+    padding-bottom: 2rem;
+    padding-top: 2rem;
+  }
+
+  &.hero-lg {
+    padding-bottom: 8rem;
+    padding-top: 8rem;
+  }
+
+  .hero-body {
+    padding: $layout-spacing;
+  }
+}

+ 5 - 0
user/themes/quark/scss/spectre/_icons.scss

@@ -0,0 +1,5 @@
+// CSS Icons
+@import "icons/icons-core";
+@import "icons/icons-navigation";
+@import "icons/icons-action";
+@import "icons/icons-object";

+ 34 - 0
user/themes/quark/scss/spectre/_labels.scss

@@ -0,0 +1,34 @@
+// Labels
+.label {
+  @include label-base();
+  @include label-variant(lighten($body-font-color, 5%), $bg-color-dark);
+  display: inline-block;
+
+  // Label rounded
+  &.label-rounded {
+    border-radius: 5rem;
+    padding-left: .4rem;
+    padding-right: .4rem; 
+  }
+
+  // Label colors
+  &.label-primary {
+    @include label-variant($light-color, $primary-color);
+  }
+
+  &.label-secondary {
+    @include label-variant($primary-color, $secondary-color);
+  }
+
+  &.label-success {
+    @include label-variant($light-color, $success-color);
+  }
+
+  &.label-warning {
+    @include label-variant($light-color, $warning-color);
+  }
+
+  &.label-error {
+    @include label-variant($light-color, $error-color);
+  }
+}

+ 444 - 0
user/themes/quark/scss/spectre/_layout.scss

@@ -0,0 +1,444 @@
+// Layout
+.container {
+  margin-left: auto;
+  margin-right: auto;
+  padding-left: $layout-spacing;
+  padding-right: $layout-spacing;
+  width: 100%;
+
+  $grid-spacing: ($layout-spacing / ($layout-spacing * 0 + 1)) * $html-font-size;
+
+  &.grid-xl {
+    max-width: $grid-spacing * 2 + $size-xl;
+  }
+
+  &.grid-lg {
+    max-width: $grid-spacing * 2 + $size-lg;
+  }
+
+  &.grid-md {
+    max-width: $grid-spacing * 2 + $size-md;
+  }
+
+  &.grid-sm {
+    max-width: $grid-spacing * 2 + $size-sm;
+  }
+
+  &.grid-xs {
+    max-width: $grid-spacing * 2 + $size-xs;
+  }
+}
+
+// Responsive breakpoint system
+.show-xs,
+.show-sm,
+.show-md,
+.show-lg,
+.show-xl {
+  display: none !important;
+}
+
+// Responsive grid system
+.columns {
+  display: flex;
+  flex-wrap: wrap;
+  margin-left: -$layout-spacing;
+  margin-right: -$layout-spacing;
+
+  &.col-gapless {
+    margin-left: 0;
+    margin-right: 0;
+
+    & > .column {
+      padding-left: 0;
+      padding-right: 0;
+    }
+  }
+  &.col-oneline {
+    flex-wrap: nowrap;
+    overflow-x: auto;
+  }
+}
+.column {
+  flex: 1;
+  max-width: 100%;
+  padding-left: $layout-spacing;
+  padding-right: $layout-spacing;
+
+  &.col-12,
+  &.col-11,
+  &.col-10,
+  &.col-9,
+  &.col-8,
+  &.col-7,
+  &.col-6,
+  &.col-5,
+  &.col-4,
+  &.col-3,
+  &.col-2,
+  &.col-1,
+  &.col-auto {
+    flex: none;
+  }
+}
+.col-12 {
+  width: 100%;
+}
+.col-11 {
+  width: 91.66666667%;
+}
+.col-10 {
+  width: 83.33333333%;
+}
+.col-9 {
+  width: 75%;
+}
+.col-8 {
+  width: 66.66666667%;
+}
+.col-7 {
+  width: 58.33333333%;
+}
+.col-6 {
+  width: 50%;
+}
+.col-5 {
+  width: 41.66666667%;
+}
+.col-4 {
+  width: 33.33333333%;
+}
+.col-3 {
+  width: 25%;
+}
+.col-2 {
+  width: 16.66666667%;
+}
+.col-1 {
+  width: 8.33333333%;
+}
+.col-auto {
+  flex: 0 0 auto;
+  max-width: none;
+  width: auto;
+}
+.col-mx-auto {
+  margin-left: auto;
+  margin-right: auto;
+}
+.col-ml-auto {
+  margin-left: auto;
+}
+.col-mr-auto {
+  margin-right: auto;
+}
+@media (max-width: $size-xl) {
+  .col-xl-12,
+  .col-xl-11,
+  .col-xl-10,
+  .col-xl-9,
+  .col-xl-8,
+  .col-xl-7,
+  .col-xl-6,
+  .col-xl-5,
+  .col-xl-4,
+  .col-xl-3,
+  .col-xl-2,
+  .col-xl-1,
+  .col-xl-auto {
+    flex: none;
+  }
+  .col-xl-12 {
+    width: 100%;
+  }
+  .col-xl-11 {
+    width: 91.66666667%;
+  }
+  .col-xl-10 {
+    width: 83.33333333%;
+  }
+  .col-xl-9 {
+    width: 75%;
+  }
+  .col-xl-8 {
+    width: 66.66666667%;
+  }
+  .col-xl-7 {
+    width: 58.33333333%;
+  }
+  .col-xl-6 {
+    width: 50%;
+  }
+  .col-xl-5 {
+    width: 41.66666667%;
+  }
+  .col-xl-4 {
+    width: 33.33333333%;
+  }
+  .col-xl-3 {
+    width: 25%;
+  }
+  .col-xl-2 {
+    width: 16.66666667%;
+  }
+  .col-xl-1 {
+    width: 8.33333333%;
+  }
+  .col-xl-auto {
+    width: auto;
+  }
+  .hide-xl {
+    display: none !important;
+  }
+  .show-xl {
+    display: block !important;
+  }
+}
+@media (max-width: $size-lg) {
+  .col-lg-12,
+  .col-lg-11,
+  .col-lg-10,
+  .col-lg-9,
+  .col-lg-8,
+  .col-lg-7,
+  .col-lg-6,
+  .col-lg-5,
+  .col-lg-4,
+  .col-lg-3,
+  .col-lg-2,
+  .col-lg-1,
+  .col-lg-auto {
+    flex: none;
+  }
+  .col-lg-12 {
+    width: 100%;
+  }
+  .col-lg-11 {
+    width: 91.66666667%;
+  }
+  .col-lg-10 {
+    width: 83.33333333%;
+  }
+  .col-lg-9 {
+    width: 75%;
+  }
+  .col-lg-8 {
+    width: 66.66666667%;
+  }
+  .col-lg-7 {
+    width: 58.33333333%;
+  }
+  .col-lg-6 {
+    width: 50%;
+  }
+  .col-lg-5 {
+    width: 41.66666667%;
+  }
+  .col-lg-4 {
+    width: 33.33333333%;
+  }
+  .col-lg-3 {
+    width: 25%;
+  }
+  .col-lg-2 {
+    width: 16.66666667%;
+  }
+  .col-lg-1 {
+    width: 8.33333333%;
+  }
+  .col-lg-auto {
+    width: auto;
+  }
+  .hide-lg {
+    display: none !important;
+  }
+  .show-lg {
+    display: block !important;
+  }
+}
+@media (max-width: $size-md) {
+  .col-md-12,
+  .col-md-11,
+  .col-md-10,
+  .col-md-9,
+  .col-md-8,
+  .col-md-7,
+  .col-md-6,
+  .col-md-5,
+  .col-md-4,
+  .col-md-3,
+  .col-md-2,
+  .col-md-1,
+  .col-md-auto {
+    flex: none;
+  }
+  .col-md-12 {
+    width: 100%;
+  }
+  .col-md-11 {
+    width: 91.66666667%;
+  }
+  .col-md-10 {
+    width: 83.33333333%;
+  }
+  .col-md-9 {
+    width: 75%;
+  }
+  .col-md-8 {
+    width: 66.66666667%;
+  }
+  .col-md-7 {
+    width: 58.33333333%;
+  }
+  .col-md-6 {
+    width: 50%;
+  }
+  .col-md-5 {
+    width: 41.66666667%;
+  }
+  .col-md-4 {
+    width: 33.33333333%;
+  }
+  .col-md-3 {
+    width: 25%;
+  }
+  .col-md-2 {
+    width: 16.66666667%;
+  }
+  .col-md-1 {
+    width: 8.33333333%;
+  }
+  .col-md-auto {
+    width: auto;
+  }
+  .hide-md {
+    display: none !important;
+  }
+  .show-md {
+    display: block !important;
+  }
+}
+@media (max-width: $size-sm) {
+  .col-sm-12,
+  .col-sm-11,
+  .col-sm-10,
+  .col-sm-9,
+  .col-sm-8,
+  .col-sm-7,
+  .col-sm-6,
+  .col-sm-5,
+  .col-sm-4,
+  .col-sm-3,
+  .col-sm-2,
+  .col-sm-1,
+  .col-sm-auto {
+    flex: none;
+  }
+  .col-sm-12 {
+    width: 100%;
+  }
+  .col-sm-11 {
+    width: 91.66666667%;
+  }
+  .col-sm-10 {
+    width: 83.33333333%;
+  }
+  .col-sm-9 {
+    width: 75%;
+  }
+  .col-sm-8 {
+    width: 66.66666667%;
+  }
+  .col-sm-7 {
+    width: 58.33333333%;
+  }
+  .col-sm-6 {
+    width: 50%;
+  }
+  .col-sm-5 {
+    width: 41.66666667%;
+  }
+  .col-sm-4 {
+    width: 33.33333333%;
+  }
+  .col-sm-3 {
+    width: 25%;
+  }
+  .col-sm-2 {
+    width: 16.66666667%;
+  }
+  .col-sm-1 {
+    width: 8.33333333%;
+  }
+  .col-sm-auto {
+    width: auto;
+  }
+  .hide-sm {
+    display: none !important;
+  }
+  .show-sm {
+    display: block !important;
+  }
+}
+@media (max-width: $size-xs) {
+  .col-xs-12,
+  .col-xs-11,
+  .col-xs-10,
+  .col-xs-9,
+  .col-xs-8,
+  .col-xs-7,
+  .col-xs-6,
+  .col-xs-5,
+  .col-xs-4,
+  .col-xs-3,
+  .col-xs-2,
+  .col-xs-1,
+  .col-xs-auto {
+    flex: none;
+  }
+  .col-xs-12 {
+    width: 100%;
+  }
+  .col-xs-11 {
+    width: 91.66666667%;
+  }
+  .col-xs-10 {
+    width: 83.33333333%;
+  }
+  .col-xs-9 {
+    width: 75%;
+  }
+  .col-xs-8 {
+    width: 66.66666667%;
+  }
+  .col-xs-7 {
+    width: 58.33333333%;
+  }
+  .col-xs-6 {
+    width: 50%;
+  }
+  .col-xs-5 {
+    width: 41.66666667%;
+  }
+  .col-xs-4 {
+    width: 33.33333333%;
+  }
+  .col-xs-3 {
+    width: 25%;
+  }
+  .col-xs-2 {
+    width: 16.66666667%;
+  }
+  .col-xs-1 {
+    width: 8.33333333%;
+  }
+  .col-xs-auto {
+    width: auto;
+  }
+  .hide-xs {
+    display: none !important;
+  }
+  .show-xs {
+    display: block !important;
+  }
+}

+ 75 - 0
user/themes/quark/scss/spectre/_media.scss

@@ -0,0 +1,75 @@
+// Media
+// Image responsive
+.img-responsive {
+  display: block;
+  height: auto;
+  max-width: 100%;
+}
+
+// object-fit support is coming to Microsoft Edge
+// https://developer.microsoft.com/en-us/microsoft-edge/platform/status/objectfitandobjectposition/
+.img-fit-cover {
+  object-fit: cover;
+}
+
+.img-fit-contain {
+  object-fit: contain;
+}
+
+// Video responsive
+.video-responsive {
+  display: block;
+  overflow: hidden;
+  padding: 0;
+  position: relative;
+  width: 100%;
+  &::before {
+    content: "";
+    display: block;
+    padding-bottom: 56.25%; // Default ratio 16:9, you can calculate this value by dividing 9 by 16
+  }
+
+  iframe,
+  object,
+  embed {
+    border: 0;
+    bottom: 0;
+    height: 100%;
+    left: 0;
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 100%;
+  }
+}
+
+video.video-responsive {
+  height: auto;
+  max-width: 100%;
+
+  &::before {
+    content: none;
+  }
+}
+
+.video-responsive-4-3 {
+  &::before {
+    padding-bottom: 75%; // Ratio 4:3
+  }
+}
+
+.video-responsive-1-1 {
+  &::before {
+    padding-bottom: 100%; // Ratio 1:1
+  }
+}
+
+// Figure
+.figure {
+  margin: 0 0 $layout-spacing 0;
+
+  .figure-caption {
+    color: $gray-color-dark;
+    margin-top: $layout-spacing;
+  }
+}

+ 66 - 0
user/themes/quark/scss/spectre/_menus.scss

@@ -0,0 +1,66 @@
+// Menus
+.menu {
+  @include shadow-variant(.05rem);
+  background: $bg-color-light;
+  border-radius: $border-radius;
+  list-style: none;
+  margin: 0;
+  min-width: $control-width-xs;
+  padding: $unit-2;
+  transform: translateY($layout-spacing-sm);
+  z-index: $zindex-3;
+
+  &.menu-nav {
+    background: transparent;
+    box-shadow: none;
+  }
+
+  .menu-item {
+    margin-top: 0;
+    padding: 0 $unit-2;
+    position: relative;
+    text-decoration: none;
+
+    & > a {
+      border-radius: $border-radius;
+      color: inherit;
+      display: block;
+      margin: 0 (-$unit-2);
+      padding: $unit-1 $unit-2;
+      text-decoration: none;
+      &:focus,
+      &:hover {
+        background: $secondary-color;
+        color: $primary-color;
+      }
+      &:active,
+      &.active {
+        background: $secondary-color;
+        color: $primary-color;
+      }
+    }
+
+    .form-checkbox,
+    .form-radio,
+    .form-switch {
+      margin: $unit-h 0;
+    }
+
+    & + .menu-item {
+      margin-top: $unit-1;
+    }
+  }
+
+  .menu-badge {
+    align-items: center;
+    display: flex;
+    height: 100%;
+    position: absolute;
+    right: 0;
+    top: 0;
+
+    .label {
+      margin-right: $unit-2;
+    }
+  }
+}

+ 57 - 0
user/themes/quark/scss/spectre/_meters.scss

@@ -0,0 +1,57 @@
+// Meters
+// Credit: https://css-tricks.com/html5-meter-element/
+.meter {
+  appearance: none;
+  background: $bg-color;
+  border: 0;
+  border-radius: $border-radius;
+  display: block;
+  width: 100%;
+  height: $unit-4;
+
+  &::-webkit-meter-inner-element {
+    display: block;
+  }
+
+  &::-webkit-meter-bar,
+  &::-webkit-meter-optimum-value,
+  &::-webkit-meter-suboptimum-value,
+  &::-webkit-meter-even-less-good-value {
+    border-radius: $border-radius;
+  }
+
+  &::-webkit-meter-bar {
+    background: $bg-color;
+  }
+
+  &::-webkit-meter-optimum-value {
+    background: $success-color;
+  }
+
+  &::-webkit-meter-suboptimum-value {
+    background: $warning-color;
+  }
+
+  &::-webkit-meter-even-less-good-value {
+    background: $error-color;
+  }
+
+  &::-moz-meter-bar,
+  &:-moz-meter-optimum,
+  &:-moz-meter-sub-optimum,
+  &:-moz-meter-sub-sub-optimum {
+    border-radius: $border-radius;
+  }
+
+  &:-moz-meter-optimum::-moz-meter-bar {
+    background: $success-color;
+  }
+
+  &:-moz-meter-sub-optimum::-moz-meter-bar {
+    background: $warning-color;
+  }
+
+  &:-moz-meter-sub-sub-optimum::-moz-meter-bar {
+    background: $error-color;
+  }
+}

+ 10 - 0
user/themes/quark/scss/spectre/_mixins.scss

@@ -0,0 +1,10 @@
+// Mixins
+@import "mixins/avatar";
+@import "mixins/button";
+@import "mixins/clearfix";
+@import "mixins/color";
+@import "mixins/label";
+@import "mixins/position";
+@import "mixins/shadow";
+@import "mixins/text";
+@import "mixins/toast";

+ 87 - 0
user/themes/quark/scss/spectre/_modals.scss

@@ -0,0 +1,87 @@
+// Modals
+.modal {
+  align-items: center;
+  bottom: 0;
+  display: none;
+  justify-content: center;
+  left: 0;
+  opacity: 0;
+  overflow: hidden;
+  padding: $layout-spacing;
+  position: fixed;
+  right: 0;
+  top: 0;
+
+  &:target,
+  &.active {
+    display: flex;
+    opacity: 1;
+    z-index: $zindex-4;
+
+    .modal-overlay {
+      background: rgba($bg-color, .75);
+      bottom: 0;
+      cursor: default;
+      display: block;
+      left: 0;
+      position: absolute;
+      right: 0;
+      top: 0;
+    }
+
+    .modal-container {
+      animation: slide-down .2s ease 1;
+      z-index: $zindex-0;
+    }
+  }
+
+  &.modal-sm {
+    .modal-container {
+      max-width: $control-width-sm;
+      padding: 0 $unit-2;
+    }
+  }
+
+  &.modal-lg {
+    .modal-overlay {
+      background: $bg-color-light;
+    }
+
+    .modal-container {
+      box-shadow: none;
+      max-width: $control-width-lg;
+    }
+  }
+}
+
+.modal-container {
+  @include shadow-variant(.2rem);
+  background: $bg-color-light;
+  border-radius: $border-radius;
+  display: flex;
+  flex-direction: column;
+  max-height: 75vh;
+  max-width: $control-width-md;
+  padding: 0 $unit-4;
+  width: 100%;
+
+  &.modal-fullheight {
+    max-height: 100vh;
+  }
+
+  .modal-header {
+    color: $dark-color;
+    padding: $unit-4;
+  }
+
+  .modal-body {
+    overflow-y: auto;
+    padding: $unit-4;
+    position: relative;
+  }
+
+  .modal-footer {
+    padding: $unit-4;
+    text-align: right;
+  }
+}

+ 28 - 0
user/themes/quark/scss/spectre/_navbar.scss

@@ -0,0 +1,28 @@
+// Navbar
+.navbar {
+  align-items: stretch;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+
+  .navbar-section {
+    align-items: center;
+    display: flex;
+    flex: 1 0 0;
+
+    &:not(:first-child):last-child {
+      justify-content: flex-end;
+    }
+  }
+
+  .navbar-center {
+    align-items: center;
+    display: flex;
+    flex: 0 0 auto;
+  }
+
+  .navbar-brand {
+    font-size: $font-size-lg;
+    text-decoration: none;
+  }
+}

+ 34 - 0
user/themes/quark/scss/spectre/_navs.scss

@@ -0,0 +1,34 @@
+// Navs
+.nav {
+  display: flex;
+  flex-direction: column;
+  list-style: none;
+  margin: $unit-1 0;
+
+  .nav-item {
+    a {
+      color: $gray-color-dark;
+      padding: $unit-1 $unit-2;
+      text-decoration: none;
+      &:focus,
+      &:hover {
+        color: $primary-color;
+      }
+    }
+    &.active {
+      & > a {
+        color: darken($gray-color-dark, 10%);
+        font-weight: bold;
+        &:focus,
+        &:hover {
+          color: $primary-color;
+        }
+      }
+    }
+  }
+
+  & .nav {
+    margin-bottom: $unit-2;
+    margin-left: $unit-4;
+  }
+}

+ 446 - 0
user/themes/quark/scss/spectre/_normalize.scss

@@ -0,0 +1,446 @@
+/* Manually forked from Normalize.css */
+/* normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
+
+/**
+ * 1. Change the default font family in all browsers (opinionated).
+ * 2. Correct the line height in all browsers.
+ * 3. Prevent adjustments of font size after orientation changes in
+ *    IE on Windows Phone and in iOS.
+ */
+
+/* Document
+   ========================================================================== */
+
+html {
+  font-family: sans-serif; /* 1 */
+  -ms-text-size-adjust: 100%; /* 3 */
+  -webkit-text-size-adjust: 100%; /* 3 */
+}
+
+/* Sections
+   ========================================================================== */
+
+/**
+ * Remove the margin in all browsers (opinionated).
+ */
+
+body {
+  margin: 0;
+}
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+article,
+aside,
+footer,
+header,
+nav,
+section {
+  display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+/* Grouping content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in IE.
+ */
+
+figcaption,
+figure,
+main { /* 1 */
+  display: block;
+}
+
+/**
+ * Add the correct margin in IE 8 (removed).
+ */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+  box-sizing: content-box; /* 1 */
+  height: 0; /* 1 */
+  overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers. (removed)
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+/* Text-level semantics
+   ========================================================================== */
+
+/**
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
+ */
+
+a {
+  background-color: transparent; /* 1 */
+  -webkit-text-decoration-skip: objects; /* 2 */
+}
+
+/**
+ * Remove the outline on focused links when they are also active or hovered
+ * in all browsers (opinionated).
+ */
+
+a:active,
+a:hover {
+  outline-width: 0;
+}
+
+/**
+ * Modify default styling of address.
+ */
+
+address {
+  font-style: normal;
+}
+
+/**
+ * 1. Remove the bottom border in Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. (removed)
+ */
+
+/**
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
+ */
+
+b,
+strong {
+  font-weight: inherit;
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+pre,
+samp {
+  font-family: $mono-font-family; /* 1 (changed) */
+  font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font style in Android 4.3-.
+ */
+
+dfn {
+  font-style: italic;
+}
+
+/**
+ * Add the correct background and color in IE 9-. (Removed)
+ */
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+  font-size: 80%;
+  font-weight: 400; /* (added) */
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/* Embedded content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+audio,
+video {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in iOS 4-7.
+ */
+
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+
+/**
+ * Remove the border on images inside links in IE 10-.
+ */
+
+img {
+  border-style: none;
+}
+
+/**
+ * Hide the overflow in IE.
+ */
+
+svg:not(:root) {
+  overflow: hidden;
+}
+
+/* Forms
+   ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit; /* 1 (changed) */
+  font-size: inherit; /* 1 (changed) */
+  line-height: inherit; /* 1 (changed) */
+  margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+  overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+  text-transform: none;
+}
+
+/**
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ *    controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+html [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button; /* 2 */
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule (removed).
+ */
+
+
+/**
+ * Change the border, margin, and padding in all browsers (opinionated) (changed).
+ */
+
+fieldset {
+  border: 0;
+  margin: 0;
+  padding: 0;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ *    `fieldset` elements in all browsers.
+ */
+
+legend {
+  box-sizing: border-box; /* 1 */
+  color: inherit; /* 2 */
+  display: table; /* 1 */
+  max-width: 100%; /* 1 */
+  padding: 0; /* 3 */
+  white-space: normal; /* 1 */
+}
+
+/**
+ * 1. Add the correct display in IE 9-.
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+  display: inline-block; /* 1 */
+  vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Remove the default vertical scrollbar in IE.
+ */
+
+textarea {
+  overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  box-sizing: border-box; /* 1 */
+  padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+  -webkit-appearance: textfield; /* 1 */
+  outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button; /* 1 */
+  font: inherit; /* 2 */
+}
+
+/* Interactive
+   ========================================================================== */
+
+/*
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in Edge, IE, and Firefox.
+ */
+
+details, /* 1 */
+menu {
+  display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+  display: list-item;
+  outline: none;
+}
+
+/* Scripting
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+canvas {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in IE.
+ */
+
+template {
+  display: none;
+}
+
+/* Hidden
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 10-.
+ */
+
+[hidden] {
+  display: none;
+}

+ 95 - 0
user/themes/quark/scss/spectre/_off-canvas.scss

@@ -0,0 +1,95 @@
+// Off canvas menus
+$off-canvas-breakpoint: $size-lg !default;
+
+.off-canvas {
+  display: flex;
+  flex-flow: nowrap;
+  height: 100%;
+  position: relative;
+  width: 100%;
+
+  .off-canvas-toggle {
+    display: block;
+    position: absolute;
+    top: $layout-spacing;
+    transition: none;
+    z-index: $zindex-0;
+    @if $rtl == true {
+      right: $layout-spacing;
+    } @else {
+      left: $layout-spacing;
+    }
+  }
+
+  .off-canvas-sidebar {
+    background: $bg-color;
+    bottom: 0;
+    min-width: 10rem;
+    overflow-y: auto;
+    position: fixed;
+    top: 0;
+    transition: transform .25s;
+    z-index: $zindex-2;
+    @if $rtl == true {
+      right: 0;
+      transform: translateX(100%);
+    } @else {
+      left: 0;
+      transform: translateX(-100%);
+    }
+  }
+
+  .off-canvas-content {
+    flex: 1 1 auto;
+    height: 100%;
+    padding: $layout-spacing $layout-spacing $layout-spacing 4rem;
+  }
+
+  .off-canvas-overlay {
+    background: rgba($dark-color, .1);
+    border-color: transparent;
+    border-radius: 0;
+    bottom: 0;
+    display: none;
+    height: 100%;
+    left: 0;
+    position: fixed;
+    right: 0;
+    top: 0;
+    width: 100%;
+  }
+
+  .off-canvas-sidebar {
+    &:target,
+    &.active {
+      transform: translateX(0);
+    }
+
+    &:target ~ .off-canvas-overlay,
+    &.active ~ .off-canvas-overlay {
+      display: block;
+      z-index: $zindex-1;
+    }
+  }
+}
+
+// Responsive layout
+@media (min-width: $off-canvas-breakpoint) {
+  .off-canvas {
+    &.off-canvas-sidebar-show {
+      .off-canvas-toggle {
+        display: none;
+      }
+  
+      .off-canvas-sidebar {
+        flex: 0 0 auto;
+        position: relative;
+        transform: none;
+      }
+
+      .off-canvas-overlay {
+        display: none !important;
+      }
+    }
+  }
+}

+ 60 - 0
user/themes/quark/scss/spectre/_pagination.scss

@@ -0,0 +1,60 @@
+// Pagination
+.pagination {
+  display: flex;
+  list-style: none;
+  margin: $unit-1 0;
+  padding: $unit-1 0;
+
+  .page-item {
+    margin: $unit-1 $unit-o;
+
+    span {
+      display: inline-block;
+      padding: $unit-1 $unit-1;
+    }
+
+    a {
+      border-radius: $border-radius;
+      display: inline-block;
+      padding: $unit-1 $unit-2;
+      text-decoration: none;
+      &:focus,
+      &:hover {
+        color: $primary-color;
+      }
+    }
+
+    &.disabled {
+      a {
+        cursor: default;
+        opacity: .5;
+        pointer-events: none;
+      }
+    }
+
+    &.active {
+      a {
+        background: $primary-color;
+        color: $light-color;
+      }
+    }
+
+    &.page-prev,
+    &.page-next {
+      flex: 1 0 50%;
+    }
+
+    &.page-next {
+      text-align: right;
+    }
+
+    .page-item-title {
+      margin: 0;
+    }
+
+    .page-item-subtitle {
+      margin: 0;
+      opacity: .5;
+    }
+  }
+}

+ 0 - 0
user/themes/quark/scss/spectre/_panels.scss


Some files were not shown because too many files changed in this diff