Merge branch 'esthetic' into main
This commit is contained in:
commit
95fc9737e7
236
public/css/buttons.css
Normal file
236
public/css/buttons.css
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/* from https://codepen.io/ben_jammin/pen/syaCq */
|
||||||
|
|
||||||
|
.button::-moz-focus-inner{
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button{
|
||||||
|
display: inline-block;
|
||||||
|
*display: inline;
|
||||||
|
zoom: 1;
|
||||||
|
padding: 6px 20px;
|
||||||
|
margin: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
overflow: visible;
|
||||||
|
font: bold 13px arial, helvetica, sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #555;
|
||||||
|
|
||||||
|
background-color: #ddd;
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,1)), to(rgba(255,255,255,0)));
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||||
|
background-image: -moz-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||||
|
background-image: -ms-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||||
|
background-image: -o-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||||
|
background-image: linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||||
|
|
||||||
|
-webkit-transition: background-color .2s ease-out;
|
||||||
|
-moz-transition: background-color .2s ease-out;
|
||||||
|
-ms-transition: background-color .2s ease-out;
|
||||||
|
-o-transition: background-color .2s ease-out;
|
||||||
|
transition: background-color .2s ease-out;
|
||||||
|
background-clip: padding-box; /* Fix bleeding */
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
-moz-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
|
||||||
|
-webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
|
||||||
|
text-shadow: 0 1px 0 rgba(255,255,255, .9);
|
||||||
|
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover{
|
||||||
|
background-color: #eee;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active{
|
||||||
|
background: #e9e9e9;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
text-shadow: none;
|
||||||
|
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
|
||||||
|
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
|
||||||
|
box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button[disabled], .button[disabled]:hover, .button[disabled]:active{
|
||||||
|
border-color: #eaeaea;
|
||||||
|
background: #fafafa;
|
||||||
|
cursor: default;
|
||||||
|
position: static;
|
||||||
|
color: #999;
|
||||||
|
/* Usually, !important should be avoided but here it's really needed :) */
|
||||||
|
-moz-box-shadow: none !important;
|
||||||
|
-webkit-box-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smaller buttons styles */
|
||||||
|
|
||||||
|
.button.small{
|
||||||
|
padding: 4px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Larger buttons styles */
|
||||||
|
|
||||||
|
.button.large{
|
||||||
|
padding: 12px 30px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.large:active{
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Colored buttons styles */
|
||||||
|
|
||||||
|
.button.green, .button.red, .button.blue {
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 1px 0 rgba(0,0,0,.2);
|
||||||
|
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.3)), to(rgba(255,255,255,0)));
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
||||||
|
background-image: -moz-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
||||||
|
background-image: -ms-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
||||||
|
background-image: -o-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
||||||
|
background-image: linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.button.green{
|
||||||
|
background-color: #57a957;
|
||||||
|
border-color: #57a957;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.green:hover{
|
||||||
|
background-color: #62c462;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.green:active{
|
||||||
|
background: #57a957;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.button.red{
|
||||||
|
background-color: #ca3535;
|
||||||
|
border-color: #c43c35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.red:hover{
|
||||||
|
background-color: #ee5f5b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.red:active{
|
||||||
|
background: #c43c35;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.button.blue{
|
||||||
|
background-color: #269CE9;
|
||||||
|
border-color: #269CE9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.blue:hover{
|
||||||
|
background-color: #70B9E8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.blue:active{
|
||||||
|
background: #269CE9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.green[disabled], .green[disabled]:hover, .green[disabled]:active{
|
||||||
|
border-color: #57A957;
|
||||||
|
background: #57A957;
|
||||||
|
color: #D2FFD2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red[disabled], .red[disabled]:hover, .red[disabled]:active{
|
||||||
|
border-color: #C43C35;
|
||||||
|
background: #C43C35;
|
||||||
|
color: #FFD3D3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue[disabled], .blue[disabled]:hover, .blue[disabled]:active{
|
||||||
|
border-color: #269CE9;
|
||||||
|
background: #269CE9;
|
||||||
|
color: #93D5FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Group buttons */
|
||||||
|
|
||||||
|
.button-group,
|
||||||
|
.button-group li{
|
||||||
|
display: inline-block;
|
||||||
|
*display: inline;
|
||||||
|
zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group{
|
||||||
|
font-size: 0; /* Inline block elements gap - fix */
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: rgba(0, 0, 0, .1);
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, .1);
|
||||||
|
padding: 7px;
|
||||||
|
-moz-border-radius: 7px;
|
||||||
|
-webkit-border-radius: 7px;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group li{
|
||||||
|
margin-right: -1px; /* Overlap each right button border */
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group .button{
|
||||||
|
font-size: 13px; /* Set the font size, different from inherited 0 */
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group .button:active{
|
||||||
|
-moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group li:first-child .button{
|
||||||
|
-moz-border-radius: 3px 0 0 3px;
|
||||||
|
-webkit-border-radius: 3px 0 0 3px;
|
||||||
|
border-radius: 3px 0 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group li:first-child .button:active{
|
||||||
|
-moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group li:last-child .button{
|
||||||
|
-moz-border-radius: 0 3px 3px 0;
|
||||||
|
-webkit-border-radius: 0 3px 3px 0;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group li:last-child .button:active{
|
||||||
|
-moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
|
||||||
|
}
|
BIN
public/favicon.png
Normal file
BIN
public/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
public/fonts/dosis/Dosis-VariableFont_wght.ttf
Normal file
BIN
public/fonts/dosis/Dosis-VariableFont_wght.ttf
Normal file
Binary file not shown.
95
public/fonts/dosis/OFL.txt
Normal file
95
public/fonts/dosis/OFL.txt
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
Copyright (c) 2011, Edgar Tolentino and Pablo Impallari (www.impallari.com|impallari@gmail.com),
|
||||||
|
Copyright (c) 2011, Igino Marini. (www.ikern.com|mail@iginomarini.com),
|
||||||
|
with Reserved Font Names "Dosis".
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
69
public/fonts/dosis/README.txt
Normal file
69
public/fonts/dosis/README.txt
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
Dosis Variable Font
|
||||||
|
===================
|
||||||
|
|
||||||
|
This download contains Dosis as both a variable font and static fonts.
|
||||||
|
|
||||||
|
Dosis is a variable font with this axis:
|
||||||
|
wght
|
||||||
|
|
||||||
|
This means all the styles are contained in a single file:
|
||||||
|
Dosis-VariableFont_wght.ttf
|
||||||
|
|
||||||
|
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||||
|
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||||
|
in those cases you can use the static font files for Dosis:
|
||||||
|
static/Dosis-ExtraLight.ttf
|
||||||
|
static/Dosis-Light.ttf
|
||||||
|
static/Dosis-Regular.ttf
|
||||||
|
static/Dosis-Medium.ttf
|
||||||
|
static/Dosis-SemiBold.ttf
|
||||||
|
static/Dosis-Bold.ttf
|
||||||
|
static/Dosis-ExtraBold.ttf
|
||||||
|
|
||||||
|
Get started
|
||||||
|
-----------
|
||||||
|
|
||||||
|
1. Install the font files you want to use
|
||||||
|
|
||||||
|
2. Use your app's font picker to view the font family and all the
|
||||||
|
available styles
|
||||||
|
|
||||||
|
Learn more about variable fonts
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||||
|
https://variablefonts.typenetwork.com
|
||||||
|
https://medium.com/variable-fonts
|
||||||
|
|
||||||
|
In desktop apps
|
||||||
|
|
||||||
|
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||||
|
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||||
|
|
||||||
|
Online
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/getting_started
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||||
|
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||||
|
|
||||||
|
Installing fonts
|
||||||
|
|
||||||
|
MacOS: https://support.apple.com/en-us/HT201749
|
||||||
|
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||||
|
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||||
|
|
||||||
|
Android Apps
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/android
|
||||||
|
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Please read the full license text (OFL.txt) to understand the permissions,
|
||||||
|
restrictions and requirements for usage, redistribution, and modification.
|
||||||
|
|
||||||
|
You can use them freely in your products & projects - print or digital,
|
||||||
|
commercial or otherwise. However, you can't sell the fonts on their own.
|
||||||
|
|
||||||
|
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||||
|
license for all details.
|
4
public/fonts/dosis/dosis.css
Normal file
4
public/fonts/dosis/dosis.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Dosis';
|
||||||
|
src: url(Dosis-VariableFont_wght.ttf) format('truetype');
|
||||||
|
}
|
BIN
public/fonts/dosis/static/Dosis-Bold.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-Bold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-ExtraBold.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-ExtraLight.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-Light.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-Light.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-Medium.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-Medium.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-Regular.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-Regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/dosis/static/Dosis-SemiBold.ttf
Normal file
BIN
public/fonts/dosis/static/Dosis-SemiBold.ttf
Normal file
Binary file not shown.
5
public/fonts/faktos.css
Normal file
5
public/fonts/faktos.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Faktos';
|
||||||
|
font-style: normal;
|
||||||
|
src: url(Faktos.ttf) format('truetype');
|
||||||
|
}
|
@ -1,11 +1,28 @@
|
|||||||
:root {
|
:root {
|
||||||
--font-scale-8: calc(1rem/1.125/1.125);
|
--font-scale-9: 0.75rem;
|
||||||
--font-scale-9: calc(1rem/1.125);
|
--font-scale-10: 1em;
|
||||||
--font-scale-10: 1rem;
|
--font-scale-11: 1.333rem;
|
||||||
--font-scale-11: calc(1rem * 1.125);
|
--font-scale-12: 1.777rem;
|
||||||
--font-scale-12: calc(1rem * 1.125 * 1.125);
|
--font-scale-13: 2.369rem;
|
||||||
|
--font-scale-14: 3.157rem;
|
||||||
|
--font-scale-15: 4.209rem;
|
||||||
|
|
||||||
|
--oxford-blue: hsla(226, 60%, 10%, 1);
|
||||||
|
--royal-blue-dark: hsla(218, 100%, 16%, 1);
|
||||||
|
--indigo-dye: hsla(209, 95%, 24%, 1);
|
||||||
|
--cg-blue: hsla(193, 80%, 35%, 1);
|
||||||
|
--white: hsla(20, 60%, 99%, 1);
|
||||||
|
|
||||||
|
--main-width: 60em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
small {font-size: var(--font-scale-9); }
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
font-size: var(--font-scale-14);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
@ -15,11 +32,12 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
background-color: var(--white);
|
||||||
color: #333;
|
color: #333;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
font-family: "Dosis", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -74,3 +92,18 @@ button:not(:disabled):active {
|
|||||||
button:focus {
|
button:focus {
|
||||||
border-color: #666;
|
border-color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- inputs --- */
|
||||||
|
|
||||||
|
input, select {
|
||||||
|
border: 0px;
|
||||||
|
border-bottom: 1px solid var(--indigo-dye);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus, select:focus {
|
||||||
|
border: 1px solid var(--indigo-dye);;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.short {
|
||||||
|
width:5em;
|
||||||
|
}
|
||||||
|
@ -4,14 +4,18 @@
|
|||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||||
|
|
||||||
<title>Svelte app</title>
|
<title>The Shipyard</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./fonts/faktos.css">
|
||||||
|
<link rel="stylesheet" href="./fonts/dosis/dosis.css">
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
<link rel='icon' type='image/png' href='/favicon.png'>
|
||||||
<link rel='stylesheet' href='./global.css'>
|
<link rel='stylesheet' href='./global.css'>
|
||||||
|
<link rel='stylesheet' href='./css/buttons.css'>
|
||||||
<link rel='stylesheet' href='./bundle.css'>
|
<link rel='stylesheet' href='./bundle.css'>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
114
src/App.svelte
114
src/App.svelte
@ -1,114 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { setContext } from 'svelte';
|
|
||||||
|
|
||||||
import shipStore from './stores/ship';
|
|
||||||
|
|
||||||
import ShipItem from './components/ShipItem/index.svelte';
|
|
||||||
import ShipCost from './components/ShipCost.svelte';
|
|
||||||
import Field from './components/Field/index.svelte';
|
|
||||||
import Hull from './components/Hull.svelte';
|
|
||||||
import Identification from './components/Identification.svelte';
|
|
||||||
import Firecons from './components/Firecons.svelte';
|
|
||||||
import Propulsion from './components/Propulsion/index.svelte';
|
|
||||||
import Section from '~C/Section';
|
|
||||||
import Weapon from '~C/Weapon';
|
|
||||||
import Cargo from '~C/Cargo/index.svelte';
|
|
||||||
import Streamlining from '~C/Streamlining/index.svelte';
|
|
||||||
import Carrier from '~C/Carrier';
|
|
||||||
import ADFC from '~C/Weaponry/ADFC';
|
|
||||||
import AddWeapon from '~C/Weaponry/AddWeapon';
|
|
||||||
|
|
||||||
const ship = shipStore();
|
|
||||||
|
|
||||||
setContext('ship',ship);
|
|
||||||
|
|
||||||
let ship_name = $ship.general.name;
|
|
||||||
|
|
||||||
const change_name = event => ship.dispatch(
|
|
||||||
ship.actions.set_name( event.target.value) );
|
|
||||||
|
|
||||||
const change_mass = ({target: {value}}) => ship.dispatch(ship.actions.set_ship_mass(parseInt(value)));
|
|
||||||
|
|
||||||
const add_weapon = () => ship.dispatch.add_weapon();
|
|
||||||
|
|
||||||
const change_ftl = ({detail}) => ship.dispatch.set_ftl(detail);
|
|
||||||
const change_engine = ({detail}) => ship.dispatch.set_engine(detail);
|
|
||||||
const change_hull = ({detail}) => ship.dispatch.set_hull(detail);
|
|
||||||
const change_firecons = ({detail}) => ship.dispatch.set_firecons(detail);
|
|
||||||
const change_weapon = ({detail}) => ship.dispatch.set_weapon(detail);
|
|
||||||
|
|
||||||
let weapons = [];
|
|
||||||
$: console.log(weapons);
|
|
||||||
$: weapons= $ship.weaponry.weapons;
|
|
||||||
|
|
||||||
const reset = ship.dispatch.reset;
|
|
||||||
|
|
||||||
const set_screens = ({detail}) => ship.dispatch.set_screens(detail);
|
|
||||||
|
|
||||||
const ship_dispatch = ({detail}) => ship.dispatch(detail);
|
|
||||||
|
|
||||||
setContext( 'ship_change', ship.dispatch );
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<input class="reset" type="button" value="reset" on:click={reset} />
|
|
||||||
|
|
||||||
<Identification />
|
|
||||||
|
|
||||||
<ShipCost />
|
|
||||||
|
|
||||||
<Propulsion
|
|
||||||
ftl={$ship.ftl}
|
|
||||||
engine={$ship.engine}
|
|
||||||
on:change_ftl={change_ftl}
|
|
||||||
on:change_engine={change_engine}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Hull ship_mass={$ship.general.mass}
|
|
||||||
{ ... $ship.structure.hull }
|
|
||||||
on:change_hull={change_hull}
|
|
||||||
screens={ $ship.structure.screens}
|
|
||||||
armour={$ship.structure.armour}
|
|
||||||
on:set_screens={set_screens}
|
|
||||||
on:ship_change={ship_dispatch}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<Section label="weaponry">
|
|
||||||
<Firecons { ... $ship.weaponry.firecons }
|
|
||||||
on:change_firecons={ change_firecons }/>
|
|
||||||
|
|
||||||
<ADFC {...$ship.weaponry.adfc } />
|
|
||||||
|
|
||||||
<AddWeapon />
|
|
||||||
|
|
||||||
{#each weapons as weapon (weapon.id)}
|
|
||||||
<Weapon {weapon} id={weapon.id} cost={weapon.cost} mass={weapon.mass} />
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<Section label="misc">
|
|
||||||
<Cargo {...$ship.cargo} on:set_cargo={ship_dispatch}/>
|
|
||||||
<Streamlining {...$ship.streamlining} />
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<Carrier {...$ship.carrier} />
|
|
||||||
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
main {
|
|
||||||
display: grid;
|
|
||||||
width: 60em;
|
|
||||||
grid-template-columns: 4fr 1fr 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
main :global(> *) {
|
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.reset { grid-column: 2 }
|
|
||||||
</style>
|
|
113
src/components/App.svelte
Normal file
113
src/components/App.svelte
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<nav>
|
||||||
|
<input class="reset button small red" type="button" value="reset" on:click={reset} />
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<ShipSpecs />
|
||||||
|
|
||||||
|
<Propulsion
|
||||||
|
ftl={$ship.ftl}
|
||||||
|
engine={$ship.engine}
|
||||||
|
on:change_ftl={change_ftl}
|
||||||
|
on:change_engine={change_engine} />
|
||||||
|
|
||||||
|
<Hull
|
||||||
|
ship_mass={$ship.general.mass}
|
||||||
|
{...$ship.structure.hull}
|
||||||
|
on:change_hull={change_hull}
|
||||||
|
screens={$ship.structure.screens}
|
||||||
|
armour={$ship.structure.armour}
|
||||||
|
on:set_screens={set_screens}
|
||||||
|
cargo={$ship.cargo}
|
||||||
|
streamlining={$ship.streamlining}
|
||||||
|
on:set_cargo={ship_dispatch}
|
||||||
|
on:ship_change={ship_dispatch} />
|
||||||
|
|
||||||
|
<Section label="weaponry">
|
||||||
|
<Firecons
|
||||||
|
{...$ship.weaponry.firecons}
|
||||||
|
on:change_firecons={change_firecons} />
|
||||||
|
|
||||||
|
<ADFC {...$ship.weaponry.adfc} />
|
||||||
|
|
||||||
|
<AddWeapon />
|
||||||
|
|
||||||
|
{#each weapons as weapon (weapon.id)}
|
||||||
|
<Weapon {weapon} id={weapon.id} cost={weapon.cost} mass={weapon.mass} />
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<Carrier {...$ship.carrier} />
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { setContext } from "svelte";
|
||||||
|
|
||||||
|
import Header from './Header';
|
||||||
|
import shipStore from "~/stores/ship";
|
||||||
|
|
||||||
|
import ShipSpecs from './ShipSpecs/index.svelte';
|
||||||
|
import ShipItem from "./ShipItem/index.svelte";
|
||||||
|
import Field from "./Field/index.svelte";
|
||||||
|
import Hull from "./Hull";
|
||||||
|
import Firecons from "./Firecons.svelte";
|
||||||
|
import Propulsion from "./Propulsion/index.svelte";
|
||||||
|
import Section from "~C/Section";
|
||||||
|
import Weapon from "~C/Weapon";
|
||||||
|
import Carrier from "~C/Carrier";
|
||||||
|
import ADFC from "~C/Weaponry/ADFC";
|
||||||
|
import AddWeapon from "~C/Weaponry/AddWeapon";
|
||||||
|
|
||||||
|
const ship = shipStore();
|
||||||
|
|
||||||
|
setContext("ship", ship);
|
||||||
|
|
||||||
|
let ship_name = $ship.general.name;
|
||||||
|
|
||||||
|
const change_name = (event) =>
|
||||||
|
ship.dispatch(ship.actions.set_name(event.target.value));
|
||||||
|
|
||||||
|
const change_mass = ({ target: { value } }) =>
|
||||||
|
ship.dispatch(ship.actions.set_ship_mass(parseInt(value)));
|
||||||
|
|
||||||
|
const add_weapon = () => ship.dispatch.add_weapon();
|
||||||
|
|
||||||
|
const change_ftl = ({ detail }) => ship.dispatch.set_ftl(detail);
|
||||||
|
const change_engine = ({ detail }) => ship.dispatch.set_engine(detail);
|
||||||
|
const change_hull = ({ detail }) => ship.dispatch.set_hull(detail);
|
||||||
|
const change_firecons = ({ detail }) => ship.dispatch.set_firecons(detail);
|
||||||
|
const change_weapon = ({ detail }) => ship.dispatch.set_weapon(detail);
|
||||||
|
|
||||||
|
let weapons = [];
|
||||||
|
$: console.log(weapons);
|
||||||
|
$: weapons = $ship.weaponry.weapons;
|
||||||
|
|
||||||
|
const reset = ship.dispatch.reset;
|
||||||
|
|
||||||
|
const set_screens = ({ detail }) => ship.dispatch.set_screens(detail);
|
||||||
|
|
||||||
|
const ship_dispatch = ({ detail }) => ship.dispatch(detail);
|
||||||
|
|
||||||
|
setContext("ship_change", ship.dispatch);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
width: 60em;
|
||||||
|
grid-template-columns: 1fr 14em 8em;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main :global(> *) {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.reset {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
</style>
|
@ -35,4 +35,5 @@ div {
|
|||||||
align-items: end;
|
align-items: end;
|
||||||
}
|
}
|
||||||
label { margin-left: 2em; }
|
label { margin-left: 2em; }
|
||||||
|
input[type="number"] { width: 5em; }
|
||||||
</style>
|
</style>
|
||||||
|
@ -14,7 +14,16 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
div > :global(*) {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
div > label {
|
||||||
|
margin-left: 0em;
|
||||||
|
}
|
||||||
label {
|
label {
|
||||||
font-size: var(--font-scale-8);
|
font-size: var(--font-scale-8);
|
||||||
|
font-weight: lighter;
|
||||||
|
font-family: Dosis;
|
||||||
|
color: var(--indigo-dye);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<ShipItem {cost} {mass}>
|
<ShipItem {cost} {mass}>
|
||||||
<Field label="firecons">
|
<Field label="firecons">
|
||||||
<input type="number" bind:value={nbr} />
|
<input type="number" class="short" bind:value={nbr} />
|
||||||
</Field>
|
</Field>
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
|
28
src/components/Header.svelte
Normal file
28
src/components/Header.svelte
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<header>
|
||||||
|
<h1>The Shipyard</h1>
|
||||||
|
<h2>a <a
|
||||||
|
href="https://shop.groundzerogames.co.uk/rules.html">Full Thrust</a> ship builder</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: var(--main-width);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
h1, h2 {
|
||||||
|
font-family: Faktos;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: right;
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 2em;
|
||||||
|
font-size: var(--font-scale-12);
|
||||||
|
}
|
||||||
|
</style>
|
@ -21,3 +21,9 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -49,4 +49,8 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<ShipItem { cost } { mass }>
|
<ShipItem { cost } { mass }>
|
||||||
|
<div>
|
||||||
|
|
||||||
<Field label="screens">
|
<Field label="screens">
|
||||||
<input type="number" bind:value={standard} min="0" />
|
<input type="number" bind:value={standard} min="0" />
|
||||||
@ -8,6 +8,7 @@
|
|||||||
<Field label="advanced screens">
|
<Field label="advanced screens">
|
||||||
<input type="number" bind:value={advanced} min="0" />
|
<input type="number" bind:value={advanced} min="0" />
|
||||||
</Field>
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
@ -34,4 +35,8 @@
|
|||||||
input {
|
input {
|
||||||
width: 3em;
|
width: 3em;
|
||||||
}
|
}
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,12 +1,16 @@
|
|||||||
<ShipItem {cost} {mass}>
|
<ShipItem {cost} {mass}>
|
||||||
<Field label="streamlining">
|
<Field label="streamlining">
|
||||||
<div>
|
<div>
|
||||||
|
<label>
|
||||||
<input type="radio" bind:group={type} value="none" />
|
<input type="radio" bind:group={type} value="none" />
|
||||||
<label>none</label>
|
none</label>
|
||||||
|
<label>
|
||||||
|
|
||||||
<input type="radio" bind:group={type} value="partial" />
|
<input type="radio" bind:group={type} value="partial" />
|
||||||
<label>partial</label>
|
partial</label>
|
||||||
|
<label>
|
||||||
<input type="radio" bind:group={type} value="full" />
|
<input type="radio" bind:group={type} value="full" />
|
||||||
<label>full</label>
|
full</label>
|
||||||
</div>
|
</div>
|
||||||
</Field>
|
</Field>
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
@ -30,4 +34,7 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
div { display: flex }
|
div { display: flex }
|
||||||
|
label {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -13,6 +13,9 @@
|
|||||||
|
|
||||||
<Armour {armour} on:ship_change />
|
<Armour {armour} on:ship_change />
|
||||||
|
|
||||||
|
<Cargo {...cargo} on:set_cargo />
|
||||||
|
|
||||||
|
<Streamlining {...streamlining} />
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -23,11 +26,16 @@
|
|||||||
import ShipItem from '~C/ShipItem';
|
import ShipItem from '~C/ShipItem';
|
||||||
import Screens from './Screens';
|
import Screens from './Screens';
|
||||||
import Armour from './Armour';
|
import Armour from './Armour';
|
||||||
|
import Cargo from './Cargo';
|
||||||
|
import Streamlining from './Streamlining';
|
||||||
|
|
||||||
export let cost, mass, ship_mass, rating, screens, armour = (
|
export let cost, mass, ship_mass, rating, screens, armour = (
|
||||||
0, 0, 10, 1, [], []
|
0, 0, 10, 1, [], []
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export let cargo = {};
|
||||||
|
export let streamlining = {};
|
||||||
|
|
||||||
let min, max;
|
let min, max;
|
||||||
$: min = Math.ceil(ship_mass / 10);
|
$: min = Math.ceil(ship_mass / 10);
|
||||||
$: max = ship_mass;
|
$: max = ship_mass;
|
||||||
@ -39,4 +47,5 @@ const dispatch = createEventDispatcher();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
input { width: 5em; }
|
||||||
</style>
|
</style>
|
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
<Section label="propulsion">
|
<Section label="propulsion">
|
||||||
|
|
||||||
<Ftl {...ftl} on:change_ftl />
|
|
||||||
|
|
||||||
<Engine {...engine} on:change_engine />
|
<Engine {...engine} on:change_engine />
|
||||||
|
|
||||||
|
<Ftl {...ftl} on:change_ftl />
|
||||||
|
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,8 +1,23 @@
|
|||||||
<fieldset>
|
<div>
|
||||||
<legend>{label}</legend>
|
<h2>{label}</h2>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export let label;
|
export let label;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
grid-column: 1 / span 3 !important;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
flex: 1;
|
||||||
|
heigth: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
<div class="ship_cost">
|
|
||||||
<div>
|
|
||||||
<label>Ship tonnage</label>
|
|
||||||
<input
|
|
||||||
value={$ship.general.mass}
|
|
||||||
on:change={change_tonnage}
|
|
||||||
type="number" min="10" max="300" />
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<div class="note" class:warning={!within_budget}>
|
|
||||||
{#if within_budget}
|
|
||||||
mass unused: { mass_unused }
|
|
||||||
{:else}
|
|
||||||
excessive mass: { -mass_unused }
|
|
||||||
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label>Ship cost</label>
|
|
||||||
<div>{$ship.general.cost}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getContext } from 'svelte';
|
|
||||||
|
|
||||||
export let ship = getContext('ship');
|
|
||||||
|
|
||||||
const change_tonnage =
|
|
||||||
({target: {value}}) =>
|
|
||||||
ship.dispatch(ship.actions.set_ship_mass(parseInt(value)));
|
|
||||||
|
|
||||||
let mass_unused;
|
|
||||||
$: mass_unused = $ship.general.mass - $ship.general.used_mass;
|
|
||||||
|
|
||||||
let within_budget = true;
|
|
||||||
|
|
||||||
$: within_budget = mass_unused >= 0;
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.ship_cost {
|
|
||||||
display: flex;
|
|
||||||
grid-column: span 3;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
.warning {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
.note {
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,9 +1,7 @@
|
|||||||
<div class="ship-item">
|
<div><slot /></div>
|
||||||
<slot />
|
|
||||||
|
|
||||||
<div class="mass" bind:this={mass_el}>{ mass }</div>
|
<div class="mass" bind:this={mass_el}>{ mass }</div>
|
||||||
<div class="cost" bind:this={cost_el}>{ cost }</div>
|
<div class="cost" bind:this={cost_el}>{ cost }</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { tick } from 'svelte';
|
import { tick } from 'svelte';
|
||||||
@ -27,6 +25,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
div {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
}
|
||||||
|
.cost,.mass { padding: 0px 2em; text-align: right; }
|
||||||
|
.cost { grid-column: 3 }
|
||||||
|
.mass { grid-column: 2 }
|
||||||
|
|
||||||
.ship-item {
|
.ship-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@ -35,7 +41,6 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cost,.mass { width: 4em; flex: inherit; }
|
|
||||||
img {
|
img {
|
||||||
width: 0.75em;
|
width: 0.75em;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<div class="identification">
|
<div>
|
||||||
|
|
||||||
<Field label="ship class" value={general.ship_class}
|
<Field label="ship class" value={general.ship_class}
|
||||||
on:change={change_class} />
|
on:change={change_class} />
|
||||||
|
|
||||||
@ -10,13 +9,12 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
|
|
||||||
import Field from './Field/index.svelte';
|
import Field from '~C/Field';
|
||||||
import { candidate_ship_types } from '~/dux/ship_types';
|
import { candidate_ship_types } from '~/dux/ship_types';
|
||||||
|
|
||||||
export let ship = getContext('ship');
|
export let ship = getContext('ship');
|
||||||
@ -41,9 +39,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.identification {
|
div {
|
||||||
grid-column: span 3;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
align-items: end;
|
||||||
|
gap: 2em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
77
src/components/ShipSpecs/ShipCost.svelte
Normal file
77
src/components/ShipSpecs/ShipCost.svelte
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<div class="mass">
|
||||||
|
<Field label="ship tonnage">
|
||||||
|
<input
|
||||||
|
value={$ship.general.mass}
|
||||||
|
on:change={change_tonnage}
|
||||||
|
type="number"
|
||||||
|
min="10"
|
||||||
|
max="300" />
|
||||||
|
<span class="mass_symbol"></span>
|
||||||
|
|
||||||
|
<div class="note" class:warning={!within_budget}>
|
||||||
|
{#if within_budget}
|
||||||
|
mass unused: {mass_unused}
|
||||||
|
{:else}excessive mass: {-mass_unused}{/if}
|
||||||
|
</div>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cost">
|
||||||
|
<Field label="cost">
|
||||||
|
<span class="cost">{$ship.general.cost}</span></Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
import Field from "~C/Field";
|
||||||
|
|
||||||
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
|
const change_tonnage = ({ target: { value } }) =>
|
||||||
|
ship.dispatch(ship.actions.set_ship_mass(parseInt(value)));
|
||||||
|
|
||||||
|
let mass_unused;
|
||||||
|
$: mass_unused = $ship.general.mass - $ship.general.used_mass;
|
||||||
|
|
||||||
|
let within_budget = true;
|
||||||
|
|
||||||
|
$: within_budget = mass_unused >= 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ship_cost {
|
||||||
|
display: flex;
|
||||||
|
grid-column: span 3;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
.mass_symbol:after {
|
||||||
|
content: url(mass.svg);
|
||||||
|
width: 0.75em;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
.warning {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
.note {
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mass,div.cost {
|
||||||
|
padding: 0px 2em; justify-self: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mass {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
div.cost {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
span.cost:after {
|
||||||
|
content: '\00A4';
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
16
src/components/ShipSpecs/index.svelte
Normal file
16
src/components/ShipSpecs/index.svelte
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<Identification />
|
||||||
|
|
||||||
|
<ShipCost />
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Identification from "./Identification.svelte";
|
||||||
|
import ShipCost from "./ShipCost.svelte";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,10 +1,14 @@
|
|||||||
<ShipItem {cost} {mass}>
|
<ShipItem {cost} {mass}>
|
||||||
|
|
||||||
<div class="remove" on:click={remove}>X</div>
|
<div class="weapon_row">
|
||||||
|
|
||||||
|
<input type="button" class="button small red remove" value="remove"
|
||||||
|
on:click={remove} />
|
||||||
|
|
||||||
|
|
||||||
<svelte:component this={weapon_component[weapon_type]} {...weapon}
|
<svelte:component this={weapon_component[weapon_type]} {...weapon}
|
||||||
on:change={update}/>
|
on:change={update}/>
|
||||||
|
</div>
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -110,13 +114,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remove {
|
.weapon_row {
|
||||||
width: 1em;
|
display: flex;
|
||||||
flex: 0;
|
gap: 2em;
|
||||||
color: white;
|
align-items: center;
|
||||||
background-color: black;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
height: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
<ShipItem {cost} {mass}>
|
<ShipItem {cost} {mass}>
|
||||||
<Field label="ADFC">
|
<Field label="ADFC">
|
||||||
<input type="number" bind:value={rating} />
|
<input type="number" class="short" bind:value={rating} />
|
||||||
</Field>
|
</Field>
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
<script>
|
|
||||||
import get from 'lodash/get';
|
|
||||||
import ShipItem from '~C/ShipItem/index.svelte';
|
|
||||||
import Field from '~C/Field/index.svelte';
|
|
||||||
import dux from '~/dux';
|
|
||||||
|
|
||||||
import {getContext } from 'svelte';
|
<script>
|
||||||
|
import get from "lodash/get";
|
||||||
|
import ShipItem from "~C/ShipItem/index.svelte";
|
||||||
|
import Field from "~C/Field/index.svelte";
|
||||||
|
import dux from "~/dux";
|
||||||
|
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
export let rating = 0;
|
export let rating = 0;
|
||||||
export let cost = 0;
|
export let cost = 0;
|
||||||
export let mass = 0;
|
export let mass = 0;
|
||||||
export let ship_change = getContext('ship_change') || ( () => {} );
|
export let ship_change = getContext("ship_change") || (() => {});
|
||||||
|
|
||||||
$: ship_change(dux.actions.set_adfc(rating));
|
$: ship_change(dux.actions.set_adfc(rating));
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
div { display: flex }
|
|
||||||
</style>
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<option value="needle">needle weapon</option>
|
<option value="needle">needle weapon</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<input type="button" value="add weapon" on:click={ add_weapon }/>
|
<input type="button" value="add weapon" class="button small blue" on:click={ add_weapon }/>
|
||||||
|
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<input class="add-weapon" type="button" value="add"
|
<input class="add-weapon button small blue" type="button" value="add"
|
||||||
on:click={add} />
|
on:click={add} />
|
||||||
|
|
||||||
<div class="weapon">
|
<div class="weapon">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import App from './App.svelte';
|
import App from './components/App.svelte';
|
||||||
|
|
||||||
const app = new App({
|
const app = new App({
|
||||||
target: document.body
|
target: document.body
|
||||||
|
Loading…
Reference in New Issue
Block a user