13 Commits
0.2 ... master

Author SHA1 Message Date
Abdelrhman Nile
97a194d962 Update README.md 2021-11-12 06:50:17 +00:00
AbdelrhmanNile
53d8f1f6b3 fixing some colors 2021-11-12 08:45:23 +02:00
Abdelrhman Nile
246a28e493 Update README.md 2021-11-10 18:37:22 +00:00
AbdelrhmanNile
6ca2898a50 README 2021-11-10 20:35:24 +02:00
AbdelrhmanNile
05df302ecd README 2021-11-10 20:29:51 +02:00
AbdelrhmanNile
26320c5909 changing color palette to onedark, replacing bing with brave search engine, changing timezone and weather location 2021-11-10 20:18:01 +02:00
Deepjyoti Barman
8cad9b0d21 Add theming ability for various aspects of the startpage
Add support for theming varisou aspects of the page all from the
config.

Thanks to @benjih for the PR.
2021-04-24 19:27:31 +05:30
Deepjyoti Barman
3661f92c15 Remove an unnecessary value in config 2021-04-24 18:57:14 +05:30
Deepjyoti Barman
a12b03ad6b Add function to update the autocomplete highlight color 2021-04-24 18:33:02 +05:30
Benji Hooper
94894c7e6f Include additional configuration for the line divider and the weather 2021-04-16 22:33:07 +01:00
Benji Hooper
8b7e59ca50 Make some background colors and text colors configurable through new style configuration object 2021-04-16 17:51:17 +01:00
Deepjyoti Barman
dc818bd2b5 Add styling for the title if it will be a link as well
The title in the cards are now optionally clickable. If the `url`
attribute is passed to the square in the config then the title will be
clickable and will open that particular `url`.

If not `url` is passed, it will be a plain old heading without any
link.
2020-11-30 13:25:28 +05:30
Deepjyoti Barman
53198646bb Add ability to pass URL for the card title 2020-11-30 13:23:39 +05:30
7 changed files with 215 additions and 76 deletions

View File

