From 88a40efb4eb7bb67f9fcc42431e7a485f609c41e Mon Sep 17 00:00:00 2001 From: Herwin Bozet Date: Mon, 4 Nov 2024 22:52:24 +0100 Subject: [PATCH] Initial commit Update .gitignore, LICENSE-CC0, and 70 more files... --- .gitignore | 9 + LICENSE-CC0 | 121 +++++++++ apache2.conf | 227 ++++++++++++++++ compile.cmd | 41 +++ docker-compose.dev.yml | 17 ++ dockerize.cmd | 21 ++ htdocs/.htaccess | 71 +++++ htdocs/css/3px-tile-0.1.png | Bin 0 -> 2408 bytes htdocs/css/3px-tile-0.2.png | Bin 0 -> 2408 bytes htdocs/css/3px-tile-0.4.png | Bin 0 -> 2408 bytes htdocs/css/bright-squares-p100-0.125.png | Bin 0 -> 28603 bytes htdocs/favicon.ico | Bin 0 -> 25015 bytes htdocs/favicon.svg | 1 + htdocs/img/logo-large-fluent-unshaded.svg | 5 + htdocs/index.php | 129 +++++++++ htdocs/js/sidebar.js | 18 ++ htdocs/parts/grids.php | 137 ++++++++++ htdocs/parts/horizontal_rulers.php | 40 +++ htdocs/parts/intro.php | 116 ++++++++ htdocs/parts/lists.php | 25 ++ htdocs/parts/rounding.php | 33 +++ htdocs/parts/sidebar.php | 99 +++++++ htdocs/parts/spacing.php | 92 +++++++ htdocs/parts/text_alignment.php | 54 ++++ htdocs/parts/text_links.php | 67 +++++ htdocs/parts/text_misc.php | 43 +++ htdocs/parts/text_modifiers.php | 42 +++ htdocs/parts/text_styles.php | 54 ++++ htdocs/parts/text_weights.php | 64 +++++ minify.cmd | 37 +++ readme.md | 12 + scss/config.scss | 8 + scss/core/border.scss | 64 +++++ scss/core/containers.scss | 19 ++ scss/core/display.scss | 18 ++ scss/core/flex.scss | 77 ++++++ scss/core/float.scss | 17 ++ scss/core/grid.scss | 45 ++++ scss/core/lists.scss | 29 ++ scss/core/overflow.scss | 20 ++ scss/core/position.scss | 7 + scss/core/rounding/corner.scss | 29 ++ scss/core/rounding/global.scss | 22 ++ scss/core/rounding/sided.scss | 33 +++ scss/core/sizing.scss | 56 ++++ scss/core/spacing/axis.scss | 39 +++ scss/core/spacing/global.scss | 46 ++++ scss/core/spacing/sided.scss | 43 +++ scss/core/text.scss | 168 ++++++++++++ scss/debugger.scss | 17 ++ scss/external/reset.scss | 60 +++++ scss/nibblepoker.scss | 75 ++++++ scss/site/backgrounds.scss | 31 +++ scss/site/base.scss | 41 +++ scss/site/borders.scss | 36 +++ scss/site/code.scss | 38 +++ scss/site/content.scss | 37 +++ scss/site/hr.scss | 54 ++++ scss/site/image.scss | 127 +++++++++ scss/site/input.scss | 140 ++++++++++ scss/site/layouts/commons.scss | 15 ++ scss/site/layouts/generic.scss | 161 +++++++++++ scss/site/mobile.scss | 19 ++ scss/site/modal.scss | 34 +++ scss/site/scrollbar.scss | 62 +++++ scss/site/splide.scss | 16 ++ scss/site/table.scss | 56 ++++ scss/site/text.scss | 122 +++++++++ scss/site/video.scss | 9 + scss/site/wedge.scss | 78 ++++++ scss/variables.scss | 315 ++++++++++++++++++++++ setup.cmd | 45 ++++ 72 files changed, 3903 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE-CC0 create mode 100644 apache2.conf create mode 100644 compile.cmd create mode 100644 docker-compose.dev.yml create mode 100644 dockerize.cmd create mode 100644 htdocs/.htaccess create mode 100644 htdocs/css/3px-tile-0.1.png create mode 100644 htdocs/css/3px-tile-0.2.png create mode 100644 htdocs/css/3px-tile-0.4.png create mode 100644 htdocs/css/bright-squares-p100-0.125.png create mode 100644 htdocs/favicon.ico create mode 100644 htdocs/favicon.svg create mode 100644 htdocs/img/logo-large-fluent-unshaded.svg create mode 100644 htdocs/index.php create mode 100644 htdocs/js/sidebar.js create mode 100644 htdocs/parts/grids.php create mode 100644 htdocs/parts/horizontal_rulers.php create mode 100644 htdocs/parts/intro.php create mode 100644 htdocs/parts/lists.php create mode 100644 htdocs/parts/rounding.php create mode 100644 htdocs/parts/sidebar.php create mode 100644 htdocs/parts/spacing.php create mode 100644 htdocs/parts/text_alignment.php create mode 100644 htdocs/parts/text_links.php create mode 100644 htdocs/parts/text_misc.php create mode 100644 htdocs/parts/text_modifiers.php create mode 100644 htdocs/parts/text_styles.php create mode 100644 htdocs/parts/text_weights.php create mode 100644 minify.cmd create mode 100644 readme.md create mode 100644 scss/config.scss create mode 100644 scss/core/border.scss create mode 100644 scss/core/containers.scss create mode 100644 scss/core/display.scss create mode 100644 scss/core/flex.scss create mode 100644 scss/core/float.scss create mode 100644 scss/core/grid.scss create mode 100644 scss/core/lists.scss create mode 100644 scss/core/overflow.scss create mode 100644 scss/core/position.scss create mode 100644 scss/core/rounding/corner.scss create mode 100644 scss/core/rounding/global.scss create mode 100644 scss/core/rounding/sided.scss create mode 100644 scss/core/sizing.scss create mode 100644 scss/core/spacing/axis.scss create mode 100644 scss/core/spacing/global.scss create mode 100644 scss/core/spacing/sided.scss create mode 100644 scss/core/text.scss create mode 100644 scss/debugger.scss create mode 100644 scss/external/reset.scss create mode 100644 scss/nibblepoker.scss create mode 100644 scss/site/backgrounds.scss create mode 100644 scss/site/base.scss create mode 100644 scss/site/borders.scss create mode 100644 scss/site/code.scss create mode 100644 scss/site/content.scss create mode 100644 scss/site/hr.scss create mode 100644 scss/site/image.scss create mode 100644 scss/site/input.scss create mode 100644 scss/site/layouts/commons.scss create mode 100644 scss/site/layouts/generic.scss create mode 100644 scss/site/mobile.scss create mode 100644 scss/site/modal.scss create mode 100644 scss/site/scrollbar.scss create mode 100644 scss/site/splide.scss create mode 100644 scss/site/table.scss create mode 100644 scss/site/text.scss create mode 100644 scss/site/video.scss create mode 100644 scss/site/wedge.scss create mode 100644 scss/variables.scss create mode 100644 setup.cmd diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9b1c97 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# IDEs +.idea/ + +# NodeJS Trash +node_modules/ + +# Build Artifacts +*.css +*.min.html diff --git a/LICENSE-CC0 b/LICENSE-CC0 new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSE-CC0 @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/apache2.conf b/apache2.conf new file mode 100644 index 0000000..ae4b2c3 --- /dev/null +++ b/apache2.conf @@ -0,0 +1,227 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.4/ for detailed information about +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific +# hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf-enabled +# | `-- *.conf +# `-- sites-enabled +# `-- *.conf +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections which can be +# customized anytime. +# +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ +# directories contain particular configuration snippets which manage modules, +# global configuration fragments, or virtual host configurations, +# respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See +# their respective man pages for detailed information. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the Mutex documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +#Mutex file:${APACHE_LOCK_DIR} default + +# +# The directory where shm and other runtime files will be stored. +# + +DefaultRuntimeDir ${APACHE_RUN_DIR} + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the severity of messages logged to the error_log. +# Available values: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the log level for particular modules, e.g. +# "LogLevel info ssl:warn" +# +LogLevel warn + +# Include module configuration: +IncludeOptional mods-enabled/*.load +IncludeOptional mods-enabled/*.conf + +# Include list of ports to listen on +Include ports.conf + + +# Sets the default security model of the Apache2 HTTPD server. It does +# not allow access to the root filesystem outside of /usr/share and /var/www. +# The former is used by web applications packaged in Debian, +# the latter may be used for local directories served by the web server. If +# your system is serving content from a sub-directory in /srv you must allow +# access here, or in any related virtual host. + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + +# +# Options Indexes FollowSymLinks +# AllowOverride None +# Require all granted +# + + + + +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive. +# +# These deviate from the Common Log Format definitions in that they use %O +# (the actual bytes sent including headers) instead of %b (the size of the +# requested file), because the latter makes it impossible to detect partial +# requests. +# +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. +# Use mod_remoteip instead. +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +IncludeOptional conf-enabled/*.conf + +# Include the virtual host configurations: +IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/compile.cmd b/compile.cmd new file mode 100644 index 0000000..aaea608 --- /dev/null +++ b/compile.cmd @@ -0,0 +1,41 @@ +@echo off +setlocal enabledelayedexpansion + +:: Going into the script's directory +cd /D "%~dp0" + + +:sass +echo. +echo Handling the SASS files +echo ----------------------- + +:sass-clean +echo Cleaning old files... +pushd %CD% +cd /d %~dp0\htdocs\ +rmdir /Q /S ".\css" +mkdir css +popd + +:sass-compile +echo Compiling SASS files... +pushd %CD% +cd /d %~dp0\htdocs\css\ +call sass "../../scss/nibblepoker.scss" -q --no-source-map > "nibblepoker.css" +call sass "../../scss/nibblepoker.scss" -q --no-source-map --style compressed > "nibblepoker.min.css" +call sass "../../scss/debugger.scss" -q --no-source-map > "debugger.css" +call sass "../../scss/debugger.scss" -q --no-source-map --style compressed > "debugger.min.css" +popd + +:sass-assets +echo Copying assets... +pushd %CD% +cd /d %~dp0 +copy ".\bkgds\*.png" ".\htdocs\css\" +popd + +:sass-end + + +:end diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..8ecdd24 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,17 @@ +services: + nibblepoker_css: + container_name: nibblepoker-css-dev + image: php:apache + ports: + - 32133:80 + - 32134:443 + environment: + - TZ=Europe/Brussels + volumes: + - ./htdocs:/var/www/html:ro + - ./apache2.conf:/etc/apache2/apache2.conf:ro + restart: unless-stopped + stop_grace_period: 5s + labels: + - "com.centurylinklabs.watchtower.enable=true" + command: ["/bin/sh", "-c", "a2enmod headers && a2enmod rewrite && a2enmod ratelimit && apache2-foreground"] diff --git a/dockerize.cmd b/dockerize.cmd new file mode 100644 index 0000000..a9ed925 --- /dev/null +++ b/dockerize.cmd @@ -0,0 +1,21 @@ +@echo off +setlocal enabledelayedexpansion + +:: Going into the script's directory +cd /D "%~dp0" + + +:dockerize +echo. +echo Preparing the container +echo ----------------------- + +:dockerize-up +pushd %CD% +docker-compose -f docker-compose.dev.yml up -d --force-recreate +popd + +:dockerize-end + + +:end diff --git a/htdocs/.htaccess b/htdocs/.htaccess new file mode 100644 index 0000000..f63278c --- /dev/null +++ b/htdocs/.htaccess @@ -0,0 +1,71 @@ +# Preventing access to .htaccess + + Require all denied + + + +# Fixing some encoding issues on non-HTML files. +# Mostly affects the old privacy policies written in french. (Accents have issues in non-utf8 encodings !) +AddCharset utf-8 .css .txt .js .md .ts .mjs +# +# Header set Content-Type "text/plain; charset=utf-8" +# +#AddDefaultCharset utf-8 + + +# Adding MIME types +AddType text/typescript .ts +AddType text/javascript .js +AddType text/javascript .mjs +AddType application/wasm .wasm +AddType video/x-matroska .mkv +AddType image/apng .apng + + +# Correcting some default options for security and language/content redirection. +# FollowSymlinks is also on since it's required for "mod_rewrite" and the server is jailed/containerized. +Options -Indexes +FollowSymlinks -ExecCGI + + +# Setting up GZIP. +# It's optional since reverse-proxies or caching layers will usually do it for us. + + mod_gzip_on Yes + mod_gzip_dechunk Yes + mod_gzip_item_include file \.(html?|txt|css|js|mjs|php|pl)$ + mod_gzip_item_include handler ^cgi-script$ + mod_gzip_item_include mime ^text/.* + mod_gzip_item_include mime ^application/x-javascript.* + mod_gzip_item_exclude mime ^image/.* + mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* + + + +# Setting some headers for security. +# Will cause "fail-safe crashes" if the "headers" module isn't enabled. +Header always set X-Frame-Options "deny" +#Header always set Content-Security-Policy "default-src 'self' archives.nibblepoker.lu archives.nibblepoker.com nibblepoker.com nibblepoker.lu; style-src 'self' nibblepoker.lu;img-src 'self' archives.nibblepoker.lu archives.nibblepoker.com nibblepoker.com nibblepoker.lu data:; object-src 'none'; child-src 'self'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content" +Header always set X-XSS-Protection " 1; mode=block" +Header always set Referrer-Policy "no-referrer" +Header always set X-Content-Type-Options "nosniff" +Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" +#Header always set Cache-Control "max-age=300, public" +Header always set Access-Control-Allow-Origin "*" +Header always set Permissions-Policy "browsing-topics=(), interest-cohort=()" + +# Removing some headers since they often raise BS alarms about too much back-end info being sent to clients. +# Note: These headers can actually be removed by most reverse-proxies. +Header unset X-Powered-By + + +# Handling all other redirections. +# Will cause "fail-safe crashes" if the "rewrite" module isn't enabled. +RewriteEngine On + +# Serving normal pages when a specific language key is at the beginning of the requested path. +# We use a regex to match all supported languages and use the 3rd ground, `(.*)` as `$3`, as the "real" path. +RewriteRule ^((en|fr)/)(.*)$ /$3 [QSA] + +# Handling requests for "robots.txt" and "sitemap.txt" via PHP. +RewriteRule ^(en/|fr/)?robots.txt$ robots.php [L] +RewriteRule ^(en/|fr/)?sitemap.txt$ sitemap.php [L] diff --git a/htdocs/css/3px-tile-0.1.png b/htdocs/css/3px-tile-0.1.png new file mode 100644 index 0000000000000000000000000000000000000000..d00539d282942c19fc94447fcde15d7416bb2489 GIT binary patch literal 2408 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 a%jMrs-Q%57X82(M00001$nKm|yT$_g+^v!1 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 a%jMrs-Q%57X82(M0000FL?o+4=u(MLE@j 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 J96f}#it2na$% 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 Pkki_Mk;ec31cd(sB25s5 literal 0 HcmV?d00001 diff --git a/htdocs/favicon.svg b/htdocs/favicon.svg new file mode 100644 index 0000000..acc8f6a --- /dev/null +++ b/htdocs/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/htdocs/img/logo-large-fluent-unshaded.svg b/htdocs/img/logo-large-fluent-unshaded.svg new file mode 100644 index 0000000..e6d5276 --- /dev/null +++ b/htdocs/img/logo-large-fluent-unshaded.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/htdocs/index.php b/htdocs/index.php new file mode 100644 index 0000000..f50ba9f --- /dev/null +++ b/htdocs/index.php @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + NibblePoker's CSS Theme + + + + + + + + + + + + + + +
+

