aboutsummaryrefslogtreecommitdiffstats
path: root/htdocs/src/scss/abstracts
diff options
context:
space:
mode:
Diffstat (limited to 'htdocs/src/scss/abstracts')
-rw-r--r--htdocs/src/scss/abstracts/_functions.scss4
-rw-r--r--htdocs/src/scss/abstracts/_mixins.scss2
-rw-r--r--htdocs/src/scss/abstracts/_placeholders.scss32
-rw-r--r--htdocs/src/scss/abstracts/_variables.scss137
-rw-r--r--htdocs/src/scss/abstracts/functions/_convert.scss16
-rw-r--r--htdocs/src/scss/abstracts/functions/_css-vars.scss8
-rw-r--r--htdocs/src/scss/abstracts/functions/_encode.scss14
-rw-r--r--htdocs/src/scss/abstracts/functions/_str-replace.scss20
-rw-r--r--htdocs/src/scss/abstracts/mixins/_css-vars.scss20
-rw-r--r--htdocs/src/scss/abstracts/mixins/_media-queries.scss81
10 files changed, 334 insertions, 0 deletions
diff --git a/htdocs/src/scss/abstracts/_functions.scss b/htdocs/src/scss/abstracts/_functions.scss
new file mode 100644
index 0000000..672e5e7
--- /dev/null
+++ b/htdocs/src/scss/abstracts/_functions.scss
@@ -0,0 +1,4 @@
+@forward "./functions/convert";
+@forward "./functions/css-vars";
+@forward "./functions/str-replace";
+@forward "./functions/encode";
diff --git a/htdocs/src/scss/abstracts/_mixins.scss b/htdocs/src/scss/abstracts/_mixins.scss
new file mode 100644
index 0000000..fd28631
--- /dev/null
+++ b/htdocs/src/scss/abstracts/_mixins.scss
@@ -0,0 +1,2 @@
+@forward "./mixins/css-vars";
+@forward "./mixins/media-queries";
diff --git a/htdocs/src/scss/abstracts/_placeholders.scss b/htdocs/src/scss/abstracts/_placeholders.scss
new file mode 100644
index 0000000..079cae7
--- /dev/null
+++ b/htdocs/src/scss/abstracts/_placeholders.scss
@@ -0,0 +1,32 @@
+/// List Reset
+%reset-list {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ margin-bottom: 0;
+ }
+}
+
+/// Ordered List Reset
+%reset-ordered-list {
+ @extend %reset-list;
+
+ li {
+ counter-increment: none;
+ display: list-item;
+
+ &::before {
+ display: none;
+ }
+ }
+}
+
+/// Display an inline list with flexbox
+%flex-list {
+ @extend %reset-list;
+
+ display: flex;
+ flex-flow: row wrap;
+}
diff --git a/htdocs/src/scss/abstracts/_variables.scss b/htdocs/src/scss/abstracts/_variables.scss
new file mode 100644
index 0000000..a891bed
--- /dev/null
+++ b/htdocs/src/scss/abstracts/_variables.scss
@@ -0,0 +1,137 @@
+@use "sass:math";
+@use "../abstracts/functions" as fun;
+
+//===========================================================================
+// Ratios
+//===========================================================================
+
+/// Ratios map
+/// @prop {String} keys - Keys are identifiers mapped to a given ratio
+/// @prop {Map} value - Value is actual ratio
+$ratios: (
+ "minor-second": 1.067,
+ "major-second": 1.125,
+ "minor-third": 1.2,
+ "major-third": 1.25,
+ "perfect-fourth": 1.333,
+ "augmented-fourth": 1.414,
+ "perfect-fifth": 1.5,
+ "golden-number": 1.618,
+);
+
+// Cannot declare the following function in partials due to module loop.
+// Also, it will only be used in this file so it is not a problem.
+
+/// Get ratio
+/// @param {String} $name - Ratio name.
+/// @return {Integer} The ratio value.
+@function get-ratio($name) {
+ @return map-get($ratios, $name);
+}
+
+//===========================================================================
+// Layout
+//===========================================================================
+
+/// Breakpoints map
+/// @prop {String} keys - Keys are identifiers mapped to a given length
+/// @prop {Map} values - Values are actual breakpoints expressed in pixels
+$breakpoints: (
+ "xs": fun.convert-px(568, "em"),
+ "sm": fun.convert-px(768, "em"),
+ "md": fun.convert-px(1024, "em"),
+ "lg": fun.convert-px(1200, "em"),
+ "xl": fun.convert-px(1600, "em"),
+ "2xl": fun.convert-px(1920, "em"),
+);
+
+//===========================================================================
+// Fonts
+//===========================================================================
+
+/* stylelint-disable -- Fonts name are not keywords, lowercase is not needed. */
+/// Regular font family
+/// @type List
+$font-family_primary: ("Inter", "Liberation Sans", Arial, sans-serif);
+
+/// Alternative regular font family
+/// @type List
+$font-family_secondary: ("Kanit", "Liberation Sans", Arial, sans-serif);
+
+/// Monospace font family
+/// @type List
+$font-family_mono: (
+ "Cousine",
+ "Liberation Mono",
+ "DejaVu Sans Mono",
+ "Courier New",
+ monospace
+);
+/* stylelint-enable */
+
+$line-height: get-ratio("golden-number");
+
+$font-size_base: 16px;
+$font-size_base-rem: fun.convert-px(16); // font-size_base without unit
+$font-size_ratio: get-ratio("minor-third");
+$font-size_sm: $font-size_base-rem * math.pow($font-size_ratio, -1);
+$font-size_md: $font-size_base-rem * math.pow($font-size_ratio, 0);
+$font-size_lg: $font-size_base-rem * math.pow($font-size_ratio, 1);
+$font-size_xl: $font-size_base-rem * math.pow($font-size_ratio, 2);
+$font-size_2xl: $font-size_base-rem * math.pow($font-size_ratio, 3);
+$font-size_3xl: $font-size_base-rem * math.pow($font-size_ratio, 4);
+$font-size_4xl: $font-size_base-rem * math.pow($font-size_ratio, 5);
+$font-size_5xl: $font-size_base-rem * math.pow($font-size_ratio, 6);
+
+//============================================================================
+// Spacings
+//============================================================================
+
+$spacing_ratio: get-ratio("golden-number");
+$spacing_base: $spacing_ratio * 1rem;
+
+$spacing_3xs: math.div($spacing_base, 4);
+$spacing_2xs: math.div($spacing_base, 3);
+$spacing_xs: math.div($spacing_base, 2);
+$spacing_sm: math.div($spacing_base, 1.5);
+$spacing_md: $spacing_base;
+$spacing_lg: $spacing_base * 1.5;
+$spacing_xl: $spacing_base * 2;
+$spacing_2xl: $spacing_base * 3;
+$spacing_3xl: $spacing_base * 4;
+
+//============================================================================
+// Colors
+//============================================================================
+
+$color_black-squeeze: hsl(212, 55%, 97%);
+$color_black-squeeze-opacity-80: hsla(212, 55%, 97%, 0.8);
+$color_catskill-white: hsl(212, 53%, 92%);
+$color_link-water: hsl(212, 51%, 87%);
+$color_geyser: hsl(212, 27%, 83%);
+$color_gull-gray: hsl(212, 15%, 66%);
+$color_gull-gray-opacity: hsla(212, 15%, 66%, 0.55);
+$color_pale-sky: hsl(212, 13%, 46%);
+$color_fiord: hsl(212, 29%, 35%);
+$color_rhino: hsl(212, 33%, 28%);
+$color_cloud-burst: hsl(211, 36%, 12%);
+$color_mirage: hsl(211, 36%, 14%);
+$color_nile-blue: hsl(212, 47%, 19%);
+$color_big-stone: hsl(212, 45%, 15%);
+$color_firefly: hsl(212, 45%, 11%);
+$color_firefly-opacity-80: hsla(212, 45%, 11%, 0.8);
+$color_chambray: hsl(212, 45%, 40%);
+$color_chathams-blue: hsl(212, 65%, 28%);
+$color_chathams-blue-light: hsl(212, 90%, 30%);
+$color_chathams-blue-light-opacity-25: hsla(212, 90%, 30%, 0.25);
+$color_chathams-blue-dark: hsl(212, 70%, 25%);
+$color_russet: hsl(23, 65%, 31%);
+$color_russet-opacity-25: hsla(23, 65%, 31%, 0.25);
+$color_horizon: hsl(213, 30%, 54%);
+$color_kashmir-blue: hsl(212, 30%, 46%);
+$color_spindle: hsl(212, 56%, 75%);
+$color_spindle-light: hsl(212, 52%, 78%);
+$color_spindle-light-opacity-35: hsla(212, 52%, 78%, 0.35);
+$color_spindle-dark: hsl(213, 60%, 72%);
+$color_brandy: hsl(37, 51%, 74%);
+$color_brandy-opacity-40: hsla(37, 51%, 74%, 0.4);
diff --git a/htdocs/src/scss/abstracts/functions/_convert.scss b/htdocs/src/scss/abstracts/functions/_convert.scss
new file mode 100644
index 0000000..9f51dc7
--- /dev/null
+++ b/htdocs/src/scss/abstracts/functions/_convert.scss
@@ -0,0 +1,16 @@
+@use "sass:math";
+
+/// Convert px to rem or em.
+/// @param {Number} $px Value in px
+/// @param {String} $to Unit. Either "rem" or "em"
+/// @param {Number} $standard 1rem (or 1em) = 16px
+/// @return {Number} Value in rem or em
+@function convert-px($px, $to: "rem", $standard: 16) {
+ @if $to == "rem" {
+ @return math.div($px, $standard) + 0rem; // stylelint-disable-line
+ } @else if $to == "em" {
+ @return math.div($px, $standard) + 0em; // stylelint-disable-line
+ } @else {
+ @error "`$to` must be either `rem` or `em`.";
+ }
+}
diff --git a/htdocs/src/scss/abstracts/functions/_css-vars.scss b/htdocs/src/scss/abstracts/functions/_css-vars.scss
new file mode 100644
index 0000000..89e1a15
--- /dev/null
+++ b/htdocs/src/scss/abstracts/functions/_css-vars.scss
@@ -0,0 +1,8 @@
+/// Retrieve a CSS variable value with prefix
+/// @see https://dev.to/felipperegazio/css-custom-properties-vars-with-sass-scss-a-practical-architecture-strategy-1m88
+/// @param {String} $name Variable name
+/// @param {String} $prefix Variable prefix
+/// @return {String} Variable in CSS format
+@function get-var($name, $prefix: dap) {
+ @return var(--#{$prefix}-#{$name});
+}
diff --git a/htdocs/src/scss/abstracts/functions/_encode.scss b/htdocs/src/scss/abstracts/functions/_encode.scss
new file mode 100644
index 0000000..4350185
--- /dev/null
+++ b/htdocs/src/scss/abstracts/functions/_encode.scss
@@ -0,0 +1,14 @@
+@use "str-replace" as fun;
+
+/// Encode a SVG.
+/// @param {String} $svg A complete svg (`<svg>...</svg>`).
+/// @return The encoded svg, ready to use for background-image.
+@function encode-svg($svg) {
+ $svg-encoding: (("<", "%3C"), (">", "%3E"), ("#", "%23"));
+
+ @each $char, $encoded in $svg-encoding {
+ $svg: fun.str-replace($svg, $char, $encoded);
+ }
+
+ @return "data:image/svg+xml;utf8," + $svg;
+}
diff --git a/htdocs/src/scss/abstracts/functions/_str-replace.scss b/htdocs/src/scss/abstracts/functions/_str-replace.scss
new file mode 100644
index 0000000..624bf33
--- /dev/null
+++ b/htdocs/src/scss/abstracts/functions/_str-replace.scss
@@ -0,0 +1,20 @@
+/// Replace `$search` with `$replace` in `$string`
+/// @author Hugo Giraudel
+/// @param {String} $string - Initial string
+/// @param {String} $search - Substring to replace
+/// @param {String} $replace ('') - New value
+/// @return {String} - Updated string
+@function str-replace($string, $search, $replace: "") {
+ $index: str-index($string, $search);
+
+ @if $index {
+ @return str-slice($string, 1, $index - 1) + $replace +
+ str-replace(
+ str-slice($string, $index + str-length($search)),
+ $search,
+ $replace
+ );
+ }
+
+ @return $string;
+}
diff --git a/htdocs/src/scss/abstracts/mixins/_css-vars.scss b/htdocs/src/scss/abstracts/mixins/_css-vars.scss
new file mode 100644
index 0000000..8e31c96
--- /dev/null
+++ b/htdocs/src/scss/abstracts/mixins/_css-vars.scss
@@ -0,0 +1,20 @@
+/// Declare a set of CSS variables properly prefixed.
+///
+/// @see https://dev.to/felipperegazio/css-custom-properties-vars-with-sass-scss-a-practical-architecture-strategy-1m88
+///
+/// @param {List} $variables - A list of variable name and value.
+/// @param {Bool} $root - Set vars at root.
+/// @param {String} $prefix - The variables prefix.
+@mixin set-vars($variables, $root: true, $prefix: "dap") {
+ @if $root {
+ :root {
+ @each $name, $value in $variables {
+ --#{$prefix}-#{$name}: #{$value};
+ }
+ }
+ } @else {
+ @each $name, $value in $variables {
+ --#{$prefix}-#{$name}: #{$value};
+ }
+ }
+}
diff --git a/htdocs/src/scss/abstracts/mixins/_media-queries.scss b/htdocs/src/scss/abstracts/mixins/_media-queries.scss
new file mode 100644
index 0000000..fcaea4b
--- /dev/null
+++ b/htdocs/src/scss/abstracts/mixins/_media-queries.scss
@@ -0,0 +1,81 @@
+@use "../variables" as var;
+
+/// Media query: media type
+/// @param {String} $type - Media type: all, screen, print, retina.
+/// @example scss - `@media only screen` equivalent is:
+/// @include media("screen");
+@mixin media($type) {
+ @if $type == "retina" {
+ $type: "(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)";
+ } @else if $type == "screen" or $type == "print" {
+ $type: "only #{$type}";
+ }
+
+ @media #{$type} {
+ @content;
+ }
+}
+
+/// Media query: min-width / max-width
+/// @param {String} $from - min-width breakpoint.
+/// @param {String} $until - max-width breakpoint.
+/// @example scss - `@media (min-width: "md")` equivalent is:
+/// @include dimensions("md");
+@mixin dimensions($from: null, $until: null) {
+ $query: "";
+
+ @if $from {
+ @if type-of($from) == "string" {
+ $size: map-get(var.$breakpoints, $from);
+ $query: "(min-width: #{$size})";
+ } @else {
+ @error "`$from` must be a string.";
+ }
+ }
+
+ @if $from and $until {
+ $query: $query + " and ";
+ }
+
+ @if $until {
+ @if type-of($until) == "string" {
+ $size: map-get(var.$breakpoints, $until);
+ $size: calc(#{$size} - 1px);
+ $query: $query + "(max-width: #{$size})";
+ } @else {
+ @error "`$until` must be a string.";
+ }
+ }
+
+ @media #{$query} {
+ @content;
+ }
+}
+
+/// Media query: prefers-reduced-motion
+/// @param {String} $value - Media query value: `no-preference` or `reduce`.
+/// @example scss - @media (prefers-reduced-motion: "reduce") equivalent is:
+/// @include motion("reduce");
+@mixin motion($value) {
+ @if $value == "no-preference" or $value == "reduce" {
+ @media (prefers-reduced-motion: #{$value}) {
+ @content;
+ }
+ } @else {
+ @error "Allowed values are `no-preference` and `reduce`.";
+ }
+}
+
+/// Media query: any-pointer
+/// @param {String} $value - Media query value: `fine`, `coarse` or `none`.
+/// @example scss - @media (any-pointer: "fine") equivalent is:
+/// @include pointer("fine");
+@mixin pointer($value) {
+ @if $value == "fine" or $value == "coarse" or $value == "none" {
+ @media (any-pointer: #{$value}) {
+ @content;
+ }
+ } @else {
+ @error "Allowed values are `fine`, `coarse` and `none`.";
+ }
+}