@@ -1,19 +1,7 @@
<div align="center"> my fork of [this](https://github.com/deepjyoti30/startpage/) start page
<h1>Minimal Startpage</h1>
<h4>Just another minimal startpage for browsers.</h4>
</div>
<img src=".github/startpage.gif"> i just changed the color palette to onedark,
you will find the documentations and everything on the original repo
<div align="center"> # SCREENSHOTS
<br> <img src = "https://i.imgur.com/s5T9dKK.png">
<img src="https://img.shields.io/badge/Maintained%3F-Yes-blueviolet?style=for-the-badge"> <img src = "https://i.imgur.com/wJagxIv.png">
<a href="LICENSE.md"><img src="https://img.shields.io/badge/License-MIT-pink.svg?style=for-the-badge"></a> <a href="http://makeapullrequest.com"><img src="https://img.shields.io/badge/PRs-welcome-lightblue.svg?style=for-the-badge"></a> <img src="https://img.shields.io/badge/supports-chrome-lightgreen.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/supports-firefox-orange.svg?style=for-the-badge"><a href="https://www.paypal.me/deepjyoti30" target="_blank"><img alt="undefined" src="https://img.shields.io/badge/paypal-deepjyoti30-blue?style=for-the-badge&logo=paypal"></a>
<a href="https://ko-fi.com/deepjyoti30" target="_blank"><img alt="undefined" src="https://img.shields.io/badge/KoFi-deepjyoti30-red?style=for-the-badge&logo=ko-fi"></a>
<br>
<h3>
<a href="https://github.com/deepjyoti30/startpage/wiki/Installation">Installation</a> | <a href="https://github.com/deepjyoti30/startpage/wiki/Configuration">Configuration</a> | <a href="https://github.com/deepjyoti30/startpage/wiki">Wiki</a>
</h3>
</div>

View File

@@ -1,7 +1,7 @@
{ {
"squares": [ "squares": [
{ "name": "media", { "name": "media",
"color": "red", "color": "#61afef",
"links": [ "links": [
{ "name": "Spotify", "url": "https://open.spotify.com/" }, { "name": "Spotify", "url": "https://open.spotify.com/" },
{ "name": "YoutubeMusic", "url": "https://music.youtube.com/" }, { "name": "YoutubeMusic", "url": "https://music.youtube.com/" },
@@ -10,7 +10,7 @@
] ]
}, },
{ "name": "work", { "name": "work",
"color": "#26A69A", "color": "#e06c75",
"links": [ "links": [
{ "name": "Github", "url": "https://github.com" }, { "name": "Github", "url": "https://github.com" },
{ "name": "Heroku", "url": "http://heroku.com/" }, { "name": "Heroku", "url": "http://heroku.com/" },
@@ -18,6 +18,7 @@
] ]
}, },
{ "name": "social", { "name": "social",
"color": "#e5c07b",
"links": [ "links": [
{ "name": "Reddit", "url": "https://reddit.com" }, { "name": "Reddit", "url": "https://reddit.com" },
{ "name": "Unixporn Love", "url": "https://deepjyoti30.github.io/unixporn-love/" }, { "name": "Unixporn Love", "url": "https://deepjyoti30.github.io/unixporn-love/" },
@@ -27,6 +28,7 @@
}, },
{ {
"name": "Others", "name": "Others",
"color": "#98c379",
"links": [ "links": [
{"name": "Material Colors", "url": "http://materialuicolors.co/"}, {"name": "Material Colors", "url": "http://materialuicolors.co/"},
{"name": "Gmail", "url": "http://gmail.com/"}, {"name": "Gmail", "url": "http://gmail.com/"},
@@ -35,17 +37,29 @@
] ]
} }
], ],
"searchEngine":"DuckDuckGo", "searchEngine":"Brave",
"user": "Deepjyoti", "user": "Pirate",
"disableMessage": false, "disableMessage": false,
"disableDate": false, "disableDate": false,
"disableSearchBar": false, "disableSearchBar": false,
"disable24Hour": false, "disable24Hour": true,
"disableWeather": true, "disableWeather": false,
"timeZone": "America/Los_Angeles", "timeZone": "Africa/Cairo",
"weatherConf": { "weatherConf": {
"location": "Pune India", "location": "Giza Egypt",
"unit": "cel" "unit": "cel"
}, },
"settingsIcon": false "settingsIcon": false,
"style": {
"backgroundColor": "#282c34",
"messageColor": "#fff",
"dateColor": "#c8ccd4",
"lineColor": "#fff",
"weatherColor": "#c8ccd4",
"searchColor": "#c8ccd4",
"searchBackgroundColor": "#1e222a",
"squareColor": "#abb2bf",
"squareBackgroundColor": "#1e222a",
"autocompleteHighlightBackgroundColor": "#3e4451"
}
} }

View File

@@ -72,7 +72,8 @@ body {
font-size: 18px; font-size: 18px;
color: #fff; color: #fff;
box-sizing: border-box; box-sizing: border-box;
z-index: -1; } z-index: -1;
cursor: pointer; }
.main #search-bar .autocomplete-items-container .autocomplete-item:hover { .main #search-bar .autocomplete-items-container .autocomplete-item:hover {
background: #3b3b3b; } background: #3b3b3b; }
.main #search-bar .autocomplete-items-container .autocomplete-active { .main #search-bar .autocomplete-items-container .autocomplete-active {
@@ -97,6 +98,9 @@ body {
.main #other-content .sqr h4 { .main #other-content .sqr h4 {
font-size: 18px; font-size: 18px;
margin: 15px; } margin: 15px; }
.main #other-content .sqr h4 a {
color: inherit;
font-size: inherit; }
.main #other-content .sqr:hover { .main #other-content .sqr:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>startpage</title> <title>New Tab</title>
<!--Json Editor--> <!--Json Editor-->
<link rel="stylesheet" href="css/jsoneditor.min.css" type="text/css"> <link rel="stylesheet" href="css/jsoneditor.min.css" type="text/css">
<!--Custom CSS--> <!--Custom CSS-->

View File