+ Homepage +

+
+ + +  Language +   + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/htdocs/js/sidebar.js b/htdocs/js/sidebar.js new file mode 100644 index 0000000..e52301a --- /dev/null +++ b/htdocs/js/sidebar.js @@ -0,0 +1,18 @@ +let isSidebarVisible = true; + +document.addEventListener("DOMContentLoaded", () => { + const eSidebar = document.getElementById("sidebar"); + const eMain = document.getElementById("main"); + + // TODO: Emit an event to help Splide re-align after the sidebar has changed state. + document.getElementById("sidebar-toggle-footer").onclick = function() { + if(isSidebarVisible) { + eSidebar.classList.add("retracted"); + eMain.classList.add("expanded"); + } else { + eSidebar.classList.remove("retracted"); + eMain.classList.remove("expanded"); + } + isSidebarVisible = !isSidebarVisible; + }; +}); diff --git a/htdocs/parts/grids.php b/htdocs/parts/grids.php new file mode 100644 index 0000000..5f1e7a4 --- /dev/null +++ b/htdocs/parts/grids.php @@ -0,0 +1,137 @@ + + + +
+

Grids +

+
+
+

+ Grids are defined by using the grid and col-X class where + X represents the number of columns and can be + 1, 2, + 3, 4, + 6 or 8. +

+ + + + +

Examples without inter-cell gaps:

+
+

div.grid.col-1>div

+
+
Cell #1
+
+ +

div.grid.col-2>div*2

+
+
Cell #1
+
Cell #2
+
+ +

div.grid.col-6>div*6

+
+
Cell #1
+
Cell #2
+
Cell #3
+
Cell #4
+
Cell #5
+
Cell #6
+
+
+ +

+ Inter-cell gaps can also be setup by using the grid-gap-X or + col-gap-X classes and replacing the X + with the standard size suffixes. +

+ +

Examples with inter-cell gaps:

+
+ div.grid.col-3.grid-gap-' . $gapSize . '>div*6

'); + echo('
'); + for($iGap = 1; $iGap <= 6; $iGap++) { + echo('
Cell #' . $iGap . '
'); + } + echo('
'); + } + ?> +
+ + TODO: All mobile rules, Add non-identical sizing + + +
+ Click to show/hide all classes +
+

+ grid + Defined a grid container +

+ + +
+ + + + + + + + '); + echo(''); + echo(''); + echo(''); + } + ?> +
+

grid-col-1

+
+

col-1

+
+ Specifies the column count

+

grid-col-'.$gridColCount.'

col-'.$gridColCount.'

+ +
+ + + + + + + + '); + echo(''); + echo(''); + echo(''); + } + ?> +
+

grid-gap-xs

+
+

gap-xs

+
+ Specifies the inter-cell gap size

+

grid-gap-'.$gridGapSize.'

gap-'.$gridGapSize.'

+ + '); + ?> +
+
+ +
diff --git a/htdocs/parts/horizontal_rulers.php b/htdocs/parts/horizontal_rulers.php new file mode 100644 index 0000000..29cafd3 --- /dev/null +++ b/htdocs/parts/horizontal_rulers.php @@ -0,0 +1,40 @@ + + + +
+

Horizontal Rulers +

+
+
+

Generic: hr

+
+ +

Subtle: hr.subtle, hr.hr-subtle

+
+ +

Dashed: hr.dashed, hr.hr-dashed

+
+ +

Dotted: hr.dotted, hr.hr-dotted

+
+ +

Double: + hr.double, hr.hr-double, + hr.thick, hr.hr-thick +

+
+ +

Outset: hr.outset, hr.hr-outset

+
+
+ +

Cutting indicator: hr.cut-here, hr.hr-cut-here

+
+
+ +
diff --git a/htdocs/parts/intro.php b/htdocs/parts/intro.php new file mode 100644 index 0000000..2325247 --- /dev/null +++ b/htdocs/parts/intro.php @@ -0,0 +1,116 @@ + + +
+

Welcome to NibblePoker.com

+
+
+

About the stylesheet

+

+ NibbleCSS was originally conceived for internal use following a bout of performance issues with + off-the-shelf stylesheets on low-end and mobile devices.
+ However, it rapidly got used outside its intended environment and was spun-off into a separate a + publicly accessible and truly free project. +

+

+ NibbleCSS is also released into the public domain as I do not believe forcing people to include licenses + or disclaimers is truly free, especially when said licenses propagate themselves like tumorous growths.
+ Following that philosophy, NibbleCSS also makes use of + Eric A. Meyer's Reset.css + which was also released into the public domain in 2011. +

+ +

Design philosophy

+
+

Core Stylesheet

+

These rules apply to the "core" part of the stylesheet:

+
    +
  • No implicit sizes, margins or paddings
  • +
  • No styles from class-less DOM, except for styling elements
  • +
  • Self-sufficient and embeddable as a single file or text blob
  • +
  • Competitive minified size
  • +
  • Standardized naming scheme
  • +
+ +

Site Stylesheet

+
    +
  • Prefabs for common elements
  • +
      +
    • Bound to specific elements
    • +
    • ???
    • +
    • ???
    • +
    • No forced smooth transition
    • +
    • MUST be snappy on low-end hardware, no snagging allowed
    • +
    +
+
+ +

Downloads

+ + + + + + + + + + + + + + + + + + +
StylesheetMinified CSSRegular CSS
NibbleCSS + + + + + + + +
Debugger + + + + + + + +
+
diff --git a/htdocs/parts/lists.php b/htdocs/parts/lists.php new file mode 100644 index 0000000..c05a3fb --- /dev/null +++ b/htdocs/parts/lists.php @@ -0,0 +1,25 @@ + + + +
+

Lists +

+
+
+

???.

+ +
+
    +
  • Line 1
  • +
  • Line 2
    Line 2 continued
  • +
  • Line 3
  • +
+
+ + TODO: All a detail of all classes +
diff --git a/htdocs/parts/rounding.php b/htdocs/parts/rounding.php new file mode 100644 index 0000000..2d58b29 --- /dev/null +++ b/htdocs/parts/rounding.php @@ -0,0 +1,33 @@ + + + +
+

Rounding +

+
+
+

Rounding can be done on a corner/side/global basis using the standard size suffixes and some special ones.

+

These examples will have ???.

+ +

Sizes:

+
+
r-0
+
r-xs
+
r-s
+
r-m
+
r-l
+
r-xl
+
+ +

Special classes:

+
+
r-r
+
+ + TODO: All a detail of all classes +
diff --git a/htdocs/parts/sidebar.php b/htdocs/parts/sidebar.php new file mode 100644 index 0000000..5ef15fa --- /dev/null +++ b/htdocs/parts/sidebar.php @@ -0,0 +1,99 @@ + + + diff --git a/htdocs/parts/spacing.php b/htdocs/parts/spacing.php new file mode 100644 index 0000000..e089a90 --- /dev/null +++ b/htdocs/parts/spacing.php @@ -0,0 +1,92 @@ + + + +
+

Spacing +

+
+
+

+ Paddings and margins can be applied on a side/axis/global basis using the standard size suffixes.
+ Additionally, the xxs size is also available for those rare tiny spacing needs. +

+ +

+ The examples below have a bordered & padded container, and a regular bordered sub-container.
+ Using margins would have the same effect, if you ignore margin folding. +

+ +
+

p-xxs

+

p-xs

+

p-s

+

p-m

+

p-l

+

p-xl

+
+ +
+ Click to show/hide all classes +
+ '); + foreach($spacingSizes as &$spacingSize){echo('p-'.$spacingSize.'');} + echo('General padding

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('m-'.$spacingSize.'');} + echo('General margin

'); + + echo('
'); + + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('px-'.$spacingSize.'');} + echo('Horizontal padding

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('py-'.$spacingSize.'');} + echo('Vertical padding

'); + + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('mx-'.$spacingSize.'');} + echo('Horizontal margin

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('my-'.$spacingSize.'');} + echo('Vertical margin

'); + + echo('
'); + + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('pt-'.$spacingSize.'');} + echo('Top padding

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('pb-'.$spacingSize.'');} + echo('Bottom padding

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('pl-'.$spacingSize.'');} + echo('Left padding

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('pr-'.$spacingSize.'');} + echo('Right padding

'); + + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('mt-'.$spacingSize.'');} + echo('Top margin

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('mb-'.$spacingSize.'');} + echo('Bottom margin

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('ml-'.$spacingSize.'');} + echo('Left margin

'); + echo('

'); + foreach($spacingSizes as &$spacingSize){echo('mr-'.$spacingSize.'');} + echo('Right margin

'); + ?> +
+
+
diff --git a/htdocs/parts/text_alignment.php b/htdocs/parts/text_alignment.php new file mode 100644 index 0000000..74c527b --- /dev/null +++ b/htdocs/parts/text_alignment.php @@ -0,0 +1,54 @@ + + + +
+

TextAlignment +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StyleExampleClasses

Left

Left

t-left

Center

Centered

t-center

Right

Right

t-right

Start

Start

t-start

End

End

t-end

Justify

Lorem ipsum.
Donor si amet elit.

t-justify
+ +
diff --git a/htdocs/parts/text_links.php b/htdocs/parts/text_links.php new file mode 100644 index 0000000..0507f58 --- /dev/null +++ b/htdocs/parts/text_links.php @@ -0,0 +1,67 @@ + + + +
+

TextLinks +

+
+
+

Regular anchors

+ + + + + + + + + + + + + + + +
ExampleSource
Real anchora

Fake anchor

*.a
+ +

Bland anchors

+ + + + + + + + + + + + + + + +
ExampleSource
Bland anchora.a-bland

Bland 'anchor'

*.a.a-bland
+ +

Hidden anchors

+ + + + + + + + + + + + + + + +
ExampleSource
Hidden anchora.a-hidden

Hidden 'anchor'

*.a.a-hidden
+
diff --git a/htdocs/parts/text_misc.php b/htdocs/parts/text_misc.php new file mode 100644 index 0000000..a4a2176 --- /dev/null +++ b/htdocs/parts/text_misc.php @@ -0,0 +1,43 @@ + + + +
+

TextMiscellaneous +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StyleExampleClasses

No wrap

Cannot really be shown

t-nowrap

Half muted

Half muted

t-half-muted

Muted

Muted text

t-muted

Super muted

Super Muted

t-super-muted
+
diff --git a/htdocs/parts/text_modifiers.php b/htdocs/parts/text_modifiers.php new file mode 100644 index 0000000..5363fe1 --- /dev/null +++ b/htdocs/parts/text_modifiers.php @@ -0,0 +1,42 @@ + + + +
+

TextModifiers +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
StyleOriginalTransformedClasses

Uppercase

Regular Case

Regular Case

t-ucase

Lowercase

Regular Case

Regular Case

t-lcase

Capitalize

no case

no caset-capitalize
+
\ No newline at end of file diff --git a/htdocs/parts/text_styles.php b/htdocs/parts/text_styles.php new file mode 100644 index 0000000..2420384 --- /dev/null +++ b/htdocs/parts/text_styles.php @@ -0,0 +1,54 @@ + + + +
+

TextStyles +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StyleExampleClassesElements

Italic

Italic text

t-italici

Oblique

Oblique text

t-obliqueN/A

Underline

Underlined text

t-underlineu

Strikethrough

Struck text

t-strikethroughs

Overline

Overline text

t-overlineN/A
+
diff --git a/htdocs/parts/text_weights.php b/htdocs/parts/text_weights.php new file mode 100644 index 0000000..eab567d --- /dev/null +++ b/htdocs/parts/text_weights.php @@ -0,0 +1,64 @@ + + + +
+

TextWeights +

+
+
+

Numeric Weights

+ + + + + + + + '); + echo(''); + echo(''); + echo(''); + echo(''); + } + ?> + +
StyleExampleClasses
' . ($i * 100) . 'Lorem Ipsum donor.t-w-' . ($i * 100) . '
+ +

Aliased Weights

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StyleExampleClasses

Lighter

Lorem Ipsum 123 !

t-lightert-w-lighter

Normal

Lorem Ipsum 123 !

t-normalt-w-normal

Bold

Lorem Ipsum 123 !

t-boldt-w-bold

Bolder

Lorem Ipsum 123 !

t-boldert-w-bolder
+
diff --git a/minify.cmd b/minify.cmd new file mode 100644 index 0000000..40407c9 --- /dev/null +++ b/minify.cmd @@ -0,0 +1,37 @@ +@echo off +setlocal enabledelayedexpansion + +:: Going into the script's directory +cd /D "%~dp0" + + +:minify +echo. +echo Minifying HTML +echo -------------- + +:minify-clean +echo Cleaning old files... +pushd %CD% +cd /d %~dp0\htdocs\ +del /Q /S "*.min.html" +popd + +:minify-run +echo Minifying HTML files... +pushd %CD% +cd /d %~dp0\htdocs +call html-minifier --case-sensitive ^ + --collapse-whitespace ^ + --decode-entities ^ + --remove-attribute-quotes ^ + --remove-comments ^ + --sort-attributes ^ + -o "index.min.html" ^ + "index.html" +popd + +:minify-end + + +:end diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..c496220 --- /dev/null +++ b/readme.md @@ -0,0 +1,12 @@ +# NibblePoker's CSS Theme (W.I.P.) +A simple and minimalist CSS stylesheet used across all my websites and web-based applications. + + +## License +The code in this repository is released under [CC0 1.0 Universal (CC0 1.0) (Public Domain)](LICENSE-CC0) + +This repository includes and redistributes [reset.css](https://meyerweb.com/eric/tools/css/reset/) from +[meyerweb.com](https://meyerweb.com/) which is also in the public domain. + +**This license doesn't apply to the logos, images, names and other external resources provided +and/or used in this repository.** diff --git a/scss/config.scss b/scss/config.scss new file mode 100644 index 0000000..6d09364 --- /dev/null +++ b/scss/config.scss @@ -0,0 +1,8 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +// Add the "w-000px"/"h-000px" classes. +$add-px-sizing-rules: false; + +$nibblepoker-background-root: "./"; + +$use-b64-backgrounds: true; diff --git a/scss/core/border.scss b/scss/core/border.scss new file mode 100644 index 0000000..7ffc5ca --- /dev/null +++ b/scss/core/border.scss @@ -0,0 +1,64 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Borders */ + +.b, .border { + border: 1px solid #{$color-border-all}; +} + +.b-0 { + border: 0; +} + +@mixin border-maker($side-key, $side-css-key) { + .b#{$side-key} { + border-#{$side-css-key}: 1px solid #{$color-border-all}; + } + .b#{$side-key}-0 { + border-#{$side-css-key}: 0; + } +} + +@include border-maker("t", "top"); +@include border-maker("b", "bottom"); +@include border-maker("l", "left"); +@include border-maker("r", "right"); + +.bx { + border-left: 1px solid #{$color-border-all}; + border-right: 1px solid #{$color-border-all}; +} +.bx-0 { + border-left: 0; + border-right: 0; +} + +.by { + border-top: 1px solid #{$color-border-all}; + border-bottom: 1px solid #{$color-border-all}; +} +.by-0 { + border-top: 0; + border-bottom: 0; +} + +//.border { +// border: 1px solid; +// +// //&.b-light { +// // border: 1px solid #{$color-border-light}; +// //} +//} + +//main { +// .border { +// border: 1px solid #{$color-border-main}; +// } +//} + +//* { +// .dark-mode & { +// border-color: #{$color-border-all}; +// } +//} + diff --git a/scss/core/containers.scss b/scss/core/containers.scss new file mode 100644 index 0000000..12821b8 --- /dev/null +++ b/scss/core/containers.scss @@ -0,0 +1,19 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Core > Containers */ + +.fluid-container { + position: relative; + width: 100%; + height: 100%; + + // First children, or all, don't care tbh. + & > * { + position: absolute; + width: inherit; + height: inherit; + max-height: inherit; + overflow-y: auto; + overflow-x: hidden; + } +} diff --git a/scss/core/display.scss b/scss/core/display.scss new file mode 100644 index 0000000..89daa59 --- /dev/null +++ b/scss/core/display.scss @@ -0,0 +1,18 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Display */ + +.d-none { + display: none; +} + +.d-inline-block { + display: inline-block; +} + +.o-hidden { + overflow: hidden; +} + +// Notes: +// * 'core/grid.scss' defines '.d-grid' ! (Add here if grids are disabled !) diff --git a/scss/core/flex.scss b/scss/core/flex.scss new file mode 100644 index 0000000..bc3098c --- /dev/null +++ b/scss/core/flex.scss @@ -0,0 +1,77 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Flex */ + +// Display properties +.d-flex { + display: flex; +} + +.d-inline-flex { + display: inline-flex; +} + +// Content justification +.flex-justify-start { + justify-content: flex-start; +} + +.flex-justify-end { + justify-content: flex-end; +} + +.flex-justify-center { + justify-content: center; +} + +.flex-justify-between { + justify-content: space-between; +} + +.flex-justify-around { + justify-content: space-around; +} + +.flex-justify-evenly { + justify-content: space-evenly; +} + +.flex-justify-left { + justify-content: left; +} + +.flex-justify-right { + justify-content: right; +} + +// ??? + +.flex-align-center { + align-items: center; +} +.flex-align-start { + align-items: flex-start; +} + +// Missing: start | end + +.flex-direction-row, .flex-row { + flex-direction: row; +} + +.flex-direction-row-reverse, .flex-row-reverse { + flex-direction: row-reverse; +} + +.flex-direction-column, .flex-column { + flex-direction: column; +} + +.flex-direction-column-reverse, .flex-column-reverse { + flex-direction: column-reverse; +} + +.flex-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; +} diff --git a/scss/core/float.scss b/scss/core/float.scss new file mode 100644 index 0000000..e61c96a --- /dev/null +++ b/scss/core/float.scss @@ -0,0 +1,17 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Float */ + +.fl, .f-left { + float: left; +} + +.fr, .f-right { + float: right; +} + +.fn, .f-none { + float: none; +} + +// TODO: Add more types diff --git a/scss/core/grid.scss b/scss/core/grid.scss new file mode 100644 index 0000000..966331f --- /dev/null +++ b/scss/core/grid.scss @@ -0,0 +1,45 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Grids */ + +.grid, .d-grid { + display: grid; +} + +@mixin grid-col-maker($col-count, $middle-part) { + .grid-col-#{$middle-part}#{$col-count}, .col-#{$middle-part}#{$col-count} { + grid-template-columns: repeat(#{$col-count}, 1fr); + } +} + +@mixin grid-gap-maker($gap-size-key, $gap-size-value) { + .grid-gap-#{$gap-size-key}, .gap-#{$gap-size-key} { + grid-gap: #{$gap-size-value}; + } +} + +// Defining rules for all devices. +@include grid-col-maker("1", ""); +@include grid-col-maker("2", ""); +@include grid-col-maker("3", ""); +@include grid-col-maker("4", ""); +@include grid-col-maker("6", ""); +@include grid-col-maker("8", ""); + +@include grid-gap-maker("xs", calc(#{$grid-gap-base-size} * 0.5)); +@include grid-gap-maker("s", calc(#{$grid-gap-base-size} * 0.75)); +@include grid-gap-maker("m", #{$grid-gap-base-size}); +@include grid-gap-maker("l", calc(#{$grid-gap-base-size} * 1.5)); +@include grid-gap-maker("xl", calc(#{$grid-gap-base-size} * 2.0)); + +@media only screen and (max-width: 992px) { + @include grid-col-maker("1", "medium-"); + @include grid-col-maker("2", "medium-"); + @include grid-col-maker("3", "medium-"); +} + +@media only screen and (max-width: 768px) { + @include grid-col-maker("1", "mobile-"); + @include grid-col-maker("2", "mobile-"); + @include grid-col-maker("3", "mobile-"); +} diff --git a/scss/core/lists.scss b/scss/core/lists.scss new file mode 100644 index 0000000..b9236e8 --- /dev/null +++ b/scss/core/lists.scss @@ -0,0 +1,29 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Lists */ + +ul:not(.no-bullet) { + padding-left: 1.5rem; + + &> li { + list-style-type: disc; + } +} + +ol:not(.no-bullet) { + list-style-type: decimal; + padding-left: 1.5rem; +} + +li { + //list-style-type: disc; + + /*&> li { + list-style-type: circle; + }*/ +} + +/*ul.no-bullet, ol.no-bullet { + list-style-type: none; + padding-left: 0; +}*/ diff --git a/scss/core/overflow.scss b/scss/core/overflow.scss new file mode 100644 index 0000000..b615fda --- /dev/null +++ b/scss/core/overflow.scss @@ -0,0 +1,20 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Overflow */ + +@mixin overflow-maker($overflow-type) { + .o-#{$overflow-type} { + overflow: #{$overflow-type}; + } + .ox-#{$overflow-type} { + overflow-x: #{$overflow-type}; + } + .oy-#{$overflow-type} { + overflow-y: #{$overflow-type}; + } +} + +@include overflow-maker(auto); +@include overflow-maker(scroll); +@include overflow-maker(clip); +@include overflow-maker(hidden); diff --git a/scss/core/position.scss b/scss/core/position.scss new file mode 100644 index 0000000..98ba009 --- /dev/null +++ b/scss/core/position.scss @@ -0,0 +1,7 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Positions */ + +.p-relative { + position: relative; +} diff --git a/scss/core/rounding/corner.scss b/scss/core/rounding/corner.scss new file mode 100644 index 0000000..2e16519 --- /dev/null +++ b/scss/core/rounding/corner.scss @@ -0,0 +1,29 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Rounding > Corner */ +@mixin corner-rounding-maker($size-key, $size-value) { + .rtl-#{$size-key} { + border-top-left-radius: #{$size-value}; + } + .rtr-#{$size-key} { + border-top-right-radius: #{$size-value}; + } + .rbl-#{$size-key} { + border-bottom-left-radius: #{$size-value}; + } + .rbr-#{$size-key} { + border-bottom-right-radius: #{$size-value}; + } +} + + +/* Utilities > Rounding > Corner > Variable Sizes */ +@include corner-rounding-maker("xs", calc(#{$border-base-radius} * 0.5)); +@include corner-rounding-maker("s", calc(#{$border-base-radius} * 0.75)); +@include corner-rounding-maker("m", #{$border-base-radius}); +@include corner-rounding-maker("l", calc(#{$border-base-radius} * 1.5)); + + +/* Utilities > Rounding > Corner > Fixed Sizes */ +@include corner-rounding-maker("0", 0); +@include corner-rounding-maker("r", 50%); diff --git a/scss/core/rounding/global.scss b/scss/core/rounding/global.scss new file mode 100644 index 0000000..25a80a6 --- /dev/null +++ b/scss/core/rounding/global.scss @@ -0,0 +1,22 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Rounding > Global */ +@mixin global-rounding-maker($size-key, $size-value) { + //, .rounding-#{$size-key} + .r-#{$size-key} { + border-radius: #{$size-value}; + } +} + + +/* Utilities > Rounding > Global > Variable Sizes */ +@include global-rounding-maker("xs", calc(#{$border-base-radius} * 0.5)); +@include global-rounding-maker("s", calc(#{$border-base-radius} * 0.75)); +@include global-rounding-maker("m", #{$border-base-radius}); +@include global-rounding-maker("l", calc(#{$border-base-radius} * 1.5)); +@include global-rounding-maker("xl", calc(#{$border-base-radius} * 2.0)); + + +/* Utilities > Rounding > Global > Fixed Sizes */ +@include global-rounding-maker("0", 0); +@include global-rounding-maker("r", 50%); diff --git a/scss/core/rounding/sided.scss b/scss/core/rounding/sided.scss new file mode 100644 index 0000000..710286d --- /dev/null +++ b/scss/core/rounding/sided.scss @@ -0,0 +1,33 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Rounding > Sided */ +@mixin sided-rounding-maker($size-key, $size-value) { + .rt-#{$size-key} { + border-top-left-radius: #{$size-value}; + border-top-right-radius: #{$size-value}; + } + .rb-#{$size-key} { + border-bottom-left-radius: #{$size-value}; + border-bottom-right-radius: #{$size-value}; + } + .rl-#{$size-key} { + border-top-left-radius: #{$size-value}; + border-bottom-left-radius: #{$size-value}; + } + .rr-#{$size-key} { + border-top-right-radius: #{$size-value}; + border-bottom-right-radius: #{$size-value}; + } +} + + +/* Utilities > Rounding > Sided > Variable Sizes */ +@include sided-rounding-maker("xs", calc(#{$border-base-radius} * 0.5)); +@include sided-rounding-maker("s", calc(#{$border-base-radius} * 0.75)); +@include sided-rounding-maker("m", #{$border-base-radius}); +@include sided-rounding-maker("l", calc(#{$border-base-radius} * 1.5)); + + +/* Utilities > Rounding > Sided > Fixed Sizes */ +@include sided-rounding-maker("0", 0); +@include sided-rounding-maker("r", 50%); diff --git a/scss/core/sizing.scss b/scss/core/sizing.scss new file mode 100644 index 0000000..fdfb456 --- /dev/null +++ b/scss/core/sizing.scss @@ -0,0 +1,56 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Sizing */ + +// 100 % +.w-full { + width: 100%; +} +.wm-full { + max-width: 100%; +} + +.h-full { + height: 100%; +} +.hm-full { + max-height: 100%; +} + +// 50 % +.w-half { + width: 50%; +} + +.h-half { + height: 50%; +} + +// Pixels Sizing (Deprecated, disabled by default, use custom rules !) +@if($add-px-sizing-rules) { + // 50, 100, ..., 250 px + @for $_ from 1 through 5 { + $pxSize: $_ * 50; + + .w-#{$pxSize} { + width: #{$pxSize}px; + } + + .h-#{$pxSize} { + height: #{$pxSize}px; + } + } + + // 300, 400, ..., 900 px + @for $_ from 3 through 9 { + $pxSize: $_ * 100; + + .w-#{$pxSize} { + width: #{$pxSize}px; + } + + .h-#{$pxSize} { + height: #{$pxSize}px; + } + } +} diff --git a/scss/core/spacing/axis.scss b/scss/core/spacing/axis.scss new file mode 100644 index 0000000..e9e0fbf --- /dev/null +++ b/scss/core/spacing/axis.scss @@ -0,0 +1,39 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Spacing > Sided */ +@mixin axis-spacing-maker($type-key, $type-property, $size-key, $size-value) { + .#{$type-key}x-#{$size-key} { + #{$type-property}-left: #{$size-value}; + #{$type-property}-right: #{$size-value}; + } + .#{$type-key}y-#{$size-key} { + #{$type-property}-top: #{$size-value}; + #{$type-property}-bottom: #{$size-value}; + } +} + + +/* Utilities > Spacing > Sided > Variable Sizes */ +@include axis-spacing-maker("m", "margin", "xxs", calc(#{$margin-base-size} * 0.25)); +@include axis-spacing-maker("m", "margin", "xs", calc(#{$margin-base-size} * 0.5)); +@include axis-spacing-maker("m", "margin", "s", calc(#{$margin-base-size} * 0.75)); +@include axis-spacing-maker("m", "margin", "m", #{$margin-base-size}); +@include axis-spacing-maker("m", "margin", "l", calc(#{$margin-base-size} * 1.5)); +@include axis-spacing-maker("m", "margin", "xl", calc(#{$margin-base-size} * 2.0)); + +@include axis-spacing-maker("p", "padding", "xxs", calc(#{$margin-base-size} * 0.25)); +@include axis-spacing-maker("p", "padding", "xs", calc(#{$margin-base-size} * 0.5)); +@include axis-spacing-maker("p", "padding", "s", calc(#{$margin-base-size} * 0.75)); +@include axis-spacing-maker("p", "padding", "m", #{$margin-base-size}); +@include axis-spacing-maker("p", "padding", "l", calc(#{$margin-base-size} * 1.5)); +@include axis-spacing-maker("p", "padding", "xl", calc(#{$margin-base-size} * 2.0)); + + +/* Utilities > Spacing > Sided > Fixed Sizes */ +@include axis-spacing-maker("m", "margin", "0", 0); +@include axis-spacing-maker("p", "padding", "0", 0); + + +/* Utilities > Spacing > Sided > Others */ +@include axis-spacing-maker("m", "margin", "auto", auto); +@include axis-spacing-maker("p", "padding", "auto", auto); diff --git a/scss/core/spacing/global.scss b/scss/core/spacing/global.scss new file mode 100644 index 0000000..b9c028b --- /dev/null +++ b/scss/core/spacing/global.scss @@ -0,0 +1,46 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Spacing > Global */ +@mixin global-spacing-maker($type-key, $type-property, $size-key, $size-value) { + .#{$type-key}-#{$size-key} { + #{$type-property}: #{$size-value}; + } +} + + +/* Utilities > Spacing > Global > Variable Sizes */ +@include global-spacing-maker("m", "margin", "xxs", calc(#{$margin-base-size} * 0.25)); +@include global-spacing-maker("m", "margin", "xs", calc(#{$margin-base-size} * 0.5)); +@include global-spacing-maker("m", "margin", "s", calc(#{$margin-base-size} * 0.75)); +@include global-spacing-maker("m", "margin", "m", #{$margin-base-size}); +@include global-spacing-maker("m", "margin", "l", calc(#{$margin-base-size} * 1.5)); +@include global-spacing-maker("m", "margin", "xl", calc(#{$margin-base-size} * 2.0)); + +@include global-spacing-maker("p", "padding", "xxs", calc(#{$margin-base-size} * 0.25)); +@include global-spacing-maker("p", "padding", "xs", calc(#{$margin-base-size} * 0.5)); +@include global-spacing-maker("p", "padding", "s", calc(#{$margin-base-size} * 0.75)); +@include global-spacing-maker("p", "padding", "m", #{$margin-base-size}); +@include global-spacing-maker("p", "padding", "l", calc(#{$margin-base-size} * 1.5)); +@include global-spacing-maker("p", "padding", "xl", calc(#{$margin-base-size} * 2.0)); + + +/* Utilities > Spacing > Global > Fixed Sizes */ +@include global-spacing-maker("m", "margin", "0", 0); +@include global-spacing-maker("p", "padding", "0", 0); + + +/* Utilities > Spacing > Global > Others */ +@include global-spacing-maker("m", "margin", "auto", auto); +@include global-spacing-maker("p", "padding", "auto", auto); + + +/* Utilities > Spacing > Global > Manual Extras */ +.p-xxxs { + padding: calc(#{$margin-base-size} * 0.125); +} +.p-mxs { + padding: calc(#{$margin-base-size} * 0.375); +} +.p-ms { + padding: calc(#{$margin-base-size} * 0.625); +} diff --git a/scss/core/spacing/sided.scss b/scss/core/spacing/sided.scss new file mode 100644 index 0000000..a7f1cef --- /dev/null +++ b/scss/core/spacing/sided.scss @@ -0,0 +1,43 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Utilities > Spacing > Sided */ +@mixin sided-spacing-maker($type-key, $type-property, $size-key, $size-value) { + .#{$type-key}t-#{$size-key} { + #{$type-property}-top: #{$size-value}; + } + .#{$type-key}b-#{$size-key} { + #{$type-property}-bottom: #{$size-value}; + } + .#{$type-key}l-#{$size-key} { + #{$type-property}-left: #{$size-value}; + } + .#{$type-key}r-#{$size-key} { + #{$type-property}-right: #{$size-value}; + } +} + + +/* Utilities > Spacing > Sided > Variable Sizes */ +@include sided-spacing-maker("m", "margin", "xxs", calc(#{$margin-base-size} * 0.25)); +@include sided-spacing-maker("m", "margin", "xs", calc(#{$margin-base-size} * 0.5)); +@include sided-spacing-maker("m", "margin", "s", calc(#{$margin-base-size} * 0.75)); +@include sided-spacing-maker("m", "margin", "m", #{$margin-base-size}); +@include sided-spacing-maker("m", "margin", "l", calc(#{$margin-base-size} * 1.5)); +@include sided-spacing-maker("m", "margin", "xl", calc(#{$margin-base-size} * 2.0)); + +@include sided-spacing-maker("p", "padding", "xxs", calc(#{$margin-base-size} * 0.25)); +@include sided-spacing-maker("p", "padding", "xs", calc(#{$margin-base-size} * 0.5)); +@include sided-spacing-maker("p", "padding", "s", calc(#{$margin-base-size} * 0.75)); +@include sided-spacing-maker("p", "padding", "m", #{$margin-base-size}); +@include sided-spacing-maker("p", "padding", "l", calc(#{$margin-base-size} * 1.5)); +@include sided-spacing-maker("p", "padding", "xl", calc(#{$margin-base-size} * 2.0)); + + +/* Utilities > Spacing > Sided > Fixed Sizes */ +@include sided-spacing-maker("m", "margin", "0", 0); +@include sided-spacing-maker("p", "padding", "0", 0); + + +/* Utilities > Spacing > Sided > Others */ +@include sided-spacing-maker("m", "margin", "auto", auto); +@include sided-spacing-maker("p", "padding", "auto", auto); diff --git a/scss/core/text.scss b/scss/core/text.scss new file mode 100644 index 0000000..fc12f3e --- /dev/null +++ b/scss/core/text.scss @@ -0,0 +1,168 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Core > Text */ + +/* Core > Text > Headings */ + +h1, h2, h3, h4, h5, h6 { + font-weight: #{$text-header-weight}; +} + + +/* Core > Text > Sizes */ + +// ".t-size-6", ".t-size-8", ..., "t-size-40" +@for $_ from 3 through 20 { + $sizeKey: $_ * 2; + $sizeValue: $sizeKey / 10; + + .t-size-#{$sizeKey} { + font-size: #{$sizeValue}rem !important; + } +} + +// Adding special odd values +.t-size-11 { + font-size: 1.1rem !important; +} +.t-size-13 { + font-size: 1.3rem !important; +} +.t-size-15 { + font-size: 1.5rem !important; +} +.t-size-17 { + font-size: 1.7rem !important; +} + +// Jumbo sizes +// ".t-size-35" & ".t-size-40" +@for $_ from 7 through 8 { + $size: $_ * 5; + + .t-size-#{$size} { + font-size: #{$size / 10}rem !important; + } +} + + +/* Core > Text > Weights */ + +.t-w-normal, .t-normal { + font-weight: normal !important; +} +b, .t-w-bold, .t-bold { + font-weight: bold !important; +} +.t-w-bolder, .t-bolder { + font-weight: bolder !important; +} +.t-w-lighter, .t-lighter { + font-weight: lighter !important; +} + +// ".t-w-100", ".t-w-200", ..., ".t-w-900" +@for $_ from 1 through 9 { + $size: $_ * 100; + + .t-w-#{$size} { + font-weight: #{$size} !important; + } +} +// /!\ Firefox moment /!\ +// * The ".t-w-200" to ".t-w-500" classes barely any effect on weight... + + +/* Core > Text > Styles */ + +i, .t-italic { + font-style: italic; +} + +.t-oblique { + font-style: oblique; +} + +u, .t-underline { + text-decoration: underline; +} + +s, .t-strikethrough { + text-decoration: line-through; +} + +.t-overline { + text-decoration: overline; +} + + +/* Core > Text > Alignment */ + +.t-justify { + text-align: justify; +} + +.t-center { + text-align: center; +} + +.t-left { + text-align: left; +} + +.t-right { + text-align: right; +} + +.t-start { + text-align: start; +} + +.t-end { + text-align: end; +} + + +/* Core > Text > Modifiers */ + +.t-ucase { + text-transform: uppercase; +} + +.t-lcase { + text-transform: lowercase; +} + +.t-capitalize { + text-transform: capitalize; +} + + +/* Core > Text > Misc */ + +.t-nowrap { + white-space: nowrap; + text-wrap: nowrap; +} + + +/* Core > Text > Helpers */ + +.t-half-muted { + opacity: 65%; +} + +.t-muted { + //@if $undefined-toggle-css-variables { + // color: var(--color-white-muted); + //} @else { + // color: #{$color-white-muted}; + //} + //color: #A9A9Aa; + opacity: 50%; +} + +.t-super-muted { + // Should be 35% TBH + opacity: 45%; +} diff --git a/scss/debugger.scss b/scss/debugger.scss new file mode 100644 index 0000000..9f68b63 --- /dev/null +++ b/scss/debugger.scss @@ -0,0 +1,17 @@ +// NibblePoker CSS Debugger - CC0 1.0 (Public Domain) + +.debug { + border: 1px dotted deeppink !important; + & *.debug { + border: 1px dotted yellow !important; + & *.debug { + border: 1px dotted cyan !important; + & *.debug { + border: 1px dotted lime !important; + & *.debug { + border: 1px dotted red !important; + } + } + } + } +} diff --git a/scss/external/reset.scss b/scss/external/reset.scss new file mode 100644 index 0000000..640f041 --- /dev/null +++ b/scss/external/reset.scss @@ -0,0 +1,60 @@ +/* + * ----------------------------------------------------------------------------- + * Reset.css + * ----------------------------------------------------------------------------- + * http://meyerweb.com/eric/tools/css/reset/ + * v2.0 | 20110126 + * License: none (public domain) + * ----------------------------------------------------------------------------- + */ + +/* External > Reset.css */ + +*, *:before, *:after { + box-sizing: border-box; +} + +html, body, div, span, object, iframe, figure, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, code, em, img, small, +strike, strong, sub, sup, tt, b, u, i, ol, ul, li, fieldset, form, label, table, caption, tbody, tfoot, thead, tr, th, +td, main, canvas, embed, footer, header, nav, section, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + text-size-adjust: none; +} + +footer, header, nav, section, main { + display: block; +} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +input { + -webkit-appearance: none; + border-radius: 0; +} diff --git a/scss/nibblepoker.scss b/scss/nibblepoker.scss new file mode 100644 index 0000000..3fdaa48 --- /dev/null +++ b/scss/nibblepoker.scss @@ -0,0 +1,75 @@ +/* + * ----------------------------------------------------------------------------- + * NibblePoker CSS Theme + * ----------------------------------------------------------------------------- + * Author: Herwin Bozet + * License: CC0 1.0 (Public Domain) + * Source: ??? + * ----------------------------------------------------------------------------- + */ + +/* Config */ +@import 'config'; + +/* Externals */ +@import 'external/reset'; // Doesn't reset checkboxes ! + +/* Variables */ +@import 'variables'; + +/* Core */ +@import 'core/border'; // Border rules (.border, .bt-0, ...) +@import 'core/float'; // Floating rules (.f-right, ...) +@import 'core/sizing'; // Rules for setting elements size (.w-full, ...) +@import 'core/flex'; // /!\ Needs an overhaul !!! +@import 'core/grid'; // /!\ Needs an overhaul !!! +@import 'core/text'; // Text-related rules (.t-bold, t-ucase, t-size-14, ...) +//@import 'core/containers'; // Cannot remember why it was used, if ever +@import 'core/display'; // /!\ Needs improvement !!! +@import 'core/position'; // /!\ Needs improvement !!! +@import 'core/overflow'; // Defines generic overflow rules (.o-hidden, .ox-scroll, ...) +@import 'core/lists'; + +/* Core > Rounding */ +@import 'core/rounding/global'; +@import 'core/rounding/sided'; +@import 'core/rounding/corner'; + +/* Core > Spacing */ +@import 'core/spacing/global'; +@import 'core/spacing/axis'; +@import 'core/spacing/sided'; + +/* Site */ + +/* Site > Layouts */ +@import 'site/layouts/commons'; // Sets up the page's default sizing rules +@import 'site/layouts/generic'; // Theme used for websites with a toggleable sidebar (Similar to WinUI apps) + +/* Site > Styles */ +@import 'site/base'; // Needs a rework, Defines some basic common broad styling/coloring rules +@import 'site/text'; // Has some hardcoded width for font-awesome icons in sidebar and headings + +/* Site > Elements */ +@import 'site/hr'; // Custom horizontal rulers +@import 'site/scrollbar'; // Personalizes the scrollbars (Horizontal is still unfinished !) +@import 'site/input'; // Has ugly fix for download buttons +@import 'site/table'; // Uses copied paddings for cells & ugly rounding fix +@import 'site/code'; // Uses forced borders, roundings and paddings +@import 'site/video'; + +/* Site > Misc */ +@import 'site/borders'; // Applies the colors mostly, the size are in the elements ! +@import 'site/backgrounds'; + +/* Site > Fixes */ +@import 'site/mobile'; // Has !important overrides for obvious reasons + +/* Site > Unsorted */ +@import 'site/image'; +@import 'site/wedge'; +@import 'site/content'; // Uses fixed sizes and floats +@import 'site/modal'; + +/* Extras */ +@import 'site/splide'; diff --git a/scss/site/backgrounds.scss b/scss/site/backgrounds.scss new file mode 100644 index 0000000..2283edf --- /dev/null +++ b/scss/site/backgrounds.scss @@ -0,0 +1,31 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Site > Misc > Backgrounds */ + +.bkgd-blank { + background: #{$color-background-main-headings}; +} + +// The element rules override rules in `base.scss ~94` +.bkgd-surround, header, nav, footer { + //background: #{$color-background-surround}; + background: #{$color-background-surround} url("#{$nibblepoker-background-root}/3px-tile-0.1.png") repeat scroll center center; +} + +.bkgd-blank-dark { + background: mix($color-background-main, $color-background-surround, 50%); +} + +.bkgd-grid { + background: #{$color-background-main-headings} url("#{$nibblepoker-background-root}/3px-tile-0.4.png") repeat scroll center center; +} + +.bkgd-squares { + background: #{$color-background-main-headings} url("#{$nibblepoker-background-root}/bright-squares-p100-0.125.png") repeat scroll center center; +} + +.bkgd-math { + //background: #{$color-background-main-headings} url("#{$nibblepoker-background-root}/old-mathematics-v2-0.25.png") repeat scroll center center; + // FIXME: Fix the code using this class !!! + background: #{$color-background-main-headings} url("#{$nibblepoker-background-root}/3px-tile-0.2.png") repeat scroll center center; +} diff --git a/scss/site/base.scss b/scss/site/base.scss new file mode 100644 index 0000000..bdcb172 --- /dev/null +++ b/scss/site/base.scss @@ -0,0 +1,41 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Site > Styles > Base */ + +/* Site > Styles > Base > Coloring & Fonts (TODO: Needs a small rework) */ + +body { + background-color: #{$color-background-body}; + + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +} + +// Overridden by a rule in background.scss ! +header, nav, footer { + background-color: #{$color-background-surround}; +} + +main { + background-color: #{$color-background-main}; + + // FIXME: Adapt when sidebar is closed ! + // FIXME: Move it to the proper layout file then !!! + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.375) inset; +} + + +/* Site > Styles > Base > Trash */ + +// FIXME: Move it out too ! +// Allowed for right-align in headings with 'ml-auto' instead of 'f-right' ! +/*.heading-main { + > h2, > h3, > h4 { + display: flex; + align-items: center; + justify-content: left; + } + &.heading-dyn-width-1 { + min-width: 75%; + } +}*/ diff --git a/scss/site/borders.scss b/scss/site/borders.scss new file mode 100644 index 0000000..8a85824 --- /dev/null +++ b/scss/site/borders.scss @@ -0,0 +1,36 @@ + +.border, code, .code, kbd { + border-color: #{$color-border-surround}; + + //&.b-light { + // border: 1px solid #{$color-border-light}; + //} +} + +code, .code, kbd { + border-color: #{$color-border-code}; +} + +main { + .border { + border-color: #{$color-border-main}; + + //&.b-light { + // border: 1px solid #{$color-border-light}; + //} + } +} + +table.stylish { + // Fixing border issues when using rounded corners by using a "fake" one using the background's color. + // It will look like utter shit when rounded on firefox because its rendering engine cannot clip rounded corners apparently. + // I guess that's what being at less than 3% of the market share does to you and your ability to care about basic shit. + &.border { + background-color: #{$color-border-main}; + } +} + +// Special fix for select inputs' dropdown menu +//select.border option::before { +// border: 1px solid deeppink !important; +//} diff --git a/scss/site/code.scss b/scss/site/code.scss new file mode 100644 index 0000000..e9db8eb --- /dev/null +++ b/scss/site/code.scss @@ -0,0 +1,38 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +code, .code, kbd { + font-family: Consolas, "Courier New", monospace; +} + +// For large blocks +code { + +} + +// For spans +.code, kbd { + background-color: #{$color-background-code}; + + border: 1px solid; + + // Using '.r-s' + border-radius: calc(#{$border-base-radius} * 0.75); + + // Using the middle of '.px-xs' and '.px-s' + padding-left: calc(#{$border-base-radius} * 0.625); + padding-right: calc(#{$border-base-radius} * 0.625); +} + +// Removes the background added by highlight.js +.code-line { + background: rgba(0,0,0,0) !important; +} + +code, .code, .code-line { + line-height: 1.35; +} + +// FIXME: Use a proper class !!! +.code:not(code) { + padding: calc(#{$border-base-radius} * 0.625); +} diff --git a/scss/site/content.scss b/scss/site/content.scss new file mode 100644 index 0000000..62c433a --- /dev/null +++ b/scss/site/content.scss @@ -0,0 +1,37 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +.content-search-entry { + min-height: #{$content-search-image-size}; +} + +.content-search-image { + width: #{$content-search-image-size}; + height: #{$content-search-image-size}; + float: left; + filter: drop-shadow(0 0 0.2rem #000000CF); +} + +.content-search-entry > p { + width: 90%; + //max-width: 800px; +} + +.content-error-text { + max-width: 700px; +} + +// Image shown in the smaller inline content cards +.content-card-image { + width: calc(#{$content-search-image-size} * 0.75); + height: calc(#{$content-search-image-size} * 0.75); + float: left; + //filter: drop-shadow(0 0 0.2rem #000000CF); + //box-shadow: 0px 0px 20px 2px #000000CF inset; +} + +// Should be a span with IMG tags inside it. +.app-card-icons { + &>img { + height: 1.25rem; + } +} diff --git a/scss/site/hr.scss b/scss/site/hr.scss new file mode 100644 index 0000000..6ab5628 --- /dev/null +++ b/scss/site/hr.scss @@ -0,0 +1,54 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Site > Elements > Horizontal Rule */ + +hr { + border-color: #{$color-border-all}; + + &.subtle, &.hr-subtle { + //background-color: rgba(0,0,0,0) !important; + //background: #5d5f61; + //background: radial-gradient(circle, rgba(83, 85, 87, 0.8) 0%, rgba(65, 67, 69, 0.65) 75%, rgba(17, 20, 23, 0) 100%); + opacity: 0.2; + } + + &.dashed, &.hr-dashed { + border-style: dashed; + } + + &.dotted, &.hr-dotted { + border-style: dotted; + } + + &.double, &.hr-double, &.thick, &.hr-thick { + border-style: double; + } + + // Default ! + //&.inset, &.inset { + // border-style: inset; + //} + + &.outset, &.hr-outset { + border-style: outset; + } + + &.cut-here, &.ht-cut-here { + border-width: 1px 0 0 0; + height: 9px; + + &:after { + content: '\002702'; + display: inline-block; + position: relative; + color: #{$color-border-all}; + font-size: 18px; + top: -8px; + left: 40px; + + font-family: serif; + //filter: grayscale(1); + //transform: rotate(-90deg); + } + } +} diff --git a/scss/site/image.scss b/scss/site/image.scss new file mode 100644 index 0000000..a8e8d09 --- /dev/null +++ b/scss/site/image.scss @@ -0,0 +1,127 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +.img-text { + height: 1em; + vertical-align: top; +} + +.btn-img { + display: flex; + height: 1em; +} + +.img-showcase { + width: 96px; + height: 96px; +} + +.img-profile { + width: 7.5rem; + height: 7.5rem; +} + +.img-contributor, .img-contributor > img { + width: 6rem; + height: 6rem; + + border-radius: 50%; + + transition: width 0.175s ease-in-out, height 0.175s ease-in-out, opacity 0.175s ease-in-out; + + &:hover, &:hover > img { + width: 7.5rem; + height: 7.5rem; + } + + &.kitty { + cursor: grab; + } +} + +.img-contributor { + display: inline-block; + box-shadow: 0 0 6px 0 rgba(0,0,0,0.75); + + &>img { + position: absolute; + + &:last-child { + box-shadow: none; + position: relative; + opacity: 0.0; + } + } + + &:hover { + img { + opacity: 0.0; + } + &>img:last-child { + opacity: 1.0; + } + } +} + +//.align-v-t + +#logo-sidebar, .logo-sidebar { + filter: brightness(110%) grayscale(100%); + //mix-blend-mode: multiply; + //opacity: 40%; + // Fixes the width to the size of the sidebar minus its padding. (15rem - 1rem * 2) + width: 13rem; + height: auto; +} + +// Based on '#logo-sidebar' +.logo-sidebar-v2 { + filter: drop-shadow(0 0 0.15rem #0000007F) saturate(75%); + width: 13rem; + height: auto; + + transition-property: -moz-filter, -ms-filter, -o-filter, -webkit-filter, filter; + transition-duration: 0.4s; + transition-timing-function: cubic-bezier(.25, .8, .25, 1.1); + + &:hover { + filter: drop-shadow(0 0 0.15rem #0000007F) saturate(100%); + } + +} + +#logo-footer { + filter: brightness(110%) grayscale(100%); + opacity: 40%; + height: 1.8em; + object-fit: contain; +} + +#error-page-skit { + max-width: 40%; + height: auto; + position: absolute; + bottom: 1.5em; + right: 1.5em; + filter: drop-shadow(0 0 0.25rem #0000007F); + //opacity: 0.25; + + //mix-blend-mode: multiply; + //opacity: 0.2; + + opacity: 0.4; + + // Preventing the selection and dragging of the image for aesthetic reasons. + user-drag: none; + user-select: none; +} + +// Logo colors +//.npl1, .npl6 { +//} +// +//.npl2, .npl5 { +//} +// +//.npl3, .npl4 { +//} + diff --git a/scss/site/input.scss b/scss/site/input.scss new file mode 100644 index 0000000..1af8a28 --- /dev/null +++ b/scss/site/input.scss @@ -0,0 +1,140 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Site > Elements > Inputs */ + +/* Site > Elements > Inputs > Commons */ + +button, input, textarea, select { + border: 0; + + // Removing ugly-ass white glow when editing text-related inputs. + // Shit looks straight out of winforms in 2023... + outline: none; + + color: #{$color-text-inputs}; + background-color: #{$color-background-inputs}; + + &:not(.no-focus) { + &:focus { + box-shadow: 0px 0px 3px 0px #{$color-input-glow}; + } + } + + &:disabled { + cursor: not-allowed; + } +} + +label { + cursor: pointer; + user-select: none; +} + +/* Site > Elements > Inputs > Checkbox */ + +input[type=checkbox] { + width: 1.65em; + height: 1.65em; + background-color: #{$color-background-checkbox-unchecked}; + + cursor: pointer; + + &:checked { + background-color: #{$color-background-checkbox-checked}; + } + + position: relative; + vertical-align: middle; +} +input[type="checkbox"] + label { + position: relative; + display: inline-block; + vertical-align: middle; +} + +/* Site > Elements > Inputs > Buttons */ + +button { + cursor: pointer; + background-color: #{$color-background-button}; + + &:hover { + background-color: #{$color-background-button-hover}; + } + + &.primary { + background-color: #{$color-background-button-primary}; + + &:hover { + background-color: #{$color-background-button-primary-hover}; + } + } + + &.success { + background-color: #{$color-background-button-success}; + + &:hover { + background-color: #{$color-background-button-success-hover}; + } + } + + &.error { + background-color: #{$color-background-button-error}; + + &:hover { + background-color: #{$color-background-button-error-hover}; + } + } + + &.warning { + background-color: #{$color-background-button-warning}; + + &:hover { + background-color: #{$color-background-button-warning-hover}; + } + } +} + +// Ugly fix for download buttons +button + button, .button-link + .button-link > button { + margin-left: 0.75rem; +} + +/* Site > Elements > Inputs > Lang Selector */ + +#lang-selector { + position: relative; + white-space: nowrap; + + > summary { + cursor: pointer; + list-style: none; + user-select: none; + } + + > div { + position: absolute; + z-index: #{$z-index-lang-dropdown}; + top: 2rem; + right: 0; + min-width: 100%; + + // Visibility transition + //height: 0; + //transition: height 0.4s; + //transition-timing-function: cubic-bezier(.25,.8,.25,1.1); + } + + // TODO: Maybe force it to be visible when closes ? + + //&[open] > div { + // height: auto; + //} +} + +textarea { + + &.no-resize { + resize: none; + } +} \ No newline at end of file diff --git a/scss/site/layouts/commons.scss b/scss/site/layouts/commons.scss new file mode 100644 index 0000000..082d0c9 --- /dev/null +++ b/scss/site/layouts/commons.scss @@ -0,0 +1,15 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Site > Layouts */ + +/* Site > Layouts > Commons */ + +html, body { + // Do not use 100vh, it includes the search bar ! + min-width: 100vw; + min-height: 100%; + width: 100vw !important; + height: 100% !important; + max-width: 100vw; + max-height: 100%; +} diff --git a/scss/site/layouts/generic.scss b/scss/site/layouts/generic.scss new file mode 100644 index 0000000..d76a541 --- /dev/null +++ b/scss/site/layouts/generic.scss @@ -0,0 +1,161 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Site > Layouts > Generic */ + +/* Site > Layouts > Generic > Main Grid */ + +body.layout-generic { + display: grid; + grid-template-columns: min-content 1fr; + grid-template-rows: min-content 1fr min-content; + gap: 0; + + & > nav { + grid-column: 1; + grid-row: 1 / span 2; + overflow-x: hidden; + overflow-y: auto; + z-index: #{$z-index-sidebar}; + } + + & > header { + grid-column: 2; + grid-row: 1; + + // Inner content + display: grid; + grid-template-columns: 1fr min-content; + grid-template-rows: min-content; + + & > h1 { + grid-column: 1; + } + + & > #lang-selector { + grid-column: 2; + } + } + + & > main { + grid-column: 2; + grid-row: 2; + overflow-x: hidden; + overflow-y: auto; + position: relative; // Helps with some absolute alignments inside it + } + + & > footer { + grid-column: 1 / span 2; + grid-row: 3; + } +} + + +/* Site > Layouts > Generic > Mobile Fixes */ + +@media only screen and (max-width: 768px) { + body.layout-generic { + & > nav { + //border-right: 1px solid #{$color-border-all}; + border-right: 1px solid #{$color-border-main}; + } + + & > header { + grid-column: 1 / span 2; + } + + & > main { + grid-column: 1 / span 2; + // TODO: Remove scrolling here + } + } +} + + +/* Site > Layouts > Generic > Sidebar */ + +body.layout-generic { + .sidebar { + width: #{$size-sidebar}; + max-width: #{$size-sidebar}; + min-height: 100%; + + &.retracted { + width: 0; + padding-left: 0; + padding-right: 0; + overflow: hidden; + } + + .sidebar-entry { + display: flex; + align-items: center; + justify-content: left; + } + } +} + + +/* Site > Layouts > Generic > Sidebar > Mobile Fixes */ + +// Inverting the sidebar's states for mobile devices +@media only screen and (max-width: 768px) { + body.layout-generic { + .sidebar { + width: 0; + padding-left: 0; + padding-right: 0; + overflow: hidden; + + &.retracted { + width: #{$size-sidebar}; + max-width: #{$size-sidebar}; + min-height: 100%; + overflow: auto; + overflow-x: hidden; + // Inherited from .p-m + padding-left: 1rem; + padding-right: 1rem; + } + + .sidebar-entry { + display: flex; + align-items: center; + justify-content: left; + } + } + } +} + + +/* Site > Layouts > Generic > Main Extras */ + +@media only screen and (max-width: 768px) { + body.layout-generic { + main { + border-left: 0 !important; + border-radius: 0 !important; + } + } +} + +@media only screen and (min-width: 768px) { + body.layout-generic { + main { + &.expanded { + border-left: 0; + border-radius: 0; + } + } + } +} + + +/* Site > Layouts > Generic > Transitions */ + +body.layout-generic { + main, .sidebar { + transition: width 0.4s, padding 0.4s, border-width 0.4s, border-radius 0.4s; + transition-timing-function: cubic-bezier(.25, .8, .25, 1.1); + } +} diff --git a/scss/site/mobile.scss b/scss/site/mobile.scss new file mode 100644 index 0000000..c3e3174 --- /dev/null +++ b/scss/site/mobile.scss @@ -0,0 +1,19 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Site > Fixes > Mobile */ + +@media only screen and (max-width: 768px) { + // Overrides the ".p-l" class used on "main". + main { + padding: calc(#{$margin-base-size} * 0.5) !important; + } + + // Overrides a style in "site/content.scss". + .content-search-entry > p { + width: 100% !important; + } + + .mobile-hide { + display: none; + } +} diff --git a/scss/site/modal.scss b/scss/site/modal.scss new file mode 100644 index 0000000..14335cf --- /dev/null +++ b/scss/site/modal.scss @@ -0,0 +1,34 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +.modal { + position: absolute; + top: 0; + left: 0; + z-index: #{$z-index-modal}; + background-color: #000000CF; + width: 100vw; + height: 100vh; + + > #modal-content-cross { + cursor: pointer; + } + + > #modal-content-inner { + position: absolute; + //background-color: #00aaaa; + top: 0; + left: 0; + right: 0; + height: 100vh; + width: 75vw; + margin-left: auto; + margin-right: auto; + display: grid; + place-items: center; + } +} + +.modal-inner-image { + max-width: 100%; + max-height: 100%; +} diff --git a/scss/site/scrollbar.scss b/scss/site/scrollbar.scss new file mode 100644 index 0000000..6d32508 --- /dev/null +++ b/scss/site/scrollbar.scss @@ -0,0 +1,62 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Site > Elements > Scrollbars */ + +//@media (min-width: 769px) { +*::-webkit-scrollbar { + width: #{$scrollbar-size}; + height: #{$scrollbar-size}; + background-color: transparent; +} + +*::-webkit-scrollbar-track:vertical { + border-left: 1px solid #{$color-scrollbar-border}; +} + +/**::-webkit-scrollbar-track:horizontal { + border-top: 1px solid #{$color-scrollbar-border}; +}*/ + +*::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.25); + border: 0.4rem solid transparent; + background-clip: content-box; + border-radius: 1em; +} + +*::-webkit-scrollbar-thumb:hover { + background-color: rgba(255, 255, 255, 0.4); + border-color: transparent; +} + +*::-webkit-scrollbar-corner { + background-color: transparent; + border-left: 1px solid rgba(0, 0, 0, 0.1); + border-top: 1px solid rgba(0, 0, 0, 0.1); +} + +//* { +// scrollbar-width: thin; +// scrollbar-color: rgba(0, 0, 0, 0.25) #ffffff; +//} +//*::-webkit-scrollbar-track { +// border-color: rgba(255, 255, 255, 0.05); +//} +//*::-webkit-scrollbar-corner { +// background-color: transparent; +// border-color: rgba(255, 255, 255, 0.05); +//} +//* { +// scrollbar-color: rgba(255, 255, 255, 0.25) #25282c; +//} +//} + +/*.hide-scrollbar { + scrollbar-width: none !important; + -ms-overflow-style: none; + + &::-webkit-scrollbar { + background: transparent; + width: 0px; + } +}*/ diff --git a/scss/site/splide.scss b/scss/site/splide.scss new file mode 100644 index 0000000..3dc4af1 --- /dev/null +++ b/scss/site/splide.scss @@ -0,0 +1,16 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Extras > Splide */ + +// Zoom-in effect for image galleries +.splide li { + transition: all 0.20s ease-in-out; +} +.splide li:hover { + transform: scale(1.05); +} + +// Generic max-height rule +.splide, .splide * { + max-height: 400px; +} diff --git a/scss/site/table.scss b/scss/site/table.scss new file mode 100644 index 0000000..f1d4c93 --- /dev/null +++ b/scss/site/table.scss @@ -0,0 +1,56 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +tr, td { + vertical-align: top; +} + +table.stylish { + th { + font-weight: bold; + } + + tr { + background-color: #{$color-background-table-dual}; + } + + tr:not(:last-of-type), th { + border-bottom: 1.5px solid #{$color-table-border}; + } + + tr:nth-child(2n), th { + background-color: #{$color-background-table-main}; + } + + td:not(:last-of-type), th:not(:last-of-type) { + border-right: 1.5px solid #{$color-table-border}; + } + + // See 'site/border.scss' for border fix. +} + +// Applying .p-xs and .p-s to all cells if needed +// See 'core/spacing' for more info. +.table-p-xs { + td, th { + padding: calc(#{$margin-base-size} * 0.5); + } +} + +.table-h-p-s { + th { + padding: calc(#{$margin-base-size} * 0.75); + } +} + +.table-p-s { + td, th { + padding: calc(#{$margin-base-size} * 0.75); + } +} + +// Centers the cells' content vertically +.table-v-center { + tr, td { + vertical-align: middle; + } +} diff --git a/scss/site/text.scss b/scss/site/text.scss new file mode 100644 index 0000000..3f73a25 --- /dev/null +++ b/scss/site/text.scss @@ -0,0 +1,122 @@ +// NibblePoker.lu CSS - MIT (C) 2023-2024 Bozet Herwin + +/* Site > Text */ + +/* Site > Text > Commons */ + +* { + color: #{$color-text-regular-normal}; +} + + +/* Site > Text > Paragraphs */ + +p { + line-height: 1.2; +} + + +/* Site > Text > Links */ + +a, .a { + // Base + text-decoration: underline; + color: #{$color-link-blue}; + + & * { + color: #{$color-link-blue}; + } + + &:hover { + color: #{$color-link-blue-hover}; + cursor: pointer; + + & * { + color: #{$color-link-blue-hover}; + text-decoration: underline; + } + } + + // Special case for buttons + //&.casper-link, &.button-link, &.text-link { + &.a-bland { + text-decoration: none; + &:hover { + text-decoration: none; // Only really applies to content listing entries... + & * { + text-decoration: none; + } + } + } + + // Bland links + //&.casper-link, &.bland-link { + &.a-hidden { + text-decoration: none; + color: #{$color-text-regular-normal}; + + & * { + color: #{$color-text-regular-normal}; + } + + &:hover { + text-decoration: underline; + color: #{$color-link-hover}; + + & * { + color: #{$color-link-hover}; + } + + // FIXME: Not working, big F + //i { + // text-decoration: none !important; + //} + } + } +} + + +/* Site > Text > Targeted Rules */ + +.t-logo-text { + font-size: 1.775em; + line-height: 1; +} + +/* Site > Text > Targeted Rules > Sidebar */ +// Special rules for the sidebar and FontAwesome icons + +.sidebar-entry { + i { + width: 1.9rem !important; + // Required to prevent a size flicker when hiding/showing the sidebar. + // The about link is the most visible one. + min-width: 1.9rem !important; + } + + // Preventing a subtle line break when hiding/showing the sidebar. + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + // Doesn't work, even with hyper-specific parent selectors... + //> i, > i:hover { + // text-decoration: none !important; + //} +} + +/* Site > Text > Targeted Rules > Headings */ + +// And now for the headings, the exceptions keep popping up :,) +// TODO: Add a simple and nicer divider. +.heading-main { + > h2, > h3, >h4 { + > i { + //margin-left: 0.25rem; + margin-right: 0.4rem; + padding-right: 0.1rem; + width: 1.75rem !important; + text-align: center; + } + } +} diff --git a/scss/site/video.scss b/scss/site/video.scss new file mode 100644 index 0000000..601506b --- /dev/null +++ b/scss/site/video.scss @@ -0,0 +1,9 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) + +/* Site > Elements > Video */ + +// FIXME: Does not respect the core tenets ! +video { + width: 100% !important; + height: auto !important; +} diff --git a/scss/site/wedge.scss b/scss/site/wedge.scss new file mode 100644 index 0000000..290c5d0 --- /dev/null +++ b/scss/site/wedge.scss @@ -0,0 +1,78 @@ +// NibblePoker.lu CSS - (C) 2023 Bozet Herwin + +/* Custom Elements > Wedge */ + +.wedge { + position: absolute; + //top: 0; + //right: 0; + + color: #{$color-text-regular-normal}; + background-color: #{$color-background-button}; + + user-select: none; + cursor: pointer; + + //opacity: 0.875; + + // https://codepen.io/setswon/pen/VJeXXq + // Using a value of ~0.35 feels sluggish. + //transition: color 0.25s ease; + //transition-timing-function: cubic-bezier(.47,1.64,.41,.8); + + &:hover:not(.no-hover) { + background-color: #{$color-background-button-hover}; + } + + &.wedge-shadow { + box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.5); + } + + &.primary { + background-color: #{$color-background-button-primary}; + &:hover:not(.no-hover) { + background-color: #{$color-background-button-primary-hover}; + } + } + + &.success { + background-color: #{$color-background-button-success}; + &:hover:not(.no-hover) { + background-color: #{$color-background-button-success-hover}; + } + } + + &.error { + background-color: #{$color-background-button-error}; + &:hover:not(.no-hover) { + background-color: #{$color-background-button-error-hover}; + } + } + + &.warning { + background-color: #{$color-background-button-warning}; + &:hover:not(.no-hover) { + background-color: #{$color-background-button-warning-hover}; + } + } + + &.wedge-tr { + top: 0; + right: 0; + } + + &.wedge-br { + bottom: 0; + right: 0; + } + + &.wedge-tl { + top: 0; + left: 0; + } + + &.wedge-bl { + bottom: 0; + left: 0; + } +} diff --git a/scss/variables.scss b/scss/variables.scss new file mode 100644 index 0000000..ebe38e7 --- /dev/null +++ b/scss/variables.scss @@ -0,0 +1,315 @@ +// NibblePoker CSS Theme - CC0 1.0 (Public Domain) +@use 'sass:color'; + +/* Variables > Palettes */ + +/* Variables > Palettes > Apollo */ +// https://lospec.com/palette-list/apollo +$color-apollo-00: #172038; +$color-apollo-01: #253a5e; +$color-apollo-02: #3c5e8b; +$color-apollo-03: #4f8fba; +$color-apollo-04: #73bed3; +$color-apollo-05: #a4dddb; +$color-apollo-06: #19332d; +$color-apollo-07: #25562e; +$color-apollo-08: #468232; +$color-apollo-09: #75a743; +$color-apollo-10: #a8ca58; +$color-apollo-11: #d0da91; +$color-apollo-12: #4d2b32; +$color-apollo-13: #7a4841; +$color-apollo-14: #ad7757; +$color-apollo-15: #c09473; +$color-apollo-16: #d7b594; +$color-apollo-17: #e7d5b3; +$color-apollo-18: #341c27; +$color-apollo-19: #602c2c; +$color-apollo-20: #884b2b; +$color-apollo-21: #be772b; +$color-apollo-22: #de9e41; +$color-apollo-23: #e8c170; +$color-apollo-24: #241527; +$color-apollo-25: #411d31; +$color-apollo-26: #752438; +$color-apollo-27: #a53030; +$color-apollo-28: #cf573c; +$color-apollo-29: #da863e; +$color-apollo-30: #1e1d39; +$color-apollo-31: #402751; +$color-apollo-32: #7a367b; +$color-apollo-33: #a23e8c; +$color-apollo-34: #c65197; +$color-apollo-35: #df84a5; +$color-apollo-36: #090a14; +$color-apollo-37: #10141f; +$color-apollo-38: #151d28; +$color-apollo-39: #202e37; +$color-apollo-40: #394a50; +$color-apollo-41: #577277; +$color-apollo-42: #819796; +$color-apollo-43: #a8b5b2; +$color-apollo-44: #c7cfcc; +$color-apollo-45: #ebede9; + +$color-apollo-37_50: mix($color-apollo-37, $color-apollo-38, 50%); + +$color-apollo-38_25: mix($color-apollo-39, $color-apollo-38, 25%); +$color-apollo-38_50: mix($color-apollo-39, $color-apollo-38, 50%); +$color-apollo-38_70: mix($color-apollo-39, $color-apollo-38, 70%); +$color-apollo-38_75: mix($color-apollo-39, $color-apollo-38, 75%); + +$color-apollo-munted-37-1: color.grayscale(color.adjust($color-apollo-37, $lightness: +3.25%)); +$color-apollo-munted-37-2: color.grayscale(color.adjust($color-apollo-37, $lightness: +1.75%)); + +$color-apollo-custom-00: mix($color-apollo-40, $color-apollo-39, 33%); +$color-apollo-custom-01: mix($color-apollo-40, $color-apollo-39, 50%); +$color-apollo-custom-02: mix($color-apollo-40, $color-apollo-39, 2.5%); +$color-apollo-custom-03: mix($color-apollo-40, $color-apollo-39, 65%); + +$color-apollo-custom-10: mix($color-apollo-40, $color-apollo-41, 75%); + +$color-apollo-custom-20: mix($color-apollo-39, $color-apollo-38, 60%); + +$color-apollo-custom-30: mix($color-apollo-01, $color-apollo-03, 80%); // Primary button +$color-apollo-custom-31: mix($color-apollo-01, $color-apollo-03, 65%); // Primary button hover + +/* Variables > Palettes > Material UI */ +// https://materialui.co/colors + +$color-material-blueGrey-50: #eceff1; +$color-material-blueGrey-100: #cfd8dc; +$color-material-blueGrey-200: #b0bec5; +$color-material-blueGrey-300: #90a4ae; +$color-material-blueGrey-400: #78909c; +$color-material-blueGrey-500: #607d8b; +$color-material-blueGrey-600: #546e7a; +$color-material-blueGrey-700: #455a64; +$color-material-blueGrey-800: #37474f; +$color-material-blueGrey-900: #263238; + +$color-material-blueGrey-1000: #151D21; +$color-material-blueGrey-850: mix($color-material-blueGrey-800, $color-material-blueGrey-900, 50%); +//$color-material-blueGrey-925: mix($color-material-blueGrey-1000, $color-material-blueGrey-900, 25%); +$color-material-blueGrey-950: mix($color-material-blueGrey-1000, $color-material-blueGrey-900, 50%); + +/* Variables > Palettes > WinUI 3 */ + +$color-winui-00: #191919; +$color-winui-01: #1D1D1D; +$color-winui-02: #202020; +$color-winui-03: #232323; +$color-winui-04: #272727; +$color-winui-05: #323232; +$color-winui-06: #3E3E3E; + +// https://flatuicolors.com/palette/defo + +/* Variables > Palettes > Misc */ + +//$color-test-01: mix(#7b6aa5, #000000, 33%); +//$color-test-02: #007c7d; + +/* Variables > Colors Mappings */ + +$color-unset: $color-apollo-34; + +/* Variables > Theme selection */ + +// Available themes: +// * Teal Supreme (teal) +// * WinUI 3 (winui) +// * La Moiti Leune (moon) +// * NibblePoker (nibblepoker) +$theme: nibblepoker; + +/* Variables > Colors Mappings > Backgrounds & Borders */ + +$color-background-main: map-get(( + teal: $color-apollo-custom-02, + winui: $color-winui-04, + moon: $color-unset, + nibblepoker: #24252B, +), $theme); + +$color-background-surround: map-get(( + teal: $color-apollo-custom-00, + winui: $color-winui-02, + moon: $color-unset, + nibblepoker: #1D1E22, +), $theme); + +// Used as the background-color in the main's rounded corners +$color-background-body: $color-background-surround; + +// Used in stylized headings +$color-background-main-headings: map-get(( + teal: $color-background-surround, + winui: $color-unset, + moon: $color-unset, + nibblepoker: $color-background-surround, +), $theme); + + +// FIXME: Remove its usage ! +// Left: Code, Kbd, Scrollbar ??? +$color-border-all: $color-unset; // Default border +$color-border-light: $color-unset; // For .b-light class (No longer exists !) + +// Used to separate the 'main' from the 'surround'. +$color-border-surround: map-get(( + teal: $color-apollo-38, + winui: $color-winui-01, + moon: $color-unset, + nibblepoker: #141417, +), $theme); + +// Used as the border for all element inside the "main". +// It probably influences more stuff, but I can't be bothered to fix this... +$color-border-main: map-get(( + teal: $color-apollo-38, // $color-apollo-custom-20; + winui: $color-winui-03, + moon: $color-unset, + nibblepoker: $color-border-surround, +), $theme); + +// TEMP !!! +$color-border-all: $color-border-main; + +$color-background-code: map-get(( + teal: $color-apollo-custom-20, + winui: $color-unset, + moon: $color-unset, + nibblepoker: mix($color-background-main, $color-background-surround, 25%), +), $theme); + +$color-border-code: map-get(( + teal: #{$color-border-surround}CF, + winui: $color-unset, + moon: $color-unset, + nibblepoker: #{$color-border-surround}CF, +), $theme); + + +$color-background-table-main: map-get(( + teal: $color-apollo-custom-01, + winui: $color-unset, + moon: $color-unset, + nibblepoker: mix($color-background-main, $color-background-surround, 50%), +), $theme); + +$color-background-table-dual: map-get(( + teal: $color-apollo-custom-00, + winui: $color-unset, + moon: $color-unset, + nibblepoker: mix($color-background-main, $color-background-surround, 12.5%), +), $theme); + +$color-table-border: map-get(( + teal: $color-apollo-39, + winui: $color-unset, + moon: $color-unset, + nibblepoker: #{$color-border-surround}CF, +), $theme); + +$color-background-inputs: map-get(( + teal: $color-apollo-40, + winui: $color-unset, + moon: $color-unset, + nibblepoker: #2d2f36, +), $theme); + +// TODO: Implement better ones ! +$color-background-checkbox-checked: $color-apollo-08; +$color-background-checkbox-unchecked: $color-apollo-27; + +$color-background-button: map-get(( + teal: $color-apollo-40, + winui: $color-unset, + moon: $color-unset, + nibblepoker: #2d2f36, +), $theme); + +$color-background-button-hover: map-get(( + teal: $color-apollo-custom-10, + winui: $color-unset, + moon: $color-unset, + nibblepoker: #373841, +), $theme); + +$color-background-button-primary: #{$color-apollo-custom-30}; +$color-background-button-primary-hover: mix($color-apollo-custom-30, $color-apollo-custom-31, 37.5%); + +$color-background-button-success: #{$color-apollo-07}; +$color-background-button-success-hover: mix($color-apollo-07, $color-apollo-08, 50%); + +$color-background-button-error: #{$color-apollo-26}; +$color-background-button-error-hover: #{$color-apollo-27}; + +$color-background-button-warning: #{$color-apollo-20}; +$color-background-button-warning-hover: #{$color-apollo-21}; + + + +/* Variables > Colors Mappings > Text */ + +$color-text-regular-normal: $color-apollo-45; +$color-text-inputs: $color-apollo-45; +$color-text-muted: #{$color-apollo-45}E0; +$color-text-muted-super: #{$color-apollo-45}C0; + +$color-link-hover: rgb(253, 255, 251); + +// Should be a mix of 03-04 and 04-05. +$color-link-blue: #{$color-apollo-04}; +$color-link-blue-hover: #{$color-apollo-05}; + +//$color-border-all: $color-apollo-38; +//$color-border-light: $color-apollo-custom-20; + +$color-input-glow: $color-apollo-02; + +//$color-wedge-blue-background: $color-apollo-03; + +// Still used for wedges !!! - Nope, it looked bad with the new colors ! +//$color-wedge-blue-border: $color-apollo-02; + +//$color-background-body: $color-apollo-custom-00; +//$color-background-main: $color-apollo-custom-02; +//$color-background-surround: $color-apollo-custom-00; +// +//// TMP V2 +//$color-background-body: $color-material-blueGrey-900; +//$color-background-main: $color-material-blueGrey-950; +//$color-background-surround: $color-material-blueGrey-900; + + +/* Variables > Scrollbar */ + +//$color-scrollbar-border: rgba(0, 0, 0, 0.15); +$color-scrollbar-border: $color-border-surround; + +$scrollbar-size: 1.25em; + +/* Variables > Others */ + +$border-base-radius: 5px; + +$margin-base-size: 1rem; + +$grid-gap-base-size: 1rem; + +//$hr-base-height: 0.5rem; // Nope + +$text-header-weight: 600; + +$size-sidebar: 15rem; +//$size-sidebar: 30rem; + +$content-search-image-size: 128px; + +/* Variables > Z Indexes */ + +$z-index-sidebar: 5; +$z-index-lang-dropdown: 10; +$z-index-modal: 99; diff --git a/setup.cmd b/setup.cmd new file mode 100644 index 0000000..56ebc1e --- /dev/null +++ b/setup.cmd @@ -0,0 +1,45 @@ +@echo off +setlocal enabledelayedexpansion + +:: Going into the script's directory +cd /D "%~dp0" + + +:setup +echo. +echo Setting up your system +echo ---------------------- + +:setup-npm +echo Updating NPM... +pushd %CD% +call npm update -g npm +popd + +:setup-sass +echo Installing SASS... +pushd %CD% +call npm install -g sass +popd +:setup-sass-update +echo Updating SASS... +pushd %CD% +call npm update -g sass +popd + +:setup-html-minify +echo Installing HTML Minifier... +pushd %CD% +call npm install -g html-minifier +popd + +:setup-html-minify-update +echo Updating HTML Minifier... +pushd %CD% +call npm update -g html-minifier +popd + +:setup-end + + +:end