<html lang="en">
<div class="wrapper">
<div class="align">
<p id="forget">Don't forget to change your <strong>City!</strong><br><br> Default city is set to <strong>London</strong></p>
<div class="app">
<div id="main">
<!-- Settings Menu -->
<div id="introscreen"><img src="https://image.flaticon.com/icons/svg/578/578457.svg"></div>
<!-- Settings Button -->
<span id="btn-right">
<span></span>
<span></span>
<span></span>
<span></span>
</span>
<!-- End Settings Button -->
<!-- Info Message-->
<div id="info-msg">
<div class="msg-box">
<h1></h1>
<p></p>
</div>
</div>
<!-- End Info Message-->
<div id="settings" class="">
<p id="settings-info"><i class="fa fa-cog" aria-hidden="true"></i> Settings</p>
<div class="search-container">
<label>
<input autocomplete="off" type="text" id="search" placeholder="Search City..." required/>
<i class="fa fa-search" aria-hidden="true"></i>
<button type="button" id="update-button" placeholder="Update">Update</button>
</label>
</div>
<ul>
<li>
<div class="text">
<p>Temperature Unit</p>
</div>
<label class="switch">
<input type="checkbox" id="unit">
<div class="slider">
<p class="left"><i class="c" aria-hidden="true">°C</i></p>
<p class="right"><i class="f" aria-hidden="true">°F</i></p>
</div>
</label>
<div class="sub-info">Choose between ºC or ºF.</div>
</li>
<li>
<div class="text">
<p>Atmospheric Conditions</p>
</div>
<label class="switch">
<input type="checkbox" id="atm">
<div class="slider">
<p class="left"><i class="fa fa-check" aria-hidden="true"></i></p>
<p class="right"><i class="fa fa-times" aria-hidden="true"></i></p>
</div>
</label>
<div class="sub-info">Humidity, pressure and visibility of the atmosphere.</div>
</li>
<li>
<div class="text">
<p>Sunrise/Sunset</p>
</div>
<label class="switch">
<input type="checkbox" id="sun">
<div class="slider">
<p class="left"><i class="fa fa-check" aria-hidden="true"></i></p>
<p class="right"><i class="fa fa-times" aria-hidden="true"></i></p>
</div>
</label>
<div class="sub-info">Sunset/Sunrise hours and total hours of light.</div>
</li>
<li>
<div class="text">
<p>Wind Conditions</p>
</div>
<label class="switch">
<input type="checkbox" id="wind">
<div class="slider">
<p class="left"><i class="fa fa-check" aria-hidden="true"></i></p>
<p class="right"><i class="fa fa-times" aria-hidden="true"></i></p>
</div>
</label>
<div class="sub-info">Chill, direction and the speed of the wind.</div>
</li>
<li>
<div class="text">
<p>Choose a theme</p>
<div class="row">
<span class="green"></span>
<span class="turqoise"></span>
<span class="blue"></span>
<span class="purple"></span>
</div>
</div>
<div class="sub-info">Select the desired theme. Press the "Save" button to update the theme!</div>
</li>
</ul>
<button type="button" id="save-button" placeholder="Update">Save</button>
</div>
<!-- End Settings Menu -->
<div id="central">
<div id="top-menu-info">
<p id="location">
<i class="fa fa-map-marker" aria-hidden="true"></i>
<span>Undefined</span>
</p>
<p id="date">
<span>Day, Day Month Year</span>
</p>
</div>
<div id="temp-div">
<div id="icon-temp">
<p>Sunny</p>
<i class="wi wi-day-cloudy" aria-hidden="true"></i>
</div>
<p id="current-temp-big">
<span id="ctb">17</span>
<span id="ctbicon">ºC</span>
</p>
</div>
<div id="weather-menu">
<span href="#" id="weather-menu-btn">
<i class="fa fa-chevron-up" aria-hidden="true"></i>
</span>
<ul>
<li id="atmli">
<p class="li_title">Atmospheric Conditions</p>
<div id="humidity" class="col-1">
<i class="wi wi-humidity" aria-hidden="true"></i>
<span>Humidity <br> <span id="hd">NaN</span></span>
</div>
<div id="pressure" class="col-2">
<i class="wi wi-barometer" aria-hidden="true"></i>
<span>Pressure <br> <span id="pd">NaN</span></span>
</div>
<div id="visibility" class="col-3">
<i class="wi wi-day-fog" aria-hidden="true"></i>
<span>Visibility <br> <span id="vd">NaN</span></span>
</div>
</li>
<li id="sunli">
<p class="li_title">Sunrise/Sunset</p>
<div id="sunrise" class="col-1">
<i class="wi wi-sunrise" aria-hidden="true"></i>
<span>Sunrise <br> <span id="srd">NaN</span></span>
</div>
<div id="totallight" class="col-2">
<i class="wi wi-time-4" aria-hidden="true"></i>
<span>Hours of light<br> <span id="td">NaN</span></span>
</div>
<div id="sunset" class="col-3">
<i class="wi wi-sunset" aria-hidden="true"></i>
<span>Sunset <br> <span id="ssd">NaN</span></span>
</div>
</li>
<li id="windli">
<p class="li_title">Wind Conditions</p>
<div id="chill" class="col-1">
<i class="wi wi-thermometer-exterior
" aria-hidden="true"></i>
<span>Feels Like <br> <span id="cd">NaN</span></span>
</div>
<div id="direction" class="col-2">
<i class="wi wi-wind from-270-deg" aria-hidden="true"></i>
<span>Direction <br> <span id="dd">NaN</span></span>
</div>
<div id="speed" class="col-3">
<i class="wi wi-strong-wind" aria-hidden="true"></i>
<span>Speed <br> <span id="sd">NaN</span></span>
</div>
</li>
<li id="forecastli">
<p class="li_title">9 Days Forecast</p>
<span class="day_left">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
</span>
<span class="day_right">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
</span>
<div class="li_row">
<div class="col-1 day10item">
<i class="wi wi-day-sunny" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-2 day10item" >
<i class="wi wi-day-cloudy" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-3 day10item">
<i class="wi wi-day-rain" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-1 day10item">
<i class="wi wi-day-sunny" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-2 day10item" >
<i class="wi wi-day-cloudy" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-3 day10item">
<i class="wi wi-day-rain" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-1 day10item">
<i class="wi wi-day-sunny" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-2 day10item" >
<i class="wi wi-day-cloudy" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
<div class="col-3 day10item">
<i class="wi wi-day-rain" aria-hidden="true"></i>
<span>NaN <br> <i>NaN°</i></span>
</div>
</div>
<div id="dotmenu">
<span class="currentday"></span>
<span></span>
<span></span>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<p id="copyright">Made by <strong><a href="https://www.linkedin.com/in/nicolae-stefan-tudoran-b02291127/" target="_blank" rel="noopener">Stefan Tudoran</a></strong><br><br>Also on <strong><a href="https://github.com/tns301/WeatherApp" target="_blank" rel="noopener">GitHub</a></strong></p>
</div>
</div>
* {
margin: 0;
padding: 0;
}
@green2: #6cd089;
@purple2: #b557b7;
@blue2: #6eadfd;
@turqoise2: #31cec2;
@green: linear-gradient(135deg, #bcec68 -20%, #0eb9a4 120%);
@purple: linear-gradient(135deg, #f572c1 -20%, #6a37ab 120%);
@blue: linear-gradient(135deg, #80ecf7 -20%, #706aff 120%);
@turqoise: linear-gradient(135deg, #5de2ff -20%, #08bb8a 120%);
@settings: #f2f2f2;
@settings-content: #fff;
@settings-info: #f9f9f9;
@settings-color: #444;
@settings-error: linear-gradient(to bottom, rgba(255, 255, 255, 0.97) 0%, rgba(245, 245, 245, 0.97) 100%);
body {
background: #fbfbfb;
font-smoothing: subpixel-antialiased;
transition: background .75s;
&.green{background:@green2;#copyright,#forget{color:#fff;a{color:#fff;}}}
&.purple{background: @purple2;#copyright,#forget{color:#fff;a{color:#fff;}}}
&.blue{background:@blue2;#copyright,#forget{color:#fff;a{color:#fff;}}}
&.turqoise{background:@turqoise2;#copyright,#forget{color:#fff;a{color:#fff;}}}
}
.wrapper {
width: 100%; min-height: 840px;
.align {
width: 100%; height: 100%;
margin: 0 auto;
padding: 40px 0;
}
.app {
position: relative;
transform:translate3d(0,0,0);
perspective: 1000;
width: 394px; min-height: 716px;
margin: 0 auto;
border-radius: 22px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15);
font-family: sans-serif;
overflow: hidden;
#main {
position: absolute;
width: 100%; height: 100%;
overflow: hidden;
border-radius: 12px;
background:#444;
user-select: none;
user-select: none;
user-select: none;
user-select: none;
// fix for border-radius "bleed"
mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
@top-menu-height:62px;
#introscreen{
visibility: visible;
opacity:1;
position: absolute;
width:100%; height: 100%;
background:#fff;
// vertical center;
display: flex;
flex-direction: column;
justify-content: center;
z-index:9999;
pointer-events: none;
user-select: none;
user-select: none;
user-select: none;
user-select: none;
user-select: none;
transition: 1s;
backface-visibility: hidden;
text-align:center;
img{
height: 300px;
color:#f5c34f;
transition: 1s;
}
&.sunloading{
img{transform:rotate(90deg) scale(5, 5);}
}
&.animfin{
visibility: hidden;
opacity:0;
}
}
#btn-right {
position: absolute;
width: 26px; height: 22px;
text-align: center;
text-decoration: none;
z-index: 5;
color: #fff;
span {
display: block;
position: absolute;
opacity: 1;
background: #fff;
transition: .5s;
}
}
#btn-right {
top: 16px; right: 5px;
margin-right: 15px;
}
#btn-right:hover{
cursor:pointer;
}
#btn-right span:nth-child(n + 1):nth-child(-n + 4) {
width: 100%; height: 3px;
left: 0; right: 0;
margin: 0 auto;
}
#btn-right span:nth-child(1) {top: 0px;}
#btn-right span:nth-child(n + 2):nth-child(-n + 3) {top: 8px;}
#btn-right span:nth-child(4) {top: 16px;}
#btn-right.open span{background:@settings-color;}
#btn-right.open span:nth-child(1), #btn-right.open span:nth-child(4) {top: 8px;width:0;}
#btn-right.open span:nth-child(2) {transform: rotate(45deg);}
#btn-right.open span:nth-child(3) {transform: rotate(-45deg);}
#info-msg{
visibility: hidden;
opacity: 0;
position: absolute;
width: 100%; height: 100%;
background: rgba(0,0,0,.70);
// vertical center;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 9000; // It's over 9000!!!!
transition: .5s;
backface-visibility: hidden;
// animation
&.show{opacity:1;visibility: visible; }
.msg-box{
position: absolute;
width:80%; min-height: 150px;
left: 0; right: 0;
transform: scale(0);
opacity: 0;
margin: 0 auto;
border-radius: 12px;
box-shadow: 0 0 8px rgba(0,0,0,.2);
background: @settings-error;
text-align: center;
transition: .5s;
.loader {
position: relative;
width: 1em; height: 1em;
margin: -5px auto;
color: #444;
font-size: 10px;
border-radius: 50%;
text-indent: -9999em;
animation: load1 1s infinite linear;
transform: translateZ(0);
transform: translateZ(0);
transform: translateZ(0);
}
&.hide{
opacity:0;
}
@-webkit-keyframes load1 {
0%,
100% {
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
}
87.5% {
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
@keyframes load1 {
0%,
100% {
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
}
87.5% {
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
&.open {
opacity: 1;
transform:scale(1);
animation: open .5s;
animation: open .5s;
animation: open .5s;
animation: open .5s;
}
@keyframes open {
0% {
transform:scale(0);
}
40% {
transform:scale(1.1);
}
60% {
transform:scale(0.90);
}
80% {
transform:scale(1.05);
}
100% {
opacity: 1;
transform:scale(1);
}
}
h1{color:@settings-color;font-size:18px;width:92%;height:auto;line-height: 23px;margin:20px auto 0 auto;}
p{color:@settings-color;font-size:14px;width:87%;min-height:30px;line-height: 30px;margin:13px auto 10px auto;transition: .25s;
&.load{
margin-top:40px;
}
&.show{
opacity:1;
}
&.hide{
opacity:0;
}
}
#ok-btn{
position:absolute;
bottom:0;
width: 100%; height: 40px;
line-height:40px;
cursor:pointer;
font-size:20px;
font-weight:bold;
box-shadow: inset 0 1px 0 rgba(255,255,255,.5);
border-top:solid 1px rgba(0,0,0,.15);
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
}
#ok-btn:hover{background:#f9f9f9;}
#ok-btn:active{background:#eaeaea;line-height:42px;}
}
}
#settings {
position: absolute;
width: 394px; height: 100%;
top: 0; right: 0;
background: @settings;
z-index: 3;
text-shadow: 0 0 1px rgba(0,0,0,.01);
border-radius: 20px;
transform:translate3d(0,0,0);
transition: .6s;
//hidden
transform: translateX(394px);
//show
&.show{transform: translateX(0px);
#settings-info{color:@settings-color;background:@settings-info;}
}
#settings-info{
height: 52px; line-height: 52px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.05);
background: @settings-info;
border-top-left-radius: 20px;
text-align: left;
text-indent: 10px;
font-size: 24px;
color: @settings;
letter-spacing: -1px;
transition: .65s ease-out;
}
ul{
width:90%; height: auto;
margin: 10px auto 0 auto;
li{
width: 100%; height: auto;
margin: 10px auto;
list-style: none;
// slide animation on opening
transition: .4s;
transform: translateX(75px);
.text{
width:100%;
min-height:40px; line-height:40px;
font-size:14px;
font-weight:bold;
color:@settings-color;
text-indent:12px;
background: @settings-content;
border-radius: 20px;
box-shadow: 0 0 1px rgba(0,0,0,.08);
.row{
width: 100%;
// Theme colors
span{
display: inline-block;
width: 20%; height: 50px;
margin-left: 4px;
margin-right: 5px;
cursor: pointer;
border-radius: 10px;
transition: .20s;
&.green{background:@green;}
&.blue{background:@blue;}
&.turqoise{background:@turqoise;}
&.purple{background:@purple;}
&.green,&.blue,&.turqoise,&.purple{
&.current{transform:scale(1);}
&.current::before {
content: "\f00c";
position: absolute;
text-align: center;
color: #fff;
text-shadow: none;
font-size:25px;
font-family:'FontAwesome';
top: 5px; left: 12px;
}
}
}
span:hover{ transform: scale(.9); }
}
}
.sub-info{
width:90%; height: 20px; line-height: 20px;
margin: 2px auto -8px auto;
color:darken(@settings,50%);
font-size:12px;
// slide animation on opening
transition: .4s;
}
&.slideAnimation{ transform: translateX(0px); }
//end slide animation on opening
.switch {
position: absolute;
display: inline-block;
width: 52px; height: 28px;
right: 7px; top: 6px;
text-shadow:none;
}
.switch input { display:none; }
.slider {
position: absolute;
cursor: pointer;
top: 0; left: 0;
right: 0; bottom: 0;
background: #ececec;
transition: background .25s;
transition: background .25s;
border-radius: 34px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.15);
span{ transform: translate(-6px, -6px); }
.left,.right{
position: absolute;
width: 26px;height: 28px;
top: 0px;
font-size: 18px;
z-index: 1;
text-align: center;
color: darken(@settings,50%);
transition: 0s;
}
.left{
left: 0px;
i{
position: relative;
top: 4px;left: 1px;
font-size: 17px;
&.c{
position:relative;
top: 5px;left: 0px;
font-size: 18px;
font-style: normal;
}
}
}
.right{
right:0px;
i{
position: relative;
top: 4px;right: 1px;
font-size: 17px;
&.f{
position: relative;
top: 5px;right: 3px;
font-size: 18px;
font-style: normal;
}
}
}
}
.slider:before {
position: absolute;
content: "";
height: 24px; width: 24px;
left: 2px; bottom: 2px;
background: #fff;
transition: .20s ease-out;
border-radius: 50%;
box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25);
z-index:2;
}
input:checked + .slider:before {
transition: .20s ease-out;
transform: translateX(24px);
}
input:checked + .slider {
p{color: #fff;}
}
input:not(:checked) + .slider {
background: #ececec;
}
}
}
.search-container{
position: relative;
width: 90%; height: 50px;
margin: 30px auto 0 auto;
// slide animation on opening
transition: .4s;
transform: translateX(75px);
&.slideAnimation{ transform: translateX(0px); }
//end slide animation on opening
#search{
position: relative;
width: 60%; height: 35px;
margin: 0 auto;
float: left;
box-shadow: 0 0 1px rgba(0,0,0,.05);
border: none;
border-radius: 15px;
background: @settings-content;
color: @settings-color;
font-weight: bold;
text-indent: 30px;
}
#search:focus{outline: none;}
#search::input-placeholder{color:@settings-color;opacity:1;transition:.4s;}
#search:focus::input-placeholder {text-indent:100%;opacity:0;transition:.4s;}
#search::placeholder {color:@settings-color;opacity:1;transition:.4s;}
#search:focus::placeholder {text-indent:100%;opacity:0;transition:.4s;}
#search:input-placeholder{color:@settings-color;opacity:1; }
#search:focus:input-placeholder {text-indent:100%;opacity:0;transition:.4s;}
i{
position: absolute;
width: 20px; height: 20px;
font-size: 17px;
left: 10px; top: 8px;
color: @settings-color;
}
}
#update-button, #save-button{
position: relative;
width: 35%; height: 35px;
float: right;
border: none;
border-radius: 15px;
font-size: 17px;
font-weight: bold;
font-family: sans-serif;
color: #fff;
text-shadow: 0 0 1px rgba(0,0,0,.25);
outline:none;
cursor:pointer;
}
#save-button{ position: absolute; float: none; margin: 0 auto; bottom: 25px; right: 0; left: 0;}
#update-button:hover ,#save-button:hover{ opacity:0.90; }
#update-button:active ,#save-button:active{ opacity: 1; box-shadow: inset 0 1px 7px rgba(0,0,0,.25); line-height: 37px; }
}
/*
#info-msg.show + #settings.show{
filter:blur(2px);
}
*/
#settings.show + #central{
transform: scale(0.87) translateX(25px);
}
#central{
position: absolute;
width: 394px; height: 100%;
top: 0; right: 0;
border-radius: 20px;
text-shadow: 0 0 2px rgba(0,0,0,.25);
transition: .6s;
transition: .6s;
#top-menu-info{
position: absolute;
width:100%; height: @top-menu-height;
top: 0; margin-top: 1px;
#location{
font-size: 27px;
text-align: center;
line-height: 50px;
color: #fff;
letter-spacing: -1px;
i{ font-size: 22px; transform: translateY(-2px); }
}
#date{
position: relative;
top: -8px; left: 3px;
font-size: 13px;
text-align: center;
text-shadow:none;
color: #fff;
}
}
#temp-div{
position: absolute;
width: 100%; height:auto;
top: 50%; transform: translateY(-50%);
transform: translateY(-50%);
perspective: 1000;
transition: .75s ease-in-out;
transition: .75s ease-in-out;
#icon-temp{
margin: 0 auto;
width: 100%;
text-align: Center;
font-size: 45px;
color: #fff;
i{
position:relative;
top:8px;
}
p{
display: inline-block;
font-size: 28px;
max-width: 210px;
line-height: 60px;
}
}
#current-temp-big{
display: inline-block;
width: 100%;
text-align: center;
color: #fff;
#ctb{
font-size: 100px;
font-weight: bold;
}
#ctbicon{
position: relative;
top: -40px; left: -5px;
font-weight: 100;
font-size: 40px;
vertical-align: unset;
}
}
}
#temp-div.weather-menu-show{
transform: translate(-80px,-320px) scale(0.75);
}
#weather-menu{
position: absolute;
width: 394px; height: auto;
bottom: 0; right: 0;
color:#fff;
transition: all .75s ease-in-out;
transform: translateY(100%);
backface-visibility: hidden;
&.show{transform: translateY(0%);
#weather-menu-btn{ transform: rotate(180deg); }
ul{ opacity:1; }
}
&.settings{
background: #444;
color: #444;
}
p{
width: 100%; height: 40px;
text-align: center;
font-size: 26px;
line-height: 40px;
font-weight: 100;
}
ul{
width: 100%;height: auto;
opacity: 0;
list-style: none;
text-align: center; // this will center left/right all elements inside ul (col-1..)
backface-visibility: hidden;
transition: opacity .75s;
transition: opacity .75s;
li{
overflow: hidden;
position: relative;
width: 100%; min-height: 122px;
margin: 0px auto;
color: #fff;
backface-visibility: hidden;
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05), inset 0 1px 0 rgba(255,255,255,.1);
background: rgba(255, 255, 255, 0.15);
&.aswshow{
display: block;
}
&.aswhidden{
display: none;
}
.day_left{
left: 0px;
}
.day_right{
right: 0px;
}
.day_left,.day_right{
position: absolute;
width: 40px; height: 40px;
top: 45px;
transition: .3s;
z-index:100;
i{
position: relative;
top: 7px;
font-size: 30px;
}
}
.day_left:hover,.day_right:hover{
cursor: pointer;
text-shadow:0 0 20px rgba(255,255,255,1);
}
.col-1,.col-2,.col-3{
display: inline-block;
width: 116px; height:72px;
margin: 0 auto;
}
.li_title{
padding: 12px 0;
font-size: 15px;
width: 100%; height: 8px;
line-height: 8px;
margin-bottom: 5px;
font-weight: 400;
}
#sunrise,#sunset,#totallight,#humidity,#pressure,#visibility,#chill,#direction,#speed,.day10item{
i{ font-size: 26px; }
span{
display: list-item;
margin-top: 4px;
font-size: 14px;
i{
position: relative;
top: 3px;
font-size: 14px;
font-style: normal;
}
strong{
position: relative;
top: 3px;
font-size: 20px;
font-weight:100;
}
}
}
#hd,#pd,#vd,#srd,#td,#ssd,#cd,#dd,#sd{ margin-top: 0px; }
.li_row{
overflow: hidden;
width: 1110px; height: 70px;
margin-top: 5px;
transition: .25s;
z-index:80;
}
#dotmenu{
width: 100%; height: 27px;
margin: 10px auto 0 auto;
z-index: 1000;
span{
display: inline-block;
width: 10px; height: 10px;
background: #fff;
border-radius: 20px;
margin-left: 2px;
transition: .20s;
&.currentday{
transform: scale(1.4);
}
}
span:hover{
cursor: pointer;
}
}
}
li:last-child{
border-bottom-left-radius: 18px;
border-bottom-right-radius: 18px;
}
}
#weather-menu-btn{
position: absolute;
top: -40px; left:0; right:0;
margin-left: auto; margin-right: auto;
width: 40px; height: 40px;
font-size: 30px;
color: #fff;
text-align: center;
transition: .25s;
}
#weather-menu-btn:hover{
text-shadow:0 0 10px rgba(255,255,255,1);
cursor: pointer;
}
}
}
}
//------- THEMES ---------
// Green
#central.green{background: @green;}
#main.green{
&.poor-Mozilla{background:@settings};
#settings{
ul{li{input:checked + .slider{
background: @green2;
}}}
#update-button,#save-button{
background: @green;
}
}
#info-msg{ .msg-box{ div{
color: @green2;
}}}
}
#main.green > #central{ background: @green; }
// Blue
#central.blue{ background: @blue; }
#main.blue{
&.poor-Mozilla{ background: @settings };
#settings{
ul{li{input:checked + .slider{
background: @blue2;
}}}
#update-button,#save-button{
background: @blue;
}
}
#info-msg{ .msg-box{ div{
color: @blue2;
}}}
}
#main.blue > #central{ background: @blue; }
// Purple
#main.purple{
&.poor-Mozilla{ background: @settings };
#settings{
ul{li{input:checked + .slider{
background: @purple2;
}}}
#update-button,#save-button{
background: @purple;
}
}
#info-msg{.msg-box{div{
color: @purple2;
}}}
}
#main.purple > #central{background: @purple;}
// Turqoise
#central.turqoise{ background: @turqoise;}
#main.turqoise{
&.poor-Mozilla{ background: @settings};
#settings{
ul{li{input:checked + .slider{
background: @turqoise2;
}}}
#update-button,#save-button{
background: @turqoise;
}
}
#info-msg{.msg-box{div{
color: @turqoise2;
}}}
}
#main.turqoise > #central{background: @turqoise;}
}
}
@-moz-document url-prefix() {
.wrapper{.app{ #main{ #settings{ ul{ li{ .slider{ .left{
top: 1px;
i {
position: relative;
top: 2px; left: 1px;
&.c{
position: relative;
top: 3px; left: 1px;
}
}}}}}}}}}
.wrapper{.app{ #main{ #settings{ ul{ li{ .slider{ .right{
i {
position: relative;
top: 3px; right: 1px;
&.f{
position: relative;
top: 4px; right: 2px;
}
}}}}}}}}}
}
#copyright {
text-shadow:0 0 1px rgba(0,0,0,.12);
text-align: center;
font-size: 16px;
font-family: sans-serif;
color: #757575;
width: 250px;
margin: 30px auto 0 auto;
a {
text-decoration: none;
color: #5a5a5a;
transition: all ease-in-out 0.35s;
}
a:hover {color: lighten(#5a5a5a,20%);
}
}
#forget {
text-shadow:0 0 1px rgba(0,0,0,.12);
font-size: 16px;
color: #757575;
margin:10px auto 25px auto;
font-family:sans-serif;
width: 350px;
text-align: center;
a {
text-decoration: none;
color: #5a5a5a;
transition: all ease-in-out 0.35s;
}
a:hover {
color: lighten(#5a5a5a,20%);
}
&.hide{transition: all ease-in-out 0.35s;opacity:0;}
}
View Compiled
$(document).ready(function(){
//Caching DOM elements
var $RightMenu = $('#settings'),
$RightButton = $('#btn-right'),
$WeatherMenu = $('#weather-menu'),
$Main = $('#main'),
$Central = $('#central'),
$Info = $('#info-msg'),
$InfoMsgBx = $('#info-msg .msg-box'),
$InfoMsgBxP = $('#info-msg .msg-box p'),
$InfoMsgBxH1 = $('#info-msg .msg-box h1'),
$DotMenu = $('#dotmenu span'),
$TempDiv = $('#temp-div'),
$LiRow = $('.li_row');
var arrayThemes = ['green','turqoise','blue','purple'],
randomTheme = Math.floor(Math.random() * 4),
array_ID = ['#unit','#atm','#sun','#wind'],
SettingsListLi = $('#settings ul li, .search-container'),
SettingsArray = [],
info = {
"Char":[
"Invalid Characters! 😡","Please use only letters! (aA-zZ) "
],
"Loc":[
"Invalid Location 📍","Please update your location!"
],
"Loading":[
"Searching for location...","Location found!"
],
"Loading2":[
"Saving, Please wait...","Save Complete!"
],
"GetDataError":[
"Huston, we have a problem 🚀🌑","This city doesn't exist!"
],
"NotEnoughCharacters":[
"🏙️ Name is too short!","Please enter at least 4 letters"
]
};
//End Caching DOM elements
var CurrentSlide = 0,
CurrentSlideX = [0,358,718],
GetData = true,
tmp_Location,
LocalSettings,
LoadedData;
// Load Settings from Local Storage
(function(){
LocalSettings = localStorage.getItem('SavedData');
if (LocalSettings === null)
{
var Settings = '1,1,1,1,' + arrayThemes[randomTheme] + ',London';
SettingsArray = Settings.split(',');
getWeather('London', false);
toLocalStorage();
}
else
{
SettingsArray = LocalSettings.split(',');
getWeather(SettingsArray[SettingsArray.length-1], false);
}
tmp_Location = SettingsArray[SettingsArray.length-1];
loadCheckboxSettings();
loadIntro();
console.log("Hello there 😜");
})();
// --------- Start Functions ----------
function getWeather(Loc, ShowLoading){
let query = 'https://query.yahooapis.com/v1/public/yql?q=select units,astronomy,atmosphere,wind,location,item from weather.forecast where woeid in (select woeid from geo.places(1) where text="'+ Loc +'") and u="c"&format=json';
$.getJSON(query, function(data) {
if (data.query.results === null)
{
updateErrorMsg("GetDataError", 0);
tmp_Location = 'Not Found';
}
else
{
if (ShowLoading) updateErrorMsg("Loading", 1);
SettingsArray[SettingsArray.length - 1] = tmp_Location;
LoadedData = data.query.results.channel;
applyData(LoadedData);
}
});
}
function toLocalStorage(){
// Save to local storage
LocalSettings = SettingsArray.toString();
localStorage.setItem('SavedData', LocalSettings);
}
function weatherIcon(d){
let icon = "";
switch(Math.floor(d)) {
case 0: icon = 'wi wi-tornado'; break;
case 1: case 3: case 4: icon = 'wi wi-thunderstorm'; break;
case 2: icon = 'wi wi-hurricane'; break;
case 5: icon = 'wi wi-rain-mix'; break;
case 6: case 7: icon = 'wi wi-sleet'; break;
case 8: case 9: icon = 'wi wi-raindrops'; break;
case 10: icon = 'wi wi-sprinkle'; break;
case 11: case 12: icon = 'wi wi-showers'; break;
case 13: case 14: icon = 'wi wi-snowflake-cold'; break;
case 15: case 16: icon = 'wi wi-snow-wind'; break;
case 17: icon = 'wi wi-hail'; break;
case 18: icon = 'wi wi-sleet'; break;
case 19: icon = 'wi wi-dust'; break;
case 20: icon = 'wi wi-fog'; break;
case 21: icon = 'wi wi-day-haze'; break;
case 22: icon = 'wi wi-smog'; break;
case 23: icon = 'wi wi-strong-wind'; break;
case 24: icon = 'wi wi-windy'; break;
case 25: icon = 'wi wi-thermometer-exterior'; break;
case 26:case 27:case 28:case 29:case 30:icon = 'wi wi-cloudy'; break;
case 31: case 33: icon = 'wi wi-night-clear'; break;
case 32: case 34: icon = 'wi wi-day-sunny'; break;
case 35: icon = 'wi wi-hail'; break;
case 36: icon = 'wi wi-hot'; break;
case 37:case 38:case 39:icon = 'wi wi-thunderstorm'; break;
case 40: icon = 'wi wi-showers'; break;
case 41:case 42:case 43:icon = 'wi wi-snow'; break;
case 44: icon = 'wi wi-cloudy'; break;
default: icon = 'wi wi-na';
}
return icon;
}
// Location
var $locspan = $('#location span'),
$datespan = $('#date span'),
$ctbicon = $("#ctbicon"),
$ctb = $("#ctb"),
$icontempi = $('#icon-temp i'),
$icontempp = $('#icon-temp p');
//Atmospheric Conditions
var $atm = $('#atm'),
$atmli = $('#atmli'),
$hd = $('#hd'),
$pd = $('#pd'),
$vd = $('#vd');
//Sunrise/Sunset
var $sun = $('#sun'),
$sunli = $('#sunli'),
$srd = $('#srd'),
$ssd = $('#ssd'),
$td = $('#td');
// Wind Conditions
var $wind = $('#wind'),
$windli = $('#windli'),
$sd = $('#sd'),
$cd = $('#cd'),
$dd = $('#dd'),
$directioni = $('#direction i');
var $10days = $('.day10item');
function applyData(d){
//Location
$locspan.text(d.location.city);
let datespan = d.item.pubDate.split(" "), datespantext = "";
for ( var date_i = 0; date_i < datespan.length - 3; date_i++ ){
datespantext += " ";
datespantext += datespan[date_i];
}
$datespan.text(datespantext);
// Central Info
let currentTemp = d.item.condition.temp;
let icon = weatherIcon(d.item.condition.code);
if (SettingsArray[0] == 1)
{
$ctbicon.text(" ºC");
}
else
{
$ctbicon.text(" ºF");
currentTemp = (convertToF(currentTemp)).replace(" ºF","");
}
$ctb.text(currentTemp);
$icontempi.removeClass().addClass(icon);
$icontempp.text(d.item.condition.text);
// Atmospheric
if ($atm.prop('checked') === true)
{
$atmli.removeClass().addClass('aswshown');
let pressure = d.atmosphere.pressure;
let visib = d.atmosphere.visibility;
if (SettingsArray[0] == 1)
{
pressure = Math.round((pressure * 0.02953)/1.3332239)+ " mmHg";
visib = Math.round(visib) + " " + d.units.distance;
}
else
{
pressure = Math.round(pressure * 0.02953) + " in";
visib = convertToMiles(visib) + " mi";
}
$hd.text(d.atmosphere.humidity + "%");
$pd.text(pressure);
$vd.text(visib);
}
else
{
$atmli.removeClass().addClass('aswhidden');
}
// Sunrise/Sunset
if ($sun.prop('checked') === true)
{
$sunli.removeClass().addClass('aswshown');
let sunrise = d.astronomy.sunrise.replace(" am","").split(":");
let sunset = d.astronomy.sunset.replace(" pm","").split(":");
if (sunset[1].length < 2)
{
sunset[1] = "0" + sunset[1];
}
if (SettingsArray[0] == 1 )
{
if (sunrise[1] < 10){
sunrise[1] = "0" + sunrise[1];
}
$srd.text(sunrise[0] + ":" + sunrise[1]);
$ssd.text((Math.floor(sunset[0]) + 12) + ":" + sunset[1]);
}
else
{
$srd.text(sunrise[0] + ":" + sunrise[1] + " am");
$ssd.text(sunset[0]+ ":" + sunset[1] + " pm");
}
var hours = 12;
if(sunset[0] > sunrise[0])
{
hours = 11;
}
let totalHours = (Math.floor(sunset[0]) + hours) - Math.floor(sunrise[0]);
let minDif,
sr = Math.floor(sunrise[1]), // Store the minutes for sunrise
ss = Math.floor(sunset[1]); // Store the minutes for sunset
if (sr < ss)
{
minDif = ss - sr;
}
else
{
minDif = (60 - sr) + ss;
}
if (minDif < 10)
{
minDif = "0" + minDif;
}
else if ( minDif == 60){
minDif = "00";
}
$td.text(totalHours + ":" + minDif);
}
else
{
$sunli.removeClass().addClass('aswhidden');
}
// Wind
if ($wind.prop('checked') === true)
{
$windli.removeClass().addClass('aswshown');
let speedWind = d.wind.speed,
tempChill = d.wind.chill;
if (SettingsArray[0] == 1)
{
speedWind = Math.round(d.wind.speed) + " km/h";
tempChill = convertToC(tempChill);
}
else
{
speedWind = convertToMiles(speedWind) + " mph";
tempChill += " ºF";
}
let iconWind = "";
if (d.wind.direction >= 0 && d.wind.direction <= 90)
{
iconWind = "fa fa-long-arrow-right";
}
else if (d.wind.direction > 90 && d.wind.direction <= 180)
{
iconWind = "fa fa-long-arrow-up";
}
else if (d.wind.direction > 180 && d.wind.direction <= 270)
{
iconWind = "fa fa-long-arrow-left";
}
else if (d.wind.direction > 270 && d.wind.direction <= 360)
{
iconWind = "fa fa-long-arrow-down";
}
$sd.text(speedWind);
$cd.text(tempChill);
$directioni.removeClass().addClass(iconWind);
$dd.text(d.wind.direction + " º");
}
else
{
$windli.removeClass().addClass('aswhidden');
}
// 9 Days forecast
for (var item = 0; item < $10days.length; item++)
{
let CurrentDay = d.item.forecast[item + 1].day;
let CurrentTemp = d.item.forecast[item + 1].high;
let CurrentTempLow = d.item.forecast[item + 1].low;
let CurrentIcon = weatherIcon(d.item.forecast[item + 1].code);
if (SettingsArray[0] == 1)
{
CurrentTemp += " ºC";
CurrentTempLow += " ºC";
}
else
{
CurrentTemp = convertToF(CurrentTemp);
CurrentTempLow = convertToF(CurrentTempLow);
}
$($10days[item]).find('i').removeClass().addClass(CurrentIcon);
$($10days[item]).find('span').html(CurrentDay + "</br><i>" + CurrentTemp + " <strong>/</strong> " + CurrentTempLow + "</i>");
}
}
function loadCheckboxSettings(){
// General Settings
for (var i = 0; i < array_ID.length; i++)
{
if (SettingsArray[i] == '1')
{
$(array_ID[i]).prop('checked',true);
}
}
// Apply theme
$Main.addClass(SettingsArray[SettingsArray.length-2] + ' poor-Mozilla');
$('span.' + SettingsArray[SettingsArray.length-2]).addClass('current');
}
function loadIntro(){
$('#btn-right').css('display','none');
$('#weather-menu-btn').css("display", "none");
$('#introscreen').addClass('sunloading');
setTimeout(function(){
$('#introscreen').addClass('animfin');
$('#btn-right').removeAttr('style');
$('#weather-menu-btn').removeAttr('style');
}, 650);
setTimeout(function(){
$('#introscreen').remove();
}, 1350);
setTimeout(function(){
$('#forget').addClass('hide');
}, 7500);
}
function convertToF(temp){
return Math.round(temp * 9 / 5 + 32) + ' ºF';
}
function convertToC(temp){
return Math.round((temp - 32)/(9 / 5)) + ' ºC';
}
function convertToMiles(speed){
return Math.round(speed / 1.60934);
}
// --------- Start Function Buttons -----------
// Update Checkbox
$('input[type=checkbox]').on('change', function(e){
let index = $('input[type=checkbox]').index(this);
if ($(this).prop('checked'))
{
SettingsArray[index] = '1';
}
else
{
SettingsArray[index] = '0';
}
});
// Open Settings Menu
$('#main').on('click','#btn-right, #weather-menu-btn', function(e){
e.preventDefault();
var $CurrentButton = $(this);
if ($CurrentButton.is('#btn-right'))
{
$RightButton.toggleClass('open');
$RightMenu.toggleClass('show');
$('body').removeAttr('class');
if ($RightMenu.hasClass('show'))
{
$RightButton.prop('disabled', true);
$Main.removeClass('poor-Mozilla');
$('body').addClass(SettingsArray[4]);
for (var ii = 0; ii < SettingsListLi.length; ii++){
AnimiateLiMenu(ii, SettingsListLi[ii], 0);
}
setTimeout(function()
{
$RightButton.prop('disabled', false);
$Main.addClass('poor-Mozilla');
}, 595);
}
else if ($RightMenu.hasClass(''))
{
$RightButton.prop('disabled', true);
$Main.removeClass('poor-Mozilla');
if (LoadedData != null){
applyData(LoadedData);
}
$('body').removeAttr('class');
setTimeout(function()
{
$RightButton.prop('disabled', false);
for (var ii = 0; ii < SettingsListLi.length; ii++){
AnimiateLiMenu(ii, SettingsListLi[ii], 1);
}
$Main.addClass('poor-Mozilla');
}, 595);
}
}
else if ($CurrentButton.is('#weather-menu-btn'))
{
$WeatherMenu.toggleClass('show');
if ($TempDiv.hasClass(''))
{
$TempDiv.addClass('weather-menu-show');
}
else
{
$TempDiv.removeClass('weather-menu-show');
}
}
function AnimiateLiMenu(Step, currentLi, AddRemove) {
if (AddRemove === 0){
setTimeout(function() {
$(currentLi).addClass('slideAnimation');
}, Step * 35);
}
else{
$(currentLi).removeClass('slideAnimation');
}
}
});
// Error Button
$('#info-msg').on('click','#ok-btn', function(e){
if ($Info.hasClass('show'))
{
$Info.removeClass('show');
$InfoMsgBx.removeClass('open');
setTimeout(function(){
$InfoMsgBx.find('#ok-btn').remove();
}, 1000);
}
});
function updateErrorMsg(value, type){
$Info.addClass('show');
$InfoMsgBx.addClass('open');
$InfoMsgBxH1.text(info[value][0]);
$InfoMsgBxP.text(info[value][1]);
if (type === 0)
{
$InfoMsgBx.append("<div id='ok-btn'>Ok</div>");
}
else
{
$InfoMsgBx.append("<div class='loader'></div>");
$InfoMsgBxP.addClass('hide');
setTimeout(function(){
$InfoMsgBx.find('.loader').addClass('hide').remove();
$InfoMsgBxP.removeClass('hide').addClass('show, load');
setTimeout(function(){
$Info.removeClass('show');
$InfoMsgBx.removeClass('open');
setTimeout(function(){
$InfoMsgBxP.removeAttr('class');
}, 500);
}, 1250);
}, 1750);
}
}
// End Error Button
// Change Theme
$('.row').on('click','span', function(e){
var new_theme = $(this).attr('class').split(' ');
if (new_theme[1] != 'current')
{
$('.row span.' + SettingsArray[4]).removeClass('current');
$(this).addClass('current');
SettingsArray[4] = new_theme[0];
}
$Main.removeAttr('class').addClass(SettingsArray[4] + ' poor-Mozilla');
$('body').removeAttr('class').addClass(SettingsArray[4]);
});
// Update Button
function isValid(string) {
var char = '~`!#$%^&*+=[]\';,/{}|\":<>?@1234567890';
for (var i = 0; i < string.length; i++)
{
if (char.indexOf(string.charAt(i)) != -1)
{
return false;
}
}
return true;
}
function checkBlank(string) {
var count = 0;
for (var i = 0; i < string.length; i++)
{
if (string[i] == " ")
{
count += 1;
}
}
if (string.length == count || string.length <= 3)
{
return false;
}
else
{
return true;
}
}
$('#settings').on('click','#update-button', function(e){
tmp_Location = $('#search').val();
if (tmp_Location === "")
{
tmp_Location = SettingsArray[5];
GetData = true;
}
else
{
var CheckForInvalid = isValid(tmp_Location);
var CheckForBlank = checkBlank(tmp_Location);
if ($RightMenu.hasClass('show') && (!CheckForInvalid || !CheckForBlank))
{
GetData = false;
if (!CheckForBlank)
{
updateErrorMsg('NotEnoughCharacters', 0);
}
else
{
updateErrorMsg('Char', 0);
}
}
else
{
if (SettingsArray[5] != tmp_Location)
{
getWeather(tmp_Location, true);
GetData = true;
}
}
}
});
// End Update Button
// Save button
$('#settings').on('click','#save-button', function(e){
// Check if location is valid or not and add the info msg.
if ($RightMenu.hasClass('show') && (GetData === false))
{
updateErrorMsg('Loc', 0);
}
else
{
updateErrorMsg('Loading2', 1);
toLocalStorage();
}
});
// Dot Menu
$('#weather-menu').on('click','.day_left, .day_right, #dotmenu span', function(){
var $button = $(this);
var $currentDay = $('#dotmenu .currentday');
if ($button.hasClass('day_right') && CurrentSlide != 2)
{
CurrentSlide += 1;
}
else if ($button.hasClass('day_left') && CurrentSlide !== 0)
{
CurrentSlide -= 1;
}
else if ($button.hasClass(''))
{
var indexbtn = $button.index();
CurrentSlide = indexbtn;
}
$LiRow.css('transform', 'translateX(-' + CurrentSlideX[CurrentSlide] + 'px)');
$currentDay.removeClass('currentday');
$DotMenu.eq(CurrentSlide).addClass('currentday');
});
//----------- End Function Buttons -----------
//----------- End Function -----------
}); // End $(document).ready
This Pen doesn't use any external CSS resources.