diff --git a/src/css/global.css b/src/css/global.css index 0589fc5..316d277 100644 --- a/src/css/global.css +++ b/src/css/global.css @@ -1,78 +1,4 @@ -/* - -COLORS -=============================================================================== - -*/ -/* -Flexoki (https://stephango.com/flexoki) -MIT License - -Copyright (c) 2023 Steph Ango - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -/* - -FONT: LINUX LIBERTINE -=============================================================================== -License: GPL and OFL 1.1 - -For license text, see: -- https://gils.nexus/font/GPL.txt -- https://gils.nexus/font/OFL-1.1.txt - -*/ -@font-face { - font-family: "Linux Libertine"; - font-style: normal; - src: local("Linux Libertine"), url("../font/LinLibertine_Rah.ttf"); -} -@font-face { - font-family: "Linux Libertine"; - font-style: normal; - font-weight: 600; - src: local("Linux Libertine Semibold"), url("../font/LinLibertine_RZah.ttf"); -} -@font-face { - font-family: "Linux Libertine"; - font-style: normal; - font-weight: 700; - src: local("Linux Libertine Bold"), url("../font/LinLibertine_RBah.ttf"); -} -@font-face { - font-family: "Linux Libertine"; - font-style: italic; - src: local("Linux Libertine Italic"), url("../font/LinLibertine_RIah.ttf"); -} -@font-face { - font-family: "Linux Libertine"; - font-style: italic; - font-weight: 600; - src: local("Linux Libertine Semibold Italic"), url("../font/LinLibertine_RZIah.ttf"); -} -@font-face { - font-family: "Linux Libertine"; - font-style: italic; - font-weight: 700; - src: local("Linux Libertine Bold Italic"), url("../font/LinLibertine_RBIah.ttf"); -} +/* IMPORTS ================================================================= */ .markup { word-wrap: break-word; line-height: 1.7; @@ -149,8 +75,84 @@ _vars.scss ******************************************************************************* Global variables for the entire website ============================================================================ */ +/* MEDIA BREAKPOINTS ======================================================= */ /* SPACING ================================================================= */ /* FONT SIZING ============================================================= */ +/* + +COLORS +=============================================================================== + +*/ +/* +Flexoki (https://stephango.com/flexoki) +MIT License + +Copyright (c) 2023 Steph Ango + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +/* + +FONT: LINUX LIBERTINE +=============================================================================== +License: GPL and OFL 1.1 + +For license text, see: +- https://gils.nexus/font/GPL.txt +- https://gils.nexus/font/OFL-1.1.txt + +*/ +@font-face { + font-family: "Linux Libertine"; + font-style: normal; + src: local("Linux Libertine"), url("../font/LinLibertine_Rah.ttf"); +} +@font-face { + font-family: "Linux Libertine"; + font-style: normal; + font-weight: 600; + src: local("Linux Libertine Semibold"), url("../font/LinLibertine_RZah.ttf"); +} +@font-face { + font-family: "Linux Libertine"; + font-style: normal; + font-weight: 700; + src: local("Linux Libertine Bold"), url("../font/LinLibertine_RBah.ttf"); +} +@font-face { + font-family: "Linux Libertine"; + font-style: italic; + src: local("Linux Libertine Italic"), url("../font/LinLibertine_RIah.ttf"); +} +@font-face { + font-family: "Linux Libertine"; + font-style: italic; + font-weight: 600; + src: local("Linux Libertine Semibold Italic"), url("../font/LinLibertine_RZIah.ttf"); +} +@font-face { + font-family: "Linux Libertine"; + font-style: italic; + font-weight: 700; + src: local("Linux Libertine Bold Italic"), url("../font/LinLibertine_RBIah.ttf"); +} html { font-size: 12pt; font-family: "Linux Libertine", "Times New Roman", Times, serif; @@ -160,7 +162,7 @@ body { display: grid; padding: 2em; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { body { grid-template-columns: 2fr 3fr 2fr; height: 100%; @@ -180,7 +182,7 @@ main, article { font-size: 1rem; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { main, article { grid-row: 2; @@ -195,7 +197,7 @@ article .gba-portrait { height: auto; max-width: 192px; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { main .gba-portrait, article .gba-portrait { float: right; diff --git a/src/css/global.css.map b/src/css/global.css.map index 6432384..cadb63b 100644 --- a/src/css/global.css.map +++ b/src/css/global.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/_colors.scss","../scss/_fonts.scss","../scss/_classes.scss","../scss/_vars.scss","../scss/global.scss","../scss/_mixins.scss"],"names":[],"mappings":"AACA;;AAAA;AAAA;;AAAA;AAOA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACRA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAaA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;ACxDF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAGF;AAAA;AAAA;EAGE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AChFJ;AAAA;AAAA;AAAA;AAAA;AAMA;AAGA;ACHA;EAEI,WDEa;ECDb,aDEe;;;ACEnB;EACE;EACA;;ACCA;EDHF;IAII;IACA;IACA;;EAEA;IACE;IACA;;EAGF;IACE;IACA;;;;AAKN;AAAA;EAEE;;ACnBA;EDiBF;AAAA;IAII;IACA;;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;;AC9BF;EDyBA;AAAA;IAOI;IACA;;;;AAKN;EACE;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA","file":"global.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/global.scss","../scss/_classes.scss","../scss/_vars.scss","../scss/_colors.scss","../scss/_fonts.scss","../scss/include/_include-media.scss"],"names":[],"mappings":"AAEA;ACFA;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAGF;AAAA;AAAA;EAGE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AChFJ;AAAA;AAAA;AAAA;AAAA;AAMA;AAGA;AAGA;ACXA;;AAAA;AAAA;;AAAA;AAOA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACRA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAaA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AJnCF;EAEI,WEVa;EFWb,aEVe;;;AFcnB;EACE;EACA;;AKmkBE;ELrkBJ;IAII;IACA;IACA;;EAEA;IACE;IACA;;EAGF;IACE;IACA;;;;AAKN;AAAA;EAEE;;AK+iBE;ELjjBJ;AAAA;IAII;IACA;;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;;AKoiBA;ELziBF;AAAA;IAOI;IACA;;;;AAKN;EACE;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA","file":"global.css"} \ No newline at end of file diff --git a/src/css/landing.css b/src/css/landing.css index 6ab2a27..8248633 100644 --- a/src/css/landing.css +++ b/src/css/landing.css @@ -1,4 +1,83 @@ /* IMPORTS ================================================================= */ +.markup { + word-wrap: break-word; + line-height: 1.7; + padding: 0 1.5em; +} +.markup p, +.markup blockquote, +.markup ul, +.markup ol, +.markup dl, +.markup table, +.markup pre { + margin: 1em 0; +} +.markup ul, +.markup ol { + all: revert; + padding-left: 30px; +} +.markup h1 { + font-size: 2.5em; +} +.markup h2 { + font-size: 2em; +} +.markup h3 { + font-size: 1.5em; +} +.markup h4 { + font-size: 1.2em; +} +.markup h5 { + font-size: 1em; +} +.markup h6 { + font-size: 1em; +} +.markup h1, +.markup h2, +.markup h3, +.markup h4, +.markup h5, +.markup h6 { + margin: 0.5em 0 0.25em 0; +} +.markup h1 + p, +.markup h2 + p, +.markup h3 + p { + margin-top: 0.5em; +} +.markup img { + max-width: 100%; +} +.markup code, +.markup pre { + background-color: #f8f8f8; + border-radius: 3px; + border: 1px solid #ddd; + font-family: monospace; + font-size: 12px; + margin: 0 2px; + padding: 0 5px; + white-space: pre; +} +.markup pre code { + border: none; + margin: 0; + padding: 0; + white-space: pre; +} + +/****************************************************************************** +_vars.scss +******************************************************************************* +Global variables for the entire website +============================================================================ */ +/* MEDIA BREAKPOINTS ======================================================= */ +/* SPACING ================================================================= */ +/* FONT SIZING ============================================================= */ /* COLORS @@ -74,85 +153,6 @@ For license text, see: font-weight: 700; src: local("Linux Libertine Bold Italic"), url("../font/LinLibertine_RBIah.ttf"); } -.markup { - word-wrap: break-word; - line-height: 1.7; - padding: 0 1.5em; -} -.markup p, -.markup blockquote, -.markup ul, -.markup ol, -.markup dl, -.markup table, -.markup pre { - margin: 1em 0; -} -.markup ul, -.markup ol { - all: revert; - padding-left: 30px; -} -.markup h1 { - font-size: 2.5em; -} -.markup h2 { - font-size: 2em; -} -.markup h3 { - font-size: 1.5em; -} -.markup h4 { - font-size: 1.2em; -} -.markup h5 { - font-size: 1em; -} -.markup h6 { - font-size: 1em; -} -.markup h1, -.markup h2, -.markup h3, -.markup h4, -.markup h5, -.markup h6 { - margin: 0.5em 0 0.25em 0; -} -.markup h1 + p, -.markup h2 + p, -.markup h3 + p { - margin-top: 0.5em; -} -.markup img { - max-width: 100%; -} -.markup code, -.markup pre { - background-color: #f8f8f8; - border-radius: 3px; - border: 1px solid #ddd; - font-family: monospace; - font-size: 12px; - margin: 0 2px; - padding: 0 5px; - white-space: pre; -} -.markup pre code { - border: none; - margin: 0; - padding: 0; - white-space: pre; -} - -/* IMPORTS ================================================================= */ -/****************************************************************************** -_vars.scss -******************************************************************************* -Global variables for the entire website -============================================================================ */ -/* SPACING ================================================================= */ -/* FONT SIZING ============================================================= */ html { font-size: 12pt; font-family: "Linux Libertine", "Times New Roman", Times, serif; @@ -162,7 +162,7 @@ body { display: grid; padding: 2em; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { body { grid-template-columns: 2fr 3fr 2fr; gap: 1em; @@ -179,7 +179,7 @@ nav { font-size: 1.5em; font-weight: bold; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { nav { grid-column: 2; } @@ -192,7 +192,7 @@ nav a::after { font-style: normal; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { main { grid-row: 2; grid-column: 2; @@ -212,7 +212,7 @@ aside { grid-column: 1; max-width: 192px; } -@media screen and (min-width: 768px) { +@media (min-width: 769px) { aside { grid-column: 2; } diff --git a/src/css/landing.css.map b/src/css/landing.css.map index 37b115b..3379af6 100644 --- a/src/css/landing.css.map +++ b/src/css/landing.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/landing.scss","../scss/_colors.scss","../scss/_fonts.scss","../scss/_classes.scss","../scss/_vars.scss","../scss/_mixins.scss"],"names":[],"mappings":"AAEA;ACDA;;AAAA;AAAA;;AAAA;AAOA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACRA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAaA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;ACxDF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAGF;AAAA;AAAA;EAGE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AH9EJ;AIFA;AAAA;AAAA;AAAA;AAAA;AAMA;AAGA;AJEA;EAEI,WIHa;EJIb,aIHe;;;AJOnB;EACE;EACA;;AKJA;ELEF;IAII;IACA,KIhBK;IJiBL;IACA;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AKnBA;ELaF;IAQI;;;AAIA;EACE;;AAGF;EACE;EACA;;;AK/BJ;ELoCF;IAEI;IACA;IACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;;AKxDA;ELqDF;IAKI;;;AAGF;EACE","file":"landing.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/landing.scss","../scss/_classes.scss","../scss/_vars.scss","../scss/_colors.scss","../scss/_fonts.scss","../scss/include/_include-media.scss"],"names":[],"mappings":"AAEA;ACFA;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAGF;AAAA;AAAA;EAGE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AChFJ;AAAA;AAAA;AAAA;AAAA;AAMA;AAGA;AAGA;ACXA;;AAAA;AAAA;;AAAA;AAOA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACRA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAaA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AJnCF;EAEI,WEVa;EFWb,aEVe;;;AFcnB;EACE;EACA;;AKmkBE;ELrkBJ;IAII;IACA,KEvBK;IFwBL;IACA;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AKojBE;EL1jBJ;IAQI;;;AAIA;EACE;;AAGF;EACE;EACA;;;AKwiBF;ELniBJ;IAEI;IACA;IACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;;AK+gBE;ELlhBJ;IAKI;;;AAGF;EACE","file":"landing.css"} \ No newline at end of file diff --git a/src/posts/index.md b/src/posts/index.md new file mode 100644 index 0000000..dc5a8b1 --- /dev/null +++ b/src/posts/index.md @@ -0,0 +1,15 @@ +--- +title: Blog +permalink: /blog/ +override:tags: [] +eleventyNavigation: + key: Blog + order: 2 +--- + +{%- for post in collections.blog reversed -%} + {% if forloop.first == true %}{% endif %} +{%- endfor -%} diff --git a/src/posts/posts.json b/src/posts/posts.json new file mode 100644 index 0000000..c2b5ea8 --- /dev/null +++ b/src/posts/posts.json @@ -0,0 +1,3 @@ +{ + "tags": "blog" +} \ No newline at end of file diff --git a/src/scss/_colors.scss b/src/scss/_colors.scss index e04f830..8b3c8e0 100644 --- a/src/scss/_colors.scss +++ b/src/scss/_colors.scss @@ -1,68 +1,4 @@ -// src/scss/_colors.scss -/* - -COLORS -=============================================================================== - -*/ - -/* -Flexoki (https://stephango.com/flexoki) -MIT License - -Copyright (c) 2023 Steph Ango - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -$paper: rgb(255, 252, 240); -$base-50: rgb(242, 240, 229); -$base-100: rgb(230, 228, 217); -$base-150: rgb(218, 216, 206); -$base-200: rgb(206, 205, 195); -$base-300: rgb(183, 181, 172); -$base-500: rgb(135, 133, 128); -$base-600: rgb(111, 110, 105); -$base-700: rgb(87, 86, 83); -$base-800: rgb(64, 62, 60); -$base-850: rgb(52, 51, 49); -$base-900: rgb(40, 39, 38); -$base-950: rgb(28, 27, 26); -$black: rgb(16, 15, 15); - -$red-400: rgb(209, 77, 65); -$red-600: rgb(175, 48, 41); -$orange-400: rgb(218, 112, 44); -$orange-600: rgb(188, 82, 21); -$yellow-400: rgb(208, 162, 21); -$yellow-600: rgb(173, 131, 1); -$green-400: rgb(135, 154, 57); -$green-600: rgb(102, 128, 11); -$cyan-400: rgb(58, 169, 159); -$cyan-600: rgb(36, 131, 123); -$blue-400: rgb(67, 133, 190); -$blue-600: rgb(32, 94, 166); -$purple-400: rgb(139, 126, 200); -$purple-600: rgb(94, 64, 157); -$magenta-400: rgb(206, 93, 151); -$magenta-600: rgb(160, 47, 111); - -//----------------------------------------------------------------------------- +// _colors.scss $background: #141013; $text: $paper; diff --git a/src/scss/_fonts.scss b/src/scss/_fonts.scss index 574c550..d6e0517 100644 --- a/src/scss/_fonts.scss +++ b/src/scss/_fonts.scss @@ -1,14 +1,17 @@ -/* +// _fonts.scss +/* ============================================================================ +FONT SOURCES +============================================================================ */ -FONT: LINUX LIBERTINE -=============================================================================== -License: GPL and OFL 1.1 +/* Linux Libertine ------------------------------------------------------------ -For license text, see: +Licensed under GPL and OFL 1.1 + +Full license texts: - https://gils.nexus/font/GPL.txt - https://gils.nexus/font/OFL-1.1.txt -*/ +---------------------------------------------------------------------------- */ // Normal @font-face { diff --git a/src/scss/_mixins.scss b/src/scss/_mixins.scss deleted file mode 100644 index 6054d77..0000000 --- a/src/scss/_mixins.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use "colors"; - -$breakpoints: ( - "sm": 600px, - "md": 768px, - "lg": 992px, - "xl": 1200px, -); - -@mixin breakpoint($mq-breakpoint, $mq-breakpoints: $breakpoints) { - // If $mq-breakpoint is a key that exists in $mq-breakpoints, get and use the value - @if map-has-key($mq-breakpoints, $mq-breakpoint) { - $mq-breakpoint: map-get($mq-breakpoints, $mq-breakpoint); - } - - // Place everything inside this mixin under the appropriate @media rule - @media screen and (min-width: #{$mq-breakpoint}) { - @content; - } -} diff --git a/src/scss/_vars.scss b/src/scss/_vars.scss index dc918b2..bf0558e 100644 --- a/src/scss/_vars.scss +++ b/src/scss/_vars.scss @@ -1,12 +1,17 @@ -/****************************************************************************** -_vars.scss -******************************************************************************* -Global variables for the entire website +// _vars.scss +/* ============================================================================ +GLOBAL VARIABLES ============================================================================ */ -/* SPACING ================================================================= */ +/* Media breakpoints ------------------------------------------------------- */ + + +/* Spacing ----------------------------------------------------------------- */ $gutter: 1em; -/* FONT SIZING ============================================================= */ +/* Typography -------------------------------------------------------------- */ +$leading: 1.7; + +/* -- Font ----------------------------------------------------------------- */ $font-base-size: 12pt; $font-stack-serif: "Linux Libertine", "Times New Roman", Times, serif; diff --git a/src/scss/global.scss b/src/scss/global.scss index bc2474c..bf04b54 100644 --- a/src/scss/global.scss +++ b/src/scss/global.scss @@ -1,8 +1,22 @@ -@use "colors"; -@use "fonts"; -@use "mixins" as *; +// global.scss + +/* IMPORTS ================================================================= */ +@use "sass:math"; + +@use "modules/include-media" as * with ( + $breakpoints: ( + xs: 0, + sm: 640px, + md: 768px, + lg: 1024px, + xl: 1280px, + 2xl: 1536px, + ) +); + @use "classes" as *; @use "vars" as *; +@use "fonts"; html { font: { @@ -14,7 +28,7 @@ html { body { display: grid; padding: $gutter * 2; - @include breakpoint("md") { + @include media(">md") { grid-template-columns: 2fr 3fr 2fr; height: 100%; padding: ($gutter * 2) 0; @@ -34,7 +48,7 @@ body { main, article { font-size: 1rem; - @include breakpoint("md") { + @include media(">md") { grid-row: 2; grid-column: 2; } @@ -45,7 +59,7 @@ article { width: 100%; height: auto; max-width: 192px; - @include breakpoint("md") { + @include media(">md") { float: right; margin: 1em; } diff --git a/src/scss/landing.scss b/src/scss/landing.scss index 6317b55..cda27b1 100644 --- a/src/scss/landing.scss +++ b/src/scss/landing.scss @@ -2,12 +2,22 @@ /* IMPORTS ================================================================= */ @use "sass:math"; -@use "colors"; -@use "fonts"; + +@use "modules/include-media" as * with ( + $breakpoints: ( + xs: 0, + sm: 640px, + md: 768px, + lg: 1024px, + xl: 1280px, + 2xl: 1536px, + ) +); @use "classes" as *; -@use "mixins" as *; @use "vars" as *; +@use "colors"; +@use "fonts"; html { font: { @@ -19,7 +29,7 @@ html { body { display: grid; padding: $gutter * 2; - @include breakpoint("md") { + @include media(">md") { grid-template-columns: 2fr 3fr 2fr; gap: $gutter; height: 100%; @@ -34,7 +44,7 @@ nav { align-self: end; font-size: 1.5em; font-weight: bold; - @include breakpoint("md") { + @include media(">md") { grid-column: 2; } @@ -51,7 +61,7 @@ nav { } main { - @include breakpoint("md") { + @include media(">md") { grid-row: 2; grid-column: 2; justify-self: center; @@ -71,7 +81,7 @@ aside { grid-row: 1; grid-column: 1; max-width: 192px; - @include breakpoint("md") { + @include media(">md") { grid-column: 2; } diff --git a/src/scss/modules/_include-media.scss b/src/scss/modules/_include-media.scss new file mode 100644 index 0000000..e073757 --- /dev/null +++ b/src/scss/modules/_include-media.scss @@ -0,0 +1,618 @@ +// _ _ _ _ _ +// (_) | | | | | (_) +// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _ +// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` | +// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| | +// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_| +// +// Simple, elegant and maintainable media queries in Sass +// v2.0.0 +// +// https://eduardoboucas.github.io/include-media +// +// Authors: Eduardo Boucas (@eduardoboucas) +// Kitty Giraudel (@kittygiraudel) +// +// This project is licensed under the terms of the MIT license +@charset "UTF-8"; + +//// +/// include-media library public configuration +/// @author Eduardo Boucas +/// @access public +//// +@use 'sass:math'; +@use 'sass:map'; +@use 'sass:list'; +@use 'sass:string'; +@use 'sass:meta'; + +/// +/// Creates a list of global breakpoints +/// +/// @example scss - Creates a single breakpoint with the label `phone` +/// $breakpoints: ('phone': 320px); +/// +$breakpoints: ( + 'phone': 320px, + 'tablet': 768px, + 'desktop': 1024px, +) !default; + +/// +/// Creates a list of static expressions or media types +/// +/// @example scss - Creates a single media type (screen) +/// $media-expressions: ('screen': 'screen'); +/// +/// @example scss - Creates a static expression with logical disjunction (OR operator) +/// $media-expressions: ( +/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)' +/// ); +/// +$media-expressions: ( + 'screen': 'screen', + 'print': 'print', + 'handheld': 'handheld', + 'landscape': '(orientation: landscape)', + 'portrait': '(orientation: portrait)', + 'retina2x': + '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)', + 'retina3x': + '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)', +) !default; + +/// +/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals +/// +/// @example scss - Interval for pixels is defined as `1` by default +/// @include media('>128px') {} +/// +/// /* Generates: */ +/// @media (min-width: 129px) {} +/// +/// @example scss - Interval for ems is defined as `0.01` by default +/// @include media('>20em') {} +/// +/// /* Generates: */ +/// @media (min-width: 20.01em) {} +/// +/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;` +/// @include media('>2.0rem') {} +/// +/// /* Generates: */ +/// @media (min-width: 2.1rem) {} +/// +$unit-intervals: ( + 'px': 1, + 'em': 0.01, + 'rem': 0.1, + '': 0, +) !default; + +/// +/// Defines whether support for media queries is available, useful for creating separate stylesheets +/// for browsers that don't support media queries. +/// +/// @example scss - Disables support for media queries +/// $im-media-support: false; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +$im-media-support: true !default; + +/// +/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or +/// intercept the breakpoint will be displayed, any others will be ignored. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'tablet'; +/// @include media('>=desktop') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output */ +/// +$im-no-media-breakpoint: 'desktop' !default; + +/// +/// Selects which media expressions are allowed in an expression for it to be used when media queries +/// are not supported. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'screen') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'retina2x') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output */ +/// +$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; + +//// +/// Cross-engine logging engine +/// @author Kitty Giraudel +/// @access private +//// + +/// +/// Log a message either with `@error` if supported +/// else with `@warn`, using `feature-exists('at-error')` +/// to detect support. +/// +/// @param {String} $message - Message to log +/// +@function im-log($message) { + @if meta.feature-exists('at-error') { + @error $message; + } @else { + @warn $message; + $_: noop(); + } + + @return $message; +} + +/// +/// Wrapper mixin for the log function so it can be used with a more friendly +/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function +/// within functions because it is not possible to include a mixin in a function +/// and use the mixin everywhere else because it's much more elegant. +/// +/// @param {String} $message - Message to log +/// +@mixin log($message) { + @if im-log($message) { + } +} + +/// +/// Function with no `@return` called next to `@warn` in Sass 3.3 +/// to trigger a compiling error and stop the process. +/// +@function noop() { +} + +/// +/// Determines whether a list of conditions is intercepted by the static breakpoint. +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint +/// +@function im-intercepts-static-breakpoint($conditions...) { + $no-media-breakpoint-value: map.get($breakpoints, $im-no-media-breakpoint); + + @if not $no-media-breakpoint-value { + @if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') { + } + } + + @each $condition in $conditions { + @if not map.has-key($media-expressions, $condition) { + $operator: get-expression-operator($condition); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($condition, $operator); + + @if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or + ($prefix == 'min' and $value > $no-media-breakpoint-value) + { + @return false; + } + } @else if not list.index($im-no-media-expressions, $condition) { + @return false; + } + } + + @return true; +} + +//// +/// Parsing engine +/// @author Kitty Giraudel +/// @access private +//// + +/// +/// Get operator of an expression +/// +/// @param {String} $expression - Expression to extract operator from +/// +/// @return {String} - Any of `>=`, `>`, `<=`, `<`, `≥`, `≤` +/// +@function get-expression-operator($expression) { + @each $operator in ('>=', '>', '<=', '<', '≥', '≤') { + @if string.index($expression, $operator) { + @return $operator; + } + } + + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log('No operator found in `#{$expression}`.'); +} + +/// +/// Get dimension of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract dimension from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {String} - `width` or `height` (or potentially anything else) +/// +@function get-expression-dimension($expression, $operator) { + $operator-index: string.index($expression, $operator); + $parsed-dimension: string.slice($expression, 0, $operator-index - 1); + $parsed-dimension: str-trim($parsed-dimension); + $dimension: 'width'; + + @if string.length($parsed-dimension) > 0 { + $dimension: $parsed-dimension; + } + + @return $dimension; +} + +/// +/// Get dimension prefix based on an operator +/// +/// @param {String} $operator - Operator +/// +/// @return {String} - `min` or `max` +/// +@function get-expression-prefix($operator) { + @return if(list.index(('<', '<=', '≤'), $operator), 'max', 'min'); +} + +/// +/// Get value of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract value from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {Number} - A numeric value +/// +@function get-expression-value($expression, $operator) { + $operator-index: string.index($expression, $operator); + $value: string.slice($expression, $operator-index + string.length($operator)); + $trimmedValue: str-trim($value); + + @if map.has-key($breakpoints, $trimmedValue) { + $value: map.get($breakpoints, $trimmedValue); + } @else { + $value: to-number($trimmedValue); + } + + $interval: map.get($unit-intervals, math.unit($value)); + + @if not $interval { + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log('Unknown unit `#{math.unit($value)}`.'); + } + + @if $operator == '>' { + $value: $value + $interval; + } @else if $operator == '<' { + $value: $value - $interval; + } + + @return $value; +} + +/// +/// Parse an expression to return a valid media-query expression +/// +/// @param {String} $expression - Expression to parse +/// +/// @return {String} - Valid media query +/// +@function parse-expression($expression) { + // If it is part of $media-expressions, it has no operator + // then there is no need to go any further, just return the value + @if map.has-key($media-expressions, $expression) { + @return map.get($media-expressions, $expression); + } + + $operator: get-expression-operator($expression); + $dimension: get-expression-dimension($expression, $operator); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($expression, $operator); + + @return '(#{$prefix}-#{$dimension}: #{$value})'; +} + +/// +/// Slice `$list` between `$start` and `$end` indexes +/// +/// @access private +/// +/// @param {List} $list - List to slice +/// @param {Number} $start [1] - Start index +/// @param {Number} $end [length($list)] - End index +/// +/// @return {List} Sliced list +/// +@function slice($list, $start: 1, $end: list.length($list)) { + @if list.length($list) < 1 or $start > $end { + @return (); + } + + $result: (); + + @for $i from $start through $end { + $result: list.append($result, list.nth($list, $i), comma); + } + + @return $result; +} + +//// +/// String to number converter +/// @author Kitty Giraudel +/// @access private +//// + +/// +/// Casts a string into a number +/// +/// @param {String | Number} $value - Value to be parsed +/// +/// @return {Number} +/// + +@function to-number($value) { + @if meta.type-of($value) == 'number' { + @return $value; + } @else if meta.type-of($value) != 'string' { + $_: im-log('Value for `to-number` should be a number or a string.'); + } + + $first-character: string.slice($value, 1, 1); + $result: 0; + $digits: 0; + $minus: ($first-character == '-'); + $numbers: ( + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + '6': 6, + '7': 7, + '8': 8, + '9': 9, + ); + + // Remove +/- sign if present at first character + @if ($first-character == '+' or $first-character == '-') { + $value: string.slice($value, 2); + } + + @for $i from 1 through string.length($value) { + $character: string.slice($value, $i, $i); + + @if not(list.index(map.keys($numbers), $character) or $character == '.') { + @return to-length(if($minus, -$result, $result), string.slice($value, $i)); + } + + @if $character == '.' { + $digits: 1; + } @else if $digits == 0 { + $result: $result * 10 + map.get($numbers, $character); + } @else { + $digits: $digits * 10; + $result: $result + math.div(map.get($numbers, $character), $digits); + } + } + + @return if($minus, -$result, $result); +} + +/// +/// Add `$unit` to `$value` +/// +/// @param {Number} $value - Value to add unit to +/// @param {String} $unit - String representation of the unit +/// +/// @return {Number} - `$value` expressed in `$unit` +/// +@function to-length($value, $unit) { + $units: ( + 'px': 1px, + 'cm': 1cm, + 'mm': 1mm, + '%': 1%, + 'ch': 1ch, + 'pc': 1pc, + 'in': 1in, + 'em': 1em, + 'rem': 1rem, + 'pt': 1pt, + 'ex': 1ex, + 'vw': 1vw, + 'vh': 1vh, + 'vmin': 1vmin, + 'vmax': 1vmax, + ); + + @if not list.index(map.keys($units), $unit) { + $_: im-log('Invalid unit `#{$unit}`.'); + } + + @return $value * map.get($units, $unit); +} + +//// +/// String to number converter +/// @author Jack McNicol +/// @access private +//// + +/// +/// Trims a string of leading and trailing spaces +/// +/// @param {String} $string - Value to be trimmed +/// +/// @return {String} +/// + +@function str-trim($string) { + @if (str-slice($string, 1, 1) == ' ') { + @return str-trim(str-slice($string, 2)); + } @else if (str-slice($string, str-length($string), -1) == ' ') { + @return str-trim(str-slice($string, 1, -2)); + } @else { + @return $string; + } +} + +/// +/// This mixin aims at redefining the configuration just for the scope of +/// the call. It is helpful when having a component needing an extended +/// configuration such as custom breakpoints (referred to as tweakpoints) +/// for instance. +/// +/// @author Kitty Giraudel +/// +/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints` +/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression` +/// +/// @example scss - Extend the global breakpoints with a tweakpoint +/// @include media-context(('custom': 678px)) { +/// .foo { +/// @include media('>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend the global media expressions with a custom one +/// @include media-context($tweak-media-expressions: ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend both configuration maps +/// @include media-context(('custom': 678px), ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) { + // Save global configuration + $global-breakpoints: $breakpoints; + $global-media-expressions: $media-expressions; + + // Update global configuration + $breakpoints: map.merge($breakpoints, $tweakpoints) !global; + $media-expressions: map.merge($media-expressions, $tweak-media-expressions) !global; + + @content; + + // Restore global configuration + $breakpoints: $global-breakpoints !global; + $media-expressions: $global-media-expressions !global; +} + +//// +/// include-media public exposed API +/// @author Eduardo Boucas +/// @access public +//// + +/// +/// Generates a media query based on a list of conditions +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @example scss - With a single set breakpoint +/// @include media('>phone') { } +/// +/// @example scss - With two set breakpoints +/// @include media('>phone', '<=tablet') { } +/// +/// @example scss - With custom values +/// @include media('>=358px', '<850px') { } +/// +/// @example scss - With set breakpoints with custom values +/// @include media('>desktop', '<=1350px') { } +/// +/// @example scss - With a static expression +/// @include media('retina2x') { } +/// +/// @example scss - Mixing everything +/// @include media('>=350px', ' 0) { + @media #{string.unquote(parse-expression(list.nth($conditions, 1)))} { + // Recursive call + $sliced-conditions: slice($conditions, 2); + @include media($sliced-conditions...) { + @content; + } + } + } +}