@@ -1,4 +1,4 @@
function autocomplete(inp, passedValues) { function autocomplete(inp, passedValues, style) {
var currentFocus; var currentFocus;
/*execute a function when someone writes in the text field:*/ /*execute a function when someone writes in the text field:*/
@@ -18,6 +18,9 @@ function autocomplete(inp, passedValues) {
parentContainer.setAttribute("id", this.id + "-autocomplete-list"); parentContainer.setAttribute("id", this.id + "-autocomplete-list");
parentContainer.style.paddingBottom = "1rem"; parentContainer.style.paddingBottom = "1rem";
if(style["searchBackgroundColor"]) {
parentContainer.style.backgroundColor = style["searchBackgroundColor"];
}
/*for each item in the array...*/ /*for each item in the array...*/
Object.keys(passedValues).forEach((el, i, arr) => { Object.keys(passedValues).forEach((el, i, arr) => {
@@ -30,6 +33,14 @@ function autocomplete(inp, passedValues) {
// Add the url as an attribute // Add the url as an attribute
item.setAttribute('url', passedValues[el]); item.setAttribute('url', passedValues[el]);
if(style["searchBackgroundColor"]) {
item.style.backgroundColor = style["searchBackgroundColor"];
}
if(style["searchColor"]) {
item.style.color = style["searchColor"];
}
/*make the matching letters bold:*/ /*make the matching letters bold:*/
item.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>"; item.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
item.innerHTML += arr[i].substr(val.length); item.innerHTML += arr[i].substr(val.length);

View File

@@ -33,7 +33,7 @@ bgClassContainer = [
searchEngines = { searchEngines = {
"Google": "https://www.google.com/search?q=", "Google": "https://www.google.com/search?q=",
"DuckDuckGo": "https://duckduckgo.com/?q=", "DuckDuckGo": "https://duckduckgo.com/?q=",
"Bing": "https://www.bing.com/search?q=", "Brave": "https://search.brave.com/search?q=",
"Yahoo": "https://search.yahoo.com/search?p=", "Yahoo": "https://search.yahoo.com/search?p=",
"Ecosia": "https://www.ecosia.org/search?q=" "Ecosia": "https://www.ecosia.org/search?q="
} }
@@ -46,7 +46,7 @@ validQuickLinks = {}
function initBody() { function initBody() {
/** /**
* Function called when the body is loaded. * Function called when the body is loaded.
* *
* Do everything like adding an event listener to * Do everything like adding an event listener to
* other things. * other things.
*/ */
@@ -71,7 +71,7 @@ function initSearchBar(jsonData) {
searchEngine = "Google" searchEngine = "Google"
} }
searchUrl = this.searchEngines[searchEngine] searchUrl = this.searchEngines[searchEngine]
document.getElementById(searchBarId).placeholder = `Search something on ${searchEngine}` document.getElementById(searchBarId).placeholder = `${searchEngine} Search`
document.getElementById(searchBarId).addEventListener("keypress", (event) => { document.getElementById(searchBarId).addEventListener("keypress", (event) => {
if (event.key != 'Enter') return if (event.key != 'Enter') return
@@ -96,7 +96,7 @@ function initSearchBar(jsonData) {
function buildMsg() { function buildMsg() {
/** /**
* Build a nice message for the user. * Build a nice message for the user.
* *
* Following is how the message would be decided. * Following is how the message would be decided.
* 0 - 5:59 : It's too late, take some sleep * 0 - 5:59 : It's too late, take some sleep
* 6 - 8:59 : You're up early * 6 - 8:59 : You're up early
@@ -129,13 +129,13 @@ function buildMsg() {
function handleMessage(userName) { function handleMessage(userName) {
/** /**
* Handle the creation of the message * Handle the creation of the message
* *
* Build the message based on the time of the day. * Build the message based on the time of the day.
* If the message is null then add just the username * If the message is null then add just the username
* Else, add the username before the message. * Else, add the username before the message.
*/ */
var builtMsg = buildMsg() var builtMsg = buildMsg()
builtMsg == "" ? builtMsg == "" ?
builtMsg = `Hello ${userName}` : builtMsg = `Hey ${userName}, ${builtMsg}!` builtMsg = `Hello ${userName}` : builtMsg = `Hey ${userName}, ${builtMsg}!`
return builtMsg; return builtMsg;
} }
@@ -146,13 +146,13 @@ function updateTime() {
*/ */
currentDate = new Date() currentDate = new Date()
options = { options = {
day: 'numeric', day: 'numeric',
month: 'short', month: 'short',
hour: 'numeric', hour: 'numeric',
minute: 'numeric', minute: 'numeric',
hour12: disable24Hour, hour12: disable24Hour,
timeZone: timeZ timeZone: timeZ
} }
finalDate = currentDate.toLocaleString(undefined, options) finalDate = currentDate.toLocaleString(undefined, options)
document.getElementById(dateId).textContent = finalDate document.getElementById(dateId).textContent = finalDate
} }
@@ -173,7 +173,7 @@ function updateWeather(weatherConfig) {
userLocation = weatherConfig["location"].replace(/\ /g, ",") userLocation = weatherConfig["location"].replace(/\ /g, ",")
passedUnit = weatherConfig["unit"] passedUnit = weatherConfig["unit"]
unit = validWeatherUnit.includes(passedUnit.substring(0, 3)) ? unit = validWeatherUnit.includes(passedUnit.substring(0, 3)) ?
passedUnit : "cel" passedUnit : "cel"
fetchUrl = apiUrl + `?q=${userLocation}&appid=${appId}&units=metric` fetchUrl = apiUrl + `?q=${userLocation}&appid=${appId}&units=metric`
@@ -184,7 +184,7 @@ function updateWeather(weatherConfig) {
weatherType = jsonData["weather"][0]["main"] weatherType = jsonData["weather"][0]["main"]
temp = !unit.includes("cel") ? temp = !unit.includes("cel") ?
getFahrenheit(temp) + "&deg;F" : temp + "&deg;C" getFahrenheit(temp) + "&deg;F" : temp + "&deg;C"
weatherText = temp + ", " + indexUppercase(weatherType) weatherText = temp + ", " + indexUppercase(weatherType)
document.getElementById(weatherId).innerHTML = weatherText document.getElementById(weatherId).innerHTML = weatherText
}) })
@@ -216,13 +216,13 @@ function parseAndCreate(jsonData) {
if (jsonData["settingsIcon"]) enableCog(); if (jsonData["settingsIcon"]) enableCog();
// If the user has not passed any custom message // If the user has not passed any custom message
if (Object.keys(jsonData).includes("message") && if (Object.keys(jsonData).includes("message") &&
typeof(jsonData["message"]) == "string" && typeof(jsonData["message"]) == "string" &&
jsonData["message"] != "") jsonData["message"] != "")
builtMsg = jsonData["message"] builtMsg = jsonData["message"]
else else
builtMsg = this.handleMessage(this.userName); builtMsg = this.handleMessage(this.userName);
document.getElementById(messageId).textContent = builtMsg document.getElementById(messageId).textContent = builtMsg
// Check if 24 hour is disabled // Check if 24 hour is disabled
disable24Hour = jsonData["disable24Hour"] disable24Hour = jsonData["disable24Hour"]
@@ -252,19 +252,66 @@ function parseAndCreate(jsonData) {
sqrs = jsonData["squares"] sqrs = jsonData["squares"]
// Extract the quicklinks from the sqrs
extractQuickLinks(sqrs);
sqrs.forEach((element, index) => { sqrs.forEach((element, index) => {
sqr = createSqr(element, index) sqr = createSqr(element, index)
document.getElementById(otherContentId).appendChild(sqr) document.getElementById(otherContentId).appendChild(sqr)
}) })
// Apply styling if present
if (jsonData["style"]) {
styleData = jsonData["style"]
if (styleData["backgroundColor"]) {
document.body.style.backgroundColor = styleData["backgroundColor"]
}
if (styleData["messageColor"]) {
document.getElementById(messageId).style.color = styleData["messageColor"]
}
if (styleData["dateColor"]) {
document.getElementById(dateId).style.color = styleData["dateColor"]
}
if (styleData["lineColor"]) {
document.getElementById(lineId).style.color = styleData["lineColor"]
}
if (styleData["weatherColor"]) {
document.getElementById(weatherId).style.color = styleData["weatherColor"]
}
if (styleData["searchColor"]) {
document.getElementById(searchBarId).style.color = styleData["searchColor"]
}
if (styleData["searchBackgroundColor"]) {
document.getElementById(searchBarId).style.backgroundColor = styleData["searchBackgroundColor"]
autocompleteBackgroundColor = styleData["searchBackgroundColor"]
}
if (styleData["searchPlaceholderColor"]) {
document.getElementById(searchBarId).classList.add(createPlaceholderStyleClass(styleData["searchPlaceholderColor"]));
}
if (styleData["autocompleteHighlightBackgroundColor"]) {
addAutocompleteStyleClass(styleData["autocompleteHighlightBackgroundColor"]);
}
if (styleData["squareBackgroundColor"]) {
elements = document.getElementsByClassName("sqr")
var i;
for (i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = styleData["squareBackgroundColor"]
}
}
if (styleData["squareColor"]) {
elements = document.querySelectorAll(".sqr a")
var i;
for (i = 0; i < elements.length; i++) {
elements[i].style.color = styleData["squareColor"]
}
}
}
// Extract the quicklinks from the sqrs
extractQuickLinks(sqrs, jsonData["style"]);
} }
function createSqr(sqrData, index) { function createSqr(sqrData, index) {
// Create a new square division with the passed element // Create a new square division with the passed element
name = sqrData["name"]; name = sqrData["name"];
link = sqrData["url"];
links = sqrData["links"]; links = sqrData["links"];
color = sqrData["color"]; color = sqrData["color"];
@@ -286,16 +333,14 @@ function createSqr(sqrData, index) {
div.classList.add(customClass); div.classList.add(customClass);
h4 = document.createElement("h4") h4 = getTitle(name, link);
h4.textContent = name
div.appendChild(h4) div.appendChild(h4)
links.forEach(element => { links.forEach(element => {
aName = element["name"] aName = element["name"]
aHref = element["url"] aHref = element["url"]
a = document.createElement("a") a = document.createElement("a")
attrHref = document.createAttribute("href") attrHref = document.createAttribute("href")
attrHref.value = aHref attrHref.value = aHref
@@ -309,6 +354,32 @@ function createSqr(sqrData, index) {
return div return div
} }
function getTitle(titleContent, linkHref=null) {
/**
* Create the title for the sqr card.
*
* The card will be optionally clicable and will open
* a new link.
*
* If the link is not passed in the config then the title
* will not be clickable.
*/
h4 = document.createElement("h4");
if (!linkHref) {
h4.textContent = titleContent;
return h4;
}
// If the link is passed, create a nested child
a = document.createElement("a");
a.setAttribute("href", linkHref);
a.textContent = titleContent;
h4.appendChild(a);
return h4;
}
// Utility functions // Utility functions
function isValidTimeZone(tz) { function isValidTimeZone(tz) {
@@ -342,7 +413,7 @@ function inRange(number, min, max) {
function isColorValid(color) { function isColorValid(color) {
/** /**
* Check if the passed color is valid. * Check if the passed color is valid.
* *
* Currently supports only css color names * Currently supports only css color names
* or hex colors having 3 or 6 characters. * or hex colors having 3 or 6 characters.
*/ */
@@ -359,12 +430,12 @@ function createClass(color) {
/** /**
* Create a new class in a style and add it to * Create a new class in a style and add it to
* the head. * the head.
* *
* I did check other alternatives since adding something like * I did check other alternatives since adding something like
* this in the innerHTML is not a preferred way to go, * this in the innerHTML is not a preferred way to go,
* especially since I'm building this as an extension, * especially since I'm building this as an extension,
* however, there's no other way. * however, there's no other way.
* *
* Since I also want to add hover effects, there seriously * Since I also want to add hover effects, there seriously
* is no other way to do that without adding a style or using * is no other way to do that without adding a style or using
* a library (cannot/don't want to do that because this is an extension). * a library (cannot/don't want to do that because this is an extension).
@@ -378,11 +449,56 @@ function createClass(color) {
return newClassName; return newClassName;
} }
function createPlaceholderStyleClass(color) {
/**
* Create a new class with for placeholder styling.
*
* This is pretty much a continuation of what has done preivously
* in the createClass function.
*/
var style = document.createElement('style');
const newClassName = `bg-${Math.random().toString(36).substring(7)}`;
style.type = 'text/css';
style.innerHTML = `::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: ${color} !important;
opacity: 1; /* Firefox */
}
function extractQuickLinks(passedSqrs) { :-ms-input-placeholder { /* Internet Explorer 10-11 */
color: ${color} !important;
}
::-ms-input-placeholder { /* Microsoft Edge */color: ${color} !important;}`;
document.getElementsByTagName('head')[0].appendChild(style);
return newClassName;
}
function addAutocompleteStyleClass(color) {
/**
* Add some colors for the autocomplete classes in order to
* keep. We need to add styles for :hover property so it is
* easier to just inject some CSS.
*/
var style = document.createElement("style");
style.type = "text/css";
style.innerHTML = `
.autocomplete-item:hover {
background: ${color} !important;
}
.autocomplete-active {
background: ${color} !important;
}
`;
document.getElementsByTagName('head')[0].appendChild(style);
}
function extractQuickLinks(passedSqrs, style) {
/** /**
* Extract the quicklinks passed in the config * Extract the quicklinks passed in the config
* *
* Cache the quicklinks passed by the user in the config JSON * Cache the quicklinks passed by the user in the config JSON
* so that they can be used as a shortcut called from the * so that they can be used as a shortcut called from the
* search bar. * search bar.
@@ -392,7 +508,7 @@ function extractQuickLinks(passedSqrs) {
}); });
// Start the autocomplete // Start the autocomplete
autocomplete(document.getElementById("search-bar-input"), this.validQuickLinks); autocomplete(document.getElementById("search-bar-input"), this.validQuickLinks, style);
} }
// Listen to key click // Listen to key click
@@ -410,10 +526,10 @@ function listenForSettings() {
function enableCog() { function enableCog() {
/** /**
* Enable the settings cog. * Enable the settings cog.
* *
* It will be disabled by default, however, if the user * It will be disabled by default, however, if the user
* wishes to enable it through the config, it will be shown. * wishes to enable it through the config, it will be shown.
* *
* Once shown, we need to add some event listeners to it as * Once shown, we need to add some event listeners to it as
* well so it works the right way. * well so it works the right way.
*/ */
@@ -432,4 +548,4 @@ function enableCog() {
hideSettings(editor); hideSettings(editor);
} }
} }
} }

View File

@@ -1,12 +1,12 @@
$background: #212121; $background: #282c34;
$foreground: #fff; $foreground: #abb2bf;
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
$media: #4DD0E1; $media: #61afef;
$work: #F06292; $work: #e06c75;
$social: #FFF176; $social: #e5c07b;
$others: #81C784; $others: #98c379;
$funky: #4DB6AC; $funky: #56b6c2;
$purple: #9575CD; $purple: #c678dd;
$upvoty: #FF8A65; $upvoty: #FF8A65;
$indigo: #7986CB; $indigo: #7986CB;
$foxxy: #A1887F; $foxxy: #A1887F;
@@ -108,6 +108,7 @@ body {
color: $foreground; color: $foreground;
box-sizing: border-box; box-sizing: border-box;
z-index: -1; z-index: -1;
cursor: pointer;
&:hover { &:hover {
background: lighten($background, 10); background: lighten($background, 10);
@@ -143,6 +144,11 @@ body {
h4 { h4 {
font-size: 18px; font-size: 18px;
margin: 15px; margin: 15px;
a {
color: inherit;
font-size: inherit;
}
} }
&:hover { &:hover {
@@ -182,7 +188,7 @@ body {
h4, a:hover { h4, a:hover {
color: $social; color: $social;
} }
} }
.others { .others {
@@ -261,10 +267,10 @@ body {
right: 25px; right: 25px;
transition: 2s ease-in; transition: 2s ease-in;
display: none; display: none;
&:hover .cog { &:hover .cog {
fill: white; fill: white;
stroke: white; stroke: white;
transition: 2s ease-in; transition: 2s ease-in;
} }
} }