You've already forked snikket-web-portal
Design foundations
- Create a colour palette - Create a sizing schema for paddings and fonts - Implement basic form controls - Create a theme demo page - Apply the theme to the existing pages. Still TODO is the final font selection.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.direnv
|
||||
/.local
|
||||
__pycache__
|
||||
/snikket_web/static/css/*.css
|
||||
|
||||
16
Makefile
Normal file
16
Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
scss_files = $(filter-out snikket_web/scss/_%.scss,$(wildcard snikket_web/scss/*.scss))
|
||||
scss_includes = $(filter snikket_web/scss/_%.scss,$(wildcard snikket_web/scss/*.scss))
|
||||
generated_css_files = $(patsubst snikket_web/scss/%.scss,snikket_web/static/css/%.css,$(scss_files))
|
||||
|
||||
PYTHON3 ?= python3
|
||||
SCSSC ?= $(PYTHON3) -m scss --load-path snikket_web/scss/
|
||||
|
||||
build_css: $(generated_css_files)
|
||||
|
||||
$(generated_css_files): snikket_web/static/css/%.css: snikket_web/scss/%.scss $(scss_includes)
|
||||
$(SCSSC) -o "$@" "$<"
|
||||
|
||||
clean:
|
||||
rm -f $(generated_css_files)
|
||||
|
||||
.PHONY: build_css clean
|
||||
1
build-requirements.txt
Normal file
1
build-requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
pyscss~=1.3
|
||||
434
docs/colours.svg
Normal file
434
docs/colours.svg
Normal file
@@ -0,0 +1,434 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="334mm"
|
||||
height="154mm"
|
||||
viewBox="0 0 334 154"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="colours.svg"
|
||||
inkscape:export-filename="/home/horazont/tmp/colours.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="642.84838"
|
||||
inkscape:cy="251.88403"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1401"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="39"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(65,-148)">
|
||||
<rect
|
||||
style="opacity:1;fill:#418fc7;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4759"
|
||||
width="24"
|
||||
height="24"
|
||||
x="120"
|
||||
y="273" />
|
||||
<rect
|
||||
y="273"
|
||||
x="-2.7815501e-08"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9362"
|
||||
style="opacity:1;fill:#062943;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="273"
|
||||
x="240"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9364"
|
||||
style="opacity:1;fill:#e4f3fd;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="273"
|
||||
x="60"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9366"
|
||||
style="opacity:1;fill:#0e4c76;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#9dccf0;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9368"
|
||||
width="24"
|
||||
height="24"
|
||||
x="180"
|
||||
y="273" />
|
||||
<rect
|
||||
style="opacity:1;fill:#0f3d62;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9370"
|
||||
width="24"
|
||||
height="24"
|
||||
x="30"
|
||||
y="273" />
|
||||
<rect
|
||||
y="273"
|
||||
x="90"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9372"
|
||||
style="opacity:1;fill:#226494;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="273"
|
||||
x="150"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9376"
|
||||
style="opacity:1;fill:#72b2e3;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="273"
|
||||
x="210"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9378"
|
||||
style="opacity:1;fill:#b5d8f3;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="243"
|
||||
x="120"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9380"
|
||||
style="opacity:1;fill:#c95e40;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#340e03;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9382"
|
||||
width="24"
|
||||
height="24"
|
||||
x="0"
|
||||
y="243" />
|
||||
<rect
|
||||
style="opacity:1;fill:#fef1ed;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9384"
|
||||
width="24"
|
||||
height="24"
|
||||
x="240"
|
||||
y="243" />
|
||||
<rect
|
||||
style="opacity:1;fill:#e2b00c;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9436"
|
||||
width="24"
|
||||
height="24"
|
||||
x="120"
|
||||
y="213" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f2ac99;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9454"
|
||||
width="24"
|
||||
height="24"
|
||||
x="180"
|
||||
y="243" />
|
||||
<rect
|
||||
y="243"
|
||||
x="210"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9456"
|
||||
style="opacity:1;fill:#fbc2b3;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="243"
|
||||
x="150"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9458"
|
||||
style="opacity:1;fill:#ed947c;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#883017;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9460"
|
||||
width="24"
|
||||
height="24"
|
||||
x="60"
|
||||
y="243" />
|
||||
<rect
|
||||
y="243"
|
||||
x="30"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9462"
|
||||
style="opacity:1;fill:#681f0b;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="243"
|
||||
x="90"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9464"
|
||||
style="opacity:1;fill:#a33d21;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="183"
|
||||
x="120"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9466"
|
||||
style="opacity:1;fill:#55c644;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="213"
|
||||
x="240"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9484"
|
||||
style="opacity:1;fill:#fffcf0;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="213"
|
||||
x="0"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9486"
|
||||
style="opacity:1;fill:#302100;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="213"
|
||||
x="60"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9488"
|
||||
style="opacity:1;fill:#886600;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#563600;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9490"
|
||||
width="24"
|
||||
height="24"
|
||||
x="30"
|
||||
y="213" />
|
||||
<rect
|
||||
y="213"
|
||||
x="90"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9494"
|
||||
style="opacity:1;fill:#b98601;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="213"
|
||||
x="180"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9496"
|
||||
style="opacity:1;fill:#feed93;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="213"
|
||||
x="150"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9500"
|
||||
style="opacity:1;fill:#fde58a;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#fff7c2;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9502"
|
||||
width="24"
|
||||
height="24"
|
||||
x="210"
|
||||
y="213" />
|
||||
<rect
|
||||
style="opacity:1;fill:#8f8983;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9504"
|
||||
width="24"
|
||||
height="24"
|
||||
x="120"
|
||||
y="153" />
|
||||
<rect
|
||||
y="153"
|
||||
x="0"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9506"
|
||||
style="opacity:1;fill:#1f1b17;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="153"
|
||||
x="240"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9508"
|
||||
style="opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="153"
|
||||
x="180"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9510"
|
||||
style="opacity:1;fill:#cac3bd;fill-opacity:0.98872178;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#e3e1df;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9512"
|
||||
width="24"
|
||||
height="24"
|
||||
x="210"
|
||||
y="153" />
|
||||
<rect
|
||||
style="opacity:1;fill:#4e4a46;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9514"
|
||||
width="24"
|
||||
height="24"
|
||||
x="60"
|
||||
y="153" />
|
||||
<rect
|
||||
y="153"
|
||||
x="30"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9516"
|
||||
style="opacity:1;fill:#3d3833;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#706965;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9518"
|
||||
width="24"
|
||||
height="24"
|
||||
x="90"
|
||||
y="153" />
|
||||
<rect
|
||||
y="153"
|
||||
x="150"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9520"
|
||||
style="opacity:1;fill:#b1aca6;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ecfbe6;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9522"
|
||||
width="24"
|
||||
height="24"
|
||||
x="240"
|
||||
y="183" />
|
||||
<rect
|
||||
style="opacity:1;fill:#052f03;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9524"
|
||||
width="24"
|
||||
height="24"
|
||||
x="0"
|
||||
y="183" />
|
||||
<rect
|
||||
style="opacity:1;fill:#197713;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9526"
|
||||
width="24"
|
||||
height="24"
|
||||
x="60"
|
||||
y="183" />
|
||||
<rect
|
||||
y="183"
|
||||
x="30"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9528"
|
||||
style="opacity:1;fill:#0c4608;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
y="183"
|
||||
x="90"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9530"
|
||||
style="opacity:1;fill:#218a1b;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#abed9c;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9532"
|
||||
width="24"
|
||||
height="24"
|
||||
x="180"
|
||||
y="183" />
|
||||
<rect
|
||||
style="opacity:1;fill:#81e06e;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect9536"
|
||||
width="24"
|
||||
height="24"
|
||||
x="150"
|
||||
y="183" />
|
||||
<rect
|
||||
y="183"
|
||||
x="210"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect9538"
|
||||
style="opacity:1;fill:#cef6c5;fill-opacity:1;stroke:none;stroke-width:0.32483485;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;line-height:1em;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-3.4391122"
|
||||
y="170.58151"
|
||||
id="text9546"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9544"
|
||||
x="-3.4391129"
|
||||
y="170.58151"
|
||||
style="stroke-width:0.26458332px">Grayscale</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;line-height:1em;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-12.554834"
|
||||
y="200.5157"
|
||||
id="text9550"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9548"
|
||||
x="-12.554835"
|
||||
y="200.5157"
|
||||
style="stroke-width:0.26458332px">Success</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;line-height:1em;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-21.180664"
|
||||
y="230.71715"
|
||||
id="text9554"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9552"
|
||||
x="-21.180664"
|
||||
y="230.71715"
|
||||
style="stroke-width:0.26458332px">Accent</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;line-height:1em;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-33.880665"
|
||||
y="261.45316"
|
||||
id="text9558"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9556"
|
||||
x="-33.880665"
|
||||
y="261.45316"
|
||||
style="stroke-width:0.26458332px">Alert</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;line-height:1em;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-17.236719"
|
||||
y="290.85278"
|
||||
id="text9562"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9560"
|
||||
x="-17.236719"
|
||||
y="290.85278"
|
||||
style="stroke-width:0.26458332px">Primary</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -34,5 +34,14 @@ async def home():
|
||||
return redirect(url_for('login'))
|
||||
|
||||
|
||||
@app.route("/meta/about.html")
|
||||
async def about():
|
||||
return await render_template("about.html")
|
||||
|
||||
|
||||
@app.route("/meta/demo.html")
|
||||
async def demo():
|
||||
return await render_template("demo.html")
|
||||
|
||||
from .user import user_bp
|
||||
app.register_blueprint(user_bp)
|
||||
|
||||
132
snikket_web/scss/_baseline.scss
Normal file
132
snikket_web/scss/_baseline.scss
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* On the scaling of the headers. I’m a nerd, so here we go.
|
||||
*
|
||||
* I tried to determine a good scale a priori. It was clear to me that the
|
||||
* observed difference between a 48px and 64px font is much smaller than the
|
||||
* perceived difference between a 8px and 16px font size.
|
||||
*
|
||||
* Thus, the perception is *not* linear in the font size.
|
||||
*
|
||||
* I set the edge points to 200% and 100% (the h6 would get a bold font face)
|
||||
* to compensate.
|
||||
*
|
||||
* The first attempt to get a visually appealing header size scale was thus to
|
||||
* generate a logarithmic scale:
|
||||
*
|
||||
* numpy.logspace(np.log10(200), 2, 6, base=10)
|
||||
*
|
||||
* This leads to the following sizes:
|
||||
*
|
||||
* $_h-sizes: [200%, 174.11011266%, 151.57165665%, 131.95079108%, 114.8698355%, 100%];
|
||||
*
|
||||
* This scale has too large differences between the larger font sizes, and too
|
||||
* small differences between the smaller font sizes. Thus, I tried to invert
|
||||
* this:
|
||||
*
|
||||
* 200 - numpy.logspace(2, np.log10(200), 6, base=10) + 100
|
||||
*
|
||||
* This leads to the following sizes:
|
||||
*
|
||||
* $_h-sizes: [200.0%, 185.13016450029647%, 168.0492089227105%, 148.42834334896025%, 125.88988734077518%, 100%];
|
||||
*
|
||||
* While this was better, it still didn’t look quite right yet. The next
|
||||
* attempt was to go about a square function instead of log. The idea behind
|
||||
* this is that the font size is essentially one edge of a rectangle, where the
|
||||
* second edge depends on the first. A square function should thus generate a
|
||||
* nicely appealing sequence:
|
||||
*
|
||||
* Again, we want the large differences to be on the large scales, too:
|
||||
*
|
||||
* xs = numpy.linspace(5, 0, 6); 4*xs*xs + 100
|
||||
*
|
||||
* This leads to the following sizes:
|
||||
*
|
||||
* $_h-sizes: [200.0%, 164.0%, 136.0%, 116.0%, 104.0%, 100.0%];
|
||||
*
|
||||
* While the first three headings looked nice with that, the others did not.
|
||||
* Further research has shown me that others use an exponential scale (instead
|
||||
* of a log scale), but with a rather small base (<1.6).
|
||||
*
|
||||
* Instead of taking one of the well-known factors (like golden ratio or major
|
||||
* second), I opted for choosing a factor which gives me a clean 200%-100%
|
||||
* range:
|
||||
*
|
||||
* numpy.power(math.pow(2, 1/5), numpy.linspace(5, 0, 6)) * 100
|
||||
*
|
||||
* The result (rounded to 8 digits) is:
|
||||
*
|
||||
* $_h-sizes: [200.0%, 174.11011266%, 151.57165665%, 131.95079108%, 114.8698355%, 100.0%];
|
||||
*
|
||||
* And... This is the first logspace range. Derp. So why did I discard it in
|
||||
* the first place? Now that I look at it, it looks amazing. Brains are weird.
|
||||
*/
|
||||
$h-sizes: [200.0%, 174.11011266%, 151.57165665%, 131.95079108%, 114.8698355%, 100.0%];
|
||||
|
||||
/**
|
||||
* And for mobile devices, we want an even less aggressive scale. Let’s try
|
||||
* 150%-100%.
|
||||
*/
|
||||
$h-small-sizes: [150.0%, 138.31618672%, 127.54245006%, 117.60790225%, 108.44717712%, 100.0%];
|
||||
$small-screen-threshold: 40rem;
|
||||
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: $font-sans;
|
||||
color: $gray-100;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5;
|
||||
margin: 1.5em 0;
|
||||
font-family: $font-bulk;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
/* normalise */
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
font-style: normal;
|
||||
font-family: $font-heading;
|
||||
color: black;
|
||||
}
|
||||
|
||||
input, button, label, select, textarea, pre, code {
|
||||
font-size: 100%;
|
||||
color: inherit;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: $font-bulk;
|
||||
}
|
||||
|
||||
option {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@for $n from 1 through 6 {
|
||||
h#{$n} {
|
||||
font-size: nth($h-sizes, $n);
|
||||
line-height: 1.5 / (nth($h-sizes, $n) / 100%);
|
||||
margin: 1.5em / (nth($h-sizes, $n) / 100%) 0;
|
||||
}
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $small-screen-threshold) {
|
||||
@for $n from 1 through 6 {
|
||||
h#{$n} {
|
||||
font-size: nth($h-small-sizes, $n);
|
||||
line-height: 1.5 / (nth($h-small-sizes, $n) / 100%);
|
||||
margin: 1.5em / (nth($h-small-sizes, $n) / 100%) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
172
snikket_web/scss/_theme.scss
Normal file
172
snikket_web/scss/_theme.scss
Normal file
@@ -0,0 +1,172 @@
|
||||
$colours: (
|
||||
"gray": [
|
||||
#1f1b17,
|
||||
#3d3833,
|
||||
#4e4a46,
|
||||
#706965,
|
||||
#8f8983,
|
||||
#b1aca6,
|
||||
#cac3bd,
|
||||
#e3e1df,
|
||||
#f6f5f4
|
||||
],
|
||||
"primary": [
|
||||
#062943,
|
||||
#0f3d62,
|
||||
#0e4c76,
|
||||
#226494,
|
||||
#418fc7,
|
||||
#72b2e3,
|
||||
#9dccf0,
|
||||
#b5d8f3,
|
||||
#e4f3fd
|
||||
],
|
||||
"alert": [
|
||||
#340e03,
|
||||
#681f0b,
|
||||
#883017,
|
||||
#a33d21,
|
||||
#c95e40,
|
||||
#ed947c,
|
||||
#f2ac99,
|
||||
#fbc2b3,
|
||||
#fef1ed
|
||||
],
|
||||
"accent": [
|
||||
#302100,
|
||||
#563600,
|
||||
#795b00,
|
||||
#a07501,
|
||||
#c79b0e,
|
||||
#f4ce3f,
|
||||
#feed93,
|
||||
#fef6c1,
|
||||
#fffbe8
|
||||
],
|
||||
"success": [
|
||||
#052f03,
|
||||
#0c4608,
|
||||
#197713,
|
||||
#218a1b,
|
||||
#55c644,
|
||||
#81e06e,
|
||||
#abed9c,
|
||||
#cef6c5,
|
||||
#ecfbe6
|
||||
]
|
||||
);
|
||||
|
||||
$gray-100: nth(map-get($colours, "gray"), 1);
|
||||
$gray-200: nth(map-get($colours, "gray"), 2);
|
||||
$gray-300: nth(map-get($colours, "gray"), 3);
|
||||
$gray-400: nth(map-get($colours, "gray"), 4);
|
||||
$gray-500: nth(map-get($colours, "gray"), 5);
|
||||
$gray-600: nth(map-get($colours, "gray"), 6);
|
||||
$gray-700: nth(map-get($colours, "gray"), 7);
|
||||
$gray-800: nth(map-get($colours, "gray"), 8);
|
||||
$gray-900: nth(map-get($colours, "gray"), 9);
|
||||
|
||||
$primary-100: nth(map-get($colours, "primary"), 1);
|
||||
$primary-200: nth(map-get($colours, "primary"), 2);
|
||||
$primary-300: nth(map-get($colours, "primary"), 3);
|
||||
$primary-400: nth(map-get($colours, "primary"), 4);
|
||||
$primary-500: nth(map-get($colours, "primary"), 5);
|
||||
$primary-600: nth(map-get($colours, "primary"), 6);
|
||||
$primary-700: nth(map-get($colours, "primary"), 7);
|
||||
$primary-800: nth(map-get($colours, "primary"), 8);
|
||||
$primary-900: nth(map-get($colours, "primary"), 9);
|
||||
|
||||
$alert-100: nth(map-get($colours, "alert"), 1);
|
||||
$alert-200: nth(map-get($colours, "alert"), 2);
|
||||
$alert-300: nth(map-get($colours, "alert"), 3);
|
||||
$alert-400: nth(map-get($colours, "alert"), 4);
|
||||
$alert-500: nth(map-get($colours, "alert"), 5);
|
||||
$alert-600: nth(map-get($colours, "alert"), 6);
|
||||
$alert-700: nth(map-get($colours, "alert"), 7);
|
||||
$alert-800: nth(map-get($colours, "alert"), 8);
|
||||
$alert-900: nth(map-get($colours, "alert"), 9);
|
||||
|
||||
$accent-100: nth(map-get($colours, "accent"), 1);
|
||||
$accent-200: nth(map-get($colours, "accent"), 2);
|
||||
$accent-300: nth(map-get($colours, "accent"), 3);
|
||||
$accent-400: nth(map-get($colours, "accent"), 4);
|
||||
$accent-500: nth(map-get($colours, "accent"), 5);
|
||||
$accent-600: nth(map-get($colours, "accent"), 6);
|
||||
$accent-700: nth(map-get($colours, "accent"), 7);
|
||||
$accent-800: nth(map-get($colours, "accent"), 8);
|
||||
$accent-900: nth(map-get($colours, "accent"), 9);
|
||||
|
||||
$success-100: nth(map-get($colours, "success"), 1);
|
||||
$success-200: nth(map-get($colours, "success"), 2);
|
||||
$success-300: nth(map-get($colours, "success"), 3);
|
||||
$success-400: nth(map-get($colours, "success"), 4);
|
||||
$success-500: nth(map-get($colours, "success"), 5);
|
||||
$success-600: nth(map-get($colours, "success"), 6);
|
||||
$success-700: nth(map-get($colours, "success"), 7);
|
||||
$success-800: nth(map-get($colours, "success"), 8);
|
||||
$success-900: nth(map-get($colours, "success"), 9);
|
||||
|
||||
/*
|
||||
$primary-100: $gray-100;
|
||||
$primary-200: $gray-200;
|
||||
$primary-300: $gray-300;
|
||||
$primary-400: $gray-400;
|
||||
$primary-500: $gray-500;
|
||||
$primary-600: $gray-600;
|
||||
$primary-700: $gray-700;
|
||||
$primary-800: $gray-800;
|
||||
$primary-900: $gray-900;
|
||||
|
||||
$alert-100: $gray-100;
|
||||
$alert-200: $gray-200;
|
||||
$alert-300: $gray-300;
|
||||
$alert-400: $gray-400;
|
||||
$alert-500: $gray-500;
|
||||
$alert-600: $gray-600;
|
||||
$alert-700: $gray-700;
|
||||
$alert-800: $gray-800;
|
||||
$alert-900: $gray-900;
|
||||
|
||||
$accent-100: $gray-100;
|
||||
$accent-200: $gray-200;
|
||||
$accent-300: $gray-300;
|
||||
$accent-400: $gray-400;
|
||||
$accent-500: $gray-500;
|
||||
$accent-600: $gray-600;
|
||||
$accent-700: $gray-700;
|
||||
$accent-800: $gray-800;
|
||||
$accent-900: $gray-900;
|
||||
|
||||
$success-100: $gray-100;
|
||||
$success-200: $gray-200;
|
||||
$success-300: $gray-300;
|
||||
$success-400: $gray-400;
|
||||
$success-500: $gray-500;
|
||||
$success-600: $gray-600;
|
||||
$success-700: $gray-700;
|
||||
$success-800: $gray-800;
|
||||
$success-900: $gray-900;
|
||||
*/
|
||||
|
||||
|
||||
$w-s5: 0.0625rem;
|
||||
$w-s4: 0.125rem;
|
||||
$w-s3: 0.25rem;
|
||||
$w-s2: 0.5rem;
|
||||
$w-s1: 0.75rem;
|
||||
$w-0: 1rem;
|
||||
$w-l1: 1.5rem;
|
||||
$w-l2: 2rem;
|
||||
$w-l3: 3rem;
|
||||
$w-l4: 4rem;
|
||||
$w-l5: 6rem;
|
||||
$w-l6: 8rem;
|
||||
$w-l7: 12rem;
|
||||
|
||||
$font-sans: "Noto Sans", sans-serif;
|
||||
$font-serif: serif;
|
||||
$font-monospace: monospace;
|
||||
|
||||
$font-heading: $font-sans;
|
||||
$font-bulk: $font-sans;
|
||||
$font-code: $font-monospace;
|
||||
666
snikket_web/scss/app.scss
Normal file
666
snikket_web/scss/app.scss
Normal file
@@ -0,0 +1,666 @@
|
||||
@import "_theme.scss";
|
||||
@import "_baseline.scss";
|
||||
|
||||
/* coarse layout */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: $gray-900;
|
||||
}
|
||||
|
||||
body > main {
|
||||
padding: $w-l1;
|
||||
}
|
||||
|
||||
/* top bar */
|
||||
|
||||
@mixin snikket-logo {
|
||||
background-image: url('/static/img/snikket-logo.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: $w-s2 0em;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
div#topbar {
|
||||
background-color: white;
|
||||
@extend .el-1;
|
||||
color: $primary-200;
|
||||
margin: 0;
|
||||
padding: $w-s1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > header {
|
||||
flex: 0 1 auto;
|
||||
color: black;
|
||||
font-size: nth($h-sizes, 1);
|
||||
|
||||
@media screen and (max-width: $small-screen-threshold) {
|
||||
font-size: nth($h-small-sizes, 1);
|
||||
}
|
||||
|
||||
& > a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
span {
|
||||
@include snikket-logo;
|
||||
}
|
||||
}
|
||||
|
||||
& > a:visited, & > a:hover, & > a:focus, & > a:active {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
& > div.filler {
|
||||
flex: 1 1 0px;
|
||||
}
|
||||
|
||||
& > nav.usermenu {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* main content */
|
||||
|
||||
main {
|
||||
max-width: 60rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* standard elevations */
|
||||
|
||||
.el-1, .box.el-1, div.form.el-1 {
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.12),
|
||||
0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.el-2, .box.el-2, div.form.el-2 {
|
||||
box-shadow:
|
||||
0 3px 6px rgba(0, 0, 0, 0.15),
|
||||
0 2px 4px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.el-3, .box.el-3, div.form.el-3 {
|
||||
box-shadow:
|
||||
0 10px 20px rgba(0, 0, 0, 0.15),
|
||||
0 3px 6px rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
.el-4, .box.el-4, div.form.el-4 {
|
||||
box-shadow:
|
||||
0 15px 25px rgba(0, 0, 0, 0.15),
|
||||
0 5px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.el-5, .box.el-5, div.form.el-5 {
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
|
||||
/* footer */
|
||||
|
||||
body > footer {
|
||||
display: block;
|
||||
background-color: $gray-100;
|
||||
color: $gray-800;
|
||||
padding: 0 $w-l1;
|
||||
|
||||
ul {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: $w-l1 0;
|
||||
}
|
||||
|
||||
li:before {
|
||||
content: '•';
|
||||
padding-right: $w-s2;
|
||||
}
|
||||
|
||||
a, a:visited, a:hover, a:active, a:focus {
|
||||
color: $gray-900;
|
||||
font-weight: bold;
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: $gray-500;
|
||||
text-decoration-width: $w-s4;
|
||||
text-decoration-thickness: $w-s4;
|
||||
text-underline-offset: 0;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration-color: $gray-700;
|
||||
}
|
||||
}
|
||||
|
||||
/* form support */
|
||||
|
||||
@for $n from 1 through 6 {
|
||||
div.form h#{$n}.form-title {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
label.required:after {
|
||||
content: '*';
|
||||
color: $alert-400;
|
||||
padding: $w-s4;
|
||||
}
|
||||
|
||||
p.form-desc.weak {
|
||||
color: $gray-300;
|
||||
}
|
||||
|
||||
$text-entry-inputs: "text" "password";
|
||||
|
||||
div.f-errbox {
|
||||
background-color: $alert-800;
|
||||
border: $w-s4 solid $alert-200;
|
||||
color: $alert-100;
|
||||
border-radius: $w-s4;
|
||||
padding: 0 $w-0;
|
||||
margin: 1em 0;
|
||||
|
||||
p {
|
||||
line-height: 1;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
padding-left: $w-0;
|
||||
}
|
||||
|
||||
li {
|
||||
}
|
||||
}
|
||||
|
||||
div.form {
|
||||
@extend .el-2;
|
||||
|
||||
margin: $w-l1;
|
||||
padding: $w-l1;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
div.form.layout-expanded {
|
||||
label {
|
||||
display: block;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
div.f-ebox {
|
||||
margin-bottom: $w-l1;
|
||||
}
|
||||
|
||||
div.f-bbox {
|
||||
text-align: right;
|
||||
padding: $w-s2 0;
|
||||
}
|
||||
|
||||
@each $type in $text-entry-inputs {
|
||||
input[type=$type] {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-bottom: $w-s4 solid $primary-500;
|
||||
margin-bottom: -$w-s4;
|
||||
padding: 0 $w-s3;
|
||||
}
|
||||
|
||||
input[type=$type].has-error {
|
||||
border-right: $w-s4 solid $alert-500;
|
||||
}
|
||||
|
||||
input[type=$type]:hover {
|
||||
border-bottom-color: $primary-700;
|
||||
}
|
||||
|
||||
input[type=$type]:focus {
|
||||
border-bottom-color: $primary-800;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"], input[type="radio"] {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
input[type="checkbox"] + label:before {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
content: "✔";
|
||||
display: inline-block;
|
||||
width: $w-0;
|
||||
height: $w-0;
|
||||
border-radius: $w-s4;
|
||||
border: $w-s4 solid $primary-500;
|
||||
text-align: center;
|
||||
font-size: $w-0;
|
||||
margin-right: $w-s2;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
input[type="radio"] + label:before {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
content: "✔";
|
||||
display: inline-block;
|
||||
width: $w-0;
|
||||
height: $w-0;
|
||||
border-radius: $w-s1;
|
||||
border: $w-s4 solid $primary-500;
|
||||
text-align: center;
|
||||
font-size: $w-0;
|
||||
margin-right: $w-s2;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
input[type="checkbox"] + label:hover:before,
|
||||
input[type="radio"] + label:hover:before {
|
||||
border-color: $primary-700;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:focus + label:before,
|
||||
input[type="radio"]:focus + label:before {
|
||||
border-color: $primary-800;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked + label:before {
|
||||
background-color: $primary-500;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label:before {
|
||||
background-color: $primary-500;
|
||||
box-shadow: inset 0 0 0 $w-s3 white;
|
||||
}
|
||||
|
||||
input[type="checkbox"] + label, input[type="radio"] + label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.select-wrap {
|
||||
display: block;
|
||||
border-bottom: $w-s4 solid $primary-500;
|
||||
margin-bottom: -$w-s4;
|
||||
position: relative;
|
||||
|
||||
& > select {
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 0 $w-s3;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
padding-right: $w-l1 + $w-s3;
|
||||
margin-top: -1px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: "\25bc";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: $w-l1;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
color: $primary-500;
|
||||
font-size: 80%;
|
||||
// now we can build a padding which eats the remaining 20%
|
||||
// em is now 0.8 parent-em
|
||||
// we want to eat 20% of 1 parent-em -> 0.2 parent-em
|
||||
// 1 parent-em = 1.25 em
|
||||
// 0.2 parent-em = 0.25 em
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-bottom-color: $primary-700;
|
||||
|
||||
&:after {
|
||||
color: $primary-700;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-bottom-color: $primary-800;
|
||||
|
||||
&:after {
|
||||
color: $primary-800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-bottom: $w-s4 solid $primary-500;
|
||||
}
|
||||
|
||||
textarea:hover {
|
||||
border-bottom-color: $primary-700;
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
border-bottom-color: $primary-800;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* form buttons */
|
||||
|
||||
button, .button {
|
||||
margin: 0 $w-s2;
|
||||
padding: $w-s3 $w-s1;
|
||||
}
|
||||
|
||||
a.button {
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
button.primary, .button.primary {
|
||||
background: linear-gradient(0deg, $primary-500, $primary-600);
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
|
||||
color: $primary-900;
|
||||
border: none;
|
||||
/* TODO: fix vertical rhyhtm ... */
|
||||
border-radius: $w-s4;
|
||||
// border: $w-s4 solid transparent;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $primary-600, $primary-700);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $primary-500;
|
||||
box-shadow: inset 0px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.accent {
|
||||
background: linear-gradient(0deg, $accent-500, $accent-600);
|
||||
color: $accent-900;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $accent-600, $accent-700);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $accent-500;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: linear-gradient(0deg, $alert-500, $alert-600);
|
||||
color: $alert-900;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $alert-600, $alert-700);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $alert-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.secondary, .button.secondary {
|
||||
background: linear-gradient(0deg, $gray-600, $gray-700);
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
|
||||
color: $gray-200;
|
||||
border: none;
|
||||
/* TODO: fix vertical rhyhtm ... */
|
||||
border-radius: $w-s4;
|
||||
// border: $w-s4 solid transparent;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $gray-700, $gray-800);
|
||||
color: black;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $gray-600;
|
||||
box-shadow: inset 0px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
color: black;
|
||||
}
|
||||
|
||||
&.accent {
|
||||
background: linear-gradient(0deg, $accent-600, $accent-700);
|
||||
color: $accent-200;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $accent-700, $accent-800);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $accent-600;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: linear-gradient(0deg, $alert-600, $alert-700);
|
||||
color: $alert-200;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: linear-gradient(0deg, $alert-700, $alert-800);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $alert-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.tertiary, .button.tertiary {
|
||||
background-color: transparent;
|
||||
color: $gray-100;
|
||||
border: none;
|
||||
/* TODO: fix vertical rhyhtm ... */
|
||||
border-radius: $w-s4;
|
||||
|
||||
&:hover {
|
||||
background-color: $gray-900;
|
||||
border-color: $gray-800;
|
||||
color: black;
|
||||
}
|
||||
|
||||
&.accent {
|
||||
&:hover {
|
||||
background-color: $accent-900;
|
||||
border-color: $accent-800;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
&:hover {
|
||||
background-color: $alert-900;
|
||||
border-color: $alert-800;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.fullwidth, .button.fullwidth {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* button, .button {
|
||||
margin: 0 $w-s2;
|
||||
}
|
||||
|
||||
button.lv-primary, .button.lv-primary {
|
||||
background-color: $gray-500;
|
||||
color: $gray-900;
|
||||
border-radius: $w-s4;
|
||||
border: $w-s4 solid $gray-400;
|
||||
|
||||
@each $type, $values in $colours {
|
||||
&.c-#{$type} {
|
||||
border-color: nth($values, 4);
|
||||
background-color: nth($values, 5);
|
||||
color: nth($values, 9);
|
||||
}
|
||||
|
||||
&.c-#{$type}:hover {
|
||||
background-color: nth($values, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.lv-secondary, .button.lv-secondary {
|
||||
background-color: $gray-700;
|
||||
color: $gray-100;
|
||||
border-radius: $w-s4;
|
||||
|
||||
@each $type, $values in $colours {
|
||||
&.c-#{$type} {
|
||||
background-color: nth($values, 7);
|
||||
color: nth($values, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.lv-tertiary, .button.lv-tertiary {
|
||||
background-color: inherit;
|
||||
color: $gray-300;
|
||||
border-radius: $w-s4;
|
||||
text-decoration: underline;
|
||||
|
||||
@each $type, $values in $colours {
|
||||
&.c-#{$type} {
|
||||
color: nth($values, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
button.lv-secondary.c-#{$type}, .button.lv-secondary.c-#{$type} {
|
||||
background-color: nth($values, 7);
|
||||
color: nth($values, 1);
|
||||
}
|
||||
|
||||
button.lv-tertiary.c-#{$type}, .button.lv-tertiary.c-#{$type} {
|
||||
color: nth($values, 3);
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* boxes */
|
||||
|
||||
.box {
|
||||
display: block;
|
||||
/* border-width: $w-s4 / 2;
|
||||
border-style: solid; */
|
||||
padding: $w-l1 /* - $w-s4 / 2; */;
|
||||
margin: $w-l1;
|
||||
border-radius: $w-s4;
|
||||
|
||||
border-color: $gray-200;
|
||||
background-color: white;
|
||||
color: $gray-100;
|
||||
|
||||
@extend .el-1;
|
||||
|
||||
@each $type, $values in $colours {
|
||||
&.#{$type} {
|
||||
border-color: nth($values, 2);
|
||||
background-color: nth($values, 9);
|
||||
color: nth($values, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.box > header {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: $w-l1;
|
||||
line-height: 1.5;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.box > p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.box.slim {
|
||||
& > header {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& > header:after {
|
||||
content: ':';
|
||||
}
|
||||
|
||||
& > p {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* login page specials */
|
||||
|
||||
body#login {
|
||||
.form {
|
||||
font-size: nth($h-sizes, 4);
|
||||
}
|
||||
|
||||
.form-title {
|
||||
color: $primary-200;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include snikket-logo;
|
||||
padding-left: 2em;
|
||||
background-position: 0 0em;
|
||||
}
|
||||
}
|
||||
|
||||
/* linearisation / responsive stuff */
|
||||
|
||||
@media screen and (max-width: $small-screen-threshold) {
|
||||
main > .form.layout-expanded {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.form.layout-expanded .box {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.box > ul {
|
||||
padding-left: $w-0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
7
snikket_web/scss/common.scss
Normal file
7
snikket_web/scss/common.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.a11y-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
top: -100px;
|
||||
}
|
||||
97
snikket_web/scss/login.scss
Normal file
97
snikket_web/scss/login.scss
Normal file
@@ -0,0 +1,97 @@
|
||||
@import "_theme.scss";
|
||||
@import "_baseline.scss";
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
background:
|
||||
url('../img/noise.png') 0 0 / 180px 180px,
|
||||
$gray-900;
|
||||
flex-direction: column;
|
||||
|
||||
& > div.login-wrap {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
& > footer {
|
||||
flex: 0 0 auto;
|
||||
background:
|
||||
url('../img/noise.png') 0 0 / 180px 180px,
|
||||
$gray-800;
|
||||
box-shadow: inset 0 0.1em 0.2em rgba(0, 0, 0, 0.2);
|
||||
color: $gray-200;
|
||||
|
||||
ul {
|
||||
display: block;
|
||||
margin: 1.5em;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ul > li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* ul > li:before {
|
||||
content: '•';
|
||||
padding-right: 0.5em;
|
||||
} */
|
||||
}
|
||||
|
||||
& > div.login-wrap > main {
|
||||
width: 40rem;
|
||||
border: 0.2em solid $primary-900;
|
||||
padding: 1.5em;
|
||||
margin: 0;
|
||||
border-radius: 0.2em;
|
||||
box-shadow: 0 0.5em 1.5em rgba(0, 0, 0, 0.2);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
div.fbox, div.abox {
|
||||
font-size: 150%;
|
||||
line-height: 1;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
div.abox {
|
||||
margin-bottom: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input[type="password"],
|
||||
input[type="text"] {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
border-bottom: 0.1em solid $primary-900;
|
||||
padding: 0.05em;
|
||||
|
||||
&:focus {
|
||||
border-bottom-color: $primary-700;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
background-color: $primary-500;
|
||||
color: $gray-900;
|
||||
padding: 0.375em 0.75em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-image: url('/static/img/snikket-logo.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0.25em 0em;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
}
|
||||
132
snikket_web/scss/theme-demo.scss
Normal file
132
snikket_web/scss/theme-demo.scss
Normal file
@@ -0,0 +1,132 @@
|
||||
@import "./app.scss";
|
||||
|
||||
.accent-100 { background-color: $accent-100; }
|
||||
.success-100 { background-color: $success-100; }
|
||||
.gray-100 { background-color: $gray-100; }
|
||||
.alert-100 { background-color: $alert-100; }
|
||||
.primary-100 { background-color: $primary-100; }
|
||||
.accent-200 { background-color: $accent-200; }
|
||||
.success-200 { background-color: $success-200; }
|
||||
.gray-200 { background-color: $gray-200; }
|
||||
.alert-200 { background-color: $alert-200; }
|
||||
.primary-200 { background-color: $primary-200; }
|
||||
.accent-300 { background-color: $accent-300; }
|
||||
.success-300 { background-color: $success-300; }
|
||||
.gray-300 { background-color: $gray-300; }
|
||||
.alert-300 { background-color: $alert-300; }
|
||||
.primary-300 { background-color: $primary-300; }
|
||||
.accent-400 { background-color: $accent-400; }
|
||||
.success-400 { background-color: $success-400; }
|
||||
.gray-400 { background-color: $gray-400; }
|
||||
.alert-400 { background-color: $alert-400; }
|
||||
.primary-400 { background-color: $primary-400; }
|
||||
.accent-500 { background-color: $accent-500; }
|
||||
.success-500 { background-color: $success-500; }
|
||||
.gray-500 { background-color: $gray-500; }
|
||||
.alert-500 { background-color: $alert-500; }
|
||||
.primary-500 { background-color: $primary-500; }
|
||||
.accent-600 { background-color: $accent-600; }
|
||||
.success-600 { background-color: $success-600; }
|
||||
.gray-600 { background-color: $gray-600; }
|
||||
.alert-600 { background-color: $alert-600; }
|
||||
.primary-600 { background-color: $primary-600; }
|
||||
.accent-700 { background-color: $accent-700; }
|
||||
.success-700 { background-color: $success-700; }
|
||||
.gray-700 { background-color: $gray-700; }
|
||||
.alert-700 { background-color: $alert-700; }
|
||||
.primary-700 { background-color: $primary-700; }
|
||||
.accent-800 { background-color: $accent-800; }
|
||||
.success-800 { background-color: $success-800; }
|
||||
.gray-800 { background-color: $gray-800; }
|
||||
.alert-800 { background-color: $alert-800; }
|
||||
.primary-800 { background-color: $primary-800; }
|
||||
.accent-900 { background-color: $accent-900; }
|
||||
.success-900 { background-color: $success-900; }
|
||||
.gray-900 { background-color: $gray-900; }
|
||||
.alert-900 { background-color: $alert-900; }
|
||||
.primary-900 { background-color: $primary-900; }
|
||||
|
||||
div.samplerow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
div.samplerow.dark {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.samplehead {
|
||||
flex: 1 0 auto;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div.samplebox {
|
||||
flex: 0 0 auto;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
// border: 1px solid $gray-900;
|
||||
border-radius: 3px;
|
||||
margin: 8px;
|
||||
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
div.samplerow.dark div.samplebox {
|
||||
//border: 1px solid $gray-100;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 60em;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
div.demo-columns {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div.demo-column {
|
||||
flex: 1 1 1px;
|
||||
margin: 0 $w-l1;
|
||||
}
|
||||
|
||||
div.demo-column:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
div.demo-column:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background:
|
||||
url('../img/line.png'),
|
||||
$gray-900;
|
||||
background-size: 1.5em 1.5em;
|
||||
background-position: 0em -0.3em;
|
||||
}
|
||||
|
||||
body:target {
|
||||
background: $gray-900;
|
||||
}
|
||||
|
||||
body #enable-lines {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:target #disable-lines {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:target #enable-lines {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 40rem) {
|
||||
div.demo-columns, div.demo-column {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
BIN
snikket_web/static/img/line.png
Normal file
BIN
snikket_web/static/img/line.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 567 B |
BIN
snikket_web/static/img/noise.png
Normal file
BIN
snikket_web/static/img/noise.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
216
snikket_web/static/img/snikket-logo.svg
Normal file
216
snikket_web/static/img/snikket-logo.svg
Normal file
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
id="svg5167"
|
||||
version="1.1"
|
||||
viewBox="0 0 22.886755 22.884575"
|
||||
height="86.492882"
|
||||
width="86.501122">
|
||||
<defs
|
||||
id="defs5161">
|
||||
<linearGradient
|
||||
id="linear-gradient"
|
||||
x1="566.13"
|
||||
y1="409.16"
|
||||
x2="566.13"
|
||||
y2="493.17001"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#f58020"
|
||||
id="stop4" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fdeb01"
|
||||
id="stop6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linear-gradient-2"
|
||||
x1="499.95999"
|
||||
y1="368.92999"
|
||||
x2="706.73999"
|
||||
y2="368.92999"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#ffc50d"
|
||||
id="stop9" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fdeb01"
|
||||
id="stop11" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linear-gradient-3"
|
||||
id="linearGradient914"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="448.32001"
|
||||
y1="210.56"
|
||||
x2="448.32001"
|
||||
y2="599.59003" />
|
||||
<linearGradient
|
||||
id="linear-gradient-3"
|
||||
x1="448.32001"
|
||||
y1="210.56"
|
||||
x2="448.32001"
|
||||
y2="599.59003"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#3fc6f1"
|
||||
id="stop14" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#4063ae"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linear-gradient-4"
|
||||
id="linearGradient916"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="692.71997"
|
||||
y1="464.03"
|
||||
x2="515.72998"
|
||||
y2="367.20001" />
|
||||
<linearGradient
|
||||
id="linear-gradient-4"
|
||||
x1="692.71997"
|
||||
y1="464.03"
|
||||
x2="515.72998"
|
||||
y2="367.20001"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#fff"
|
||||
id="stop19" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
id="stop21" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linear-gradient-5"
|
||||
x1="300.94"
|
||||
y1="599.45001"
|
||||
x2="346.32001"
|
||||
y2="539.47998"
|
||||
xlink:href="#linear-gradient-3" />
|
||||
<linearGradient
|
||||
id="linear-gradient-6"
|
||||
x1="627.41998"
|
||||
y1="554.45001"
|
||||
x2="351.38"
|
||||
y2="472.28"
|
||||
xlink:href="#linear-gradient-4" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata5164">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-94.389956,-137.39105)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g912"
|
||||
transform="matrix(0.05535021,0,0,0.05535021,88.573756,137.39108)"
|
||||
style="isolation:isolate">
|
||||
<path
|
||||
id="path46"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 679,510.12 c 0,0.09 0,0.09 -0.19,0.19 a 0.91,0.91 0 0 0 0.09,-0.48 0.34,0.34 0 0 1 0.1,0.29 z"
|
||||
class="cls-2"
|
||||
style="fill:#2d2b70" />
|
||||
<path
|
||||
id="path48"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 678.89,509.83 a 0.91,0.91 0 0 1 -0.09,0.48 c 0.19,-0.1 0.19,-0.1 0.19,-0.19 a 0.34,0.34 0 0 0 -0.1,-0.29 z"
|
||||
class="cls-2"
|
||||
style="fill:#2d2b70" />
|
||||
<path
|
||||
id="path50"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 679,510.12 c 0,0.09 0,0.09 -0.19,0.19 a 0.91,0.91 0 0 0 0.09,-0.48 0.34,0.34 0 0 1 0.1,0.29 z"
|
||||
class="cls-2"
|
||||
style="fill:#2d2b70" />
|
||||
<path
|
||||
id="path52"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 679,510.12 c 0,0.09 0,0.09 -0.19,0.19 a 0.91,0.91 0 0 0 0.09,-0.48 0.34,0.34 0 0 1 0.1,0.29 z"
|
||||
class="cls-2"
|
||||
style="fill:#2d2b70" />
|
||||
<path
|
||||
id="path54"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="M 632.3,454.62 A 206.27,206.27 0 0 1 522.84,501.21 205.25,205.25 0 0 1 500,406.68 205.75,205.75 0 0 1 632.3,454.62 Z"
|
||||
class="cls-3"
|
||||
style="fill:url(#linear-gradient)" />
|
||||
<path
|
||||
id="path56"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 699.18,351.28 a 206.32,206.32 0 0 0 -95.78,-123.53 206.49,206.49 0 0 0 -87,98.17 204.39,204.39 0 0 0 -16.4,80.76 207,207 0 0 1 178.89,103.15 0.34,0.34 0 0 1 0.1,0.29 206.7,206.7 0 0 0 20.19,-158.84 z"
|
||||
class="cls-4"
|
||||
style="fill:url(#linear-gradient-2)" />
|
||||
<path
|
||||
id="path58"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="M 603.37,585.71 A 206.76,206.76 0 0 1 321,510.12 c -3,-5.08 -5.65,-10.25 -8.13,-15.6 -0.77,-1.63 -1.25,-2.68 -1.34,-3 l -0.1,-0.1 a 204.93,204.93 0 0 1 -17.89,-74.15 22.26,22.26 0 0 1 -0.1,-2.58 v -0.1 c -0.19,-2.58 -0.19,-5.26 -0.19,-7.94 q 0,-5.31 0.29,-10.62 a 203.13,203.13 0 0 1 7.27,-44.78 C 325,264 405,200 499.94,200 a 204.88,204.88 0 0 1 103.43,27.75 206.47,206.47 0 0 0 -87,98.17 206.57,206.57 0 0 0 87,259.79 z"
|
||||
class="cls-5"
|
||||
style="fill:url(#linearGradient914)" />
|
||||
<circle
|
||||
id="circle60"
|
||||
r="46.560001"
|
||||
cy="106.76"
|
||||
cx="247.60001"
|
||||
class="cls-6"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
id="path62"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 435.81,277.84 a 28.92,28.92 0 1 0 28.84,28.92 11.83,11.83 0 0 0 -0.14,-2.22 16.92,16.92 0 0 1 -25.3,-14.65 16.66,16.66 0 0 1 4.14,-11 28.76,28.76 0 0 0 -7.54,-1.05 z"
|
||||
class="cls-7"
|
||||
style="fill:#231f20" />
|
||||
<g
|
||||
id="g66"
|
||||
class="cls-8"
|
||||
style="mix-blend-mode:overlay">
|
||||
<path
|
||||
id="path64"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 678.89,508.68 v 1.15 A 207,207 0 0 0 500,406.68 204.38,204.38 0 0 1 516.45,325.92 c 63,12.35 115.21,50.71 142.38,102.1 a 172.75,172.75 0 0 1 20.06,80.66 z"
|
||||
class="cls-9"
|
||||
style="fill:url(#linearGradient916)" />
|
||||
</g>
|
||||
<path
|
||||
id="path68"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="m 303.21,613.45 c 42.58,-37.22 16.36,-103.82 9.67,-118.93 2.48,5.35 5.16,10.52 8.13,15.6 a 205,205 0 0 0 63.53,68 c -28.89,31.22 -81.33,35.33 -81.33,35.33 z"
|
||||
class="cls-10"
|
||||
style="fill:url(#linear-gradient-5)" />
|
||||
<g
|
||||
id="g72"
|
||||
class="cls-8"
|
||||
style="mix-blend-mode:overlay">
|
||||
<path
|
||||
id="path70"
|
||||
transform="translate(-188.17,-200)"
|
||||
d="M 603.4,585.71 A 206.72,206.72 0 0 1 293.58,417.3 a 22.26,22.26 0 0 1 -0.1,-2.58 v -0.1 c -0.19,-2.58 -0.19,-5.26 -0.19,-7.94 0,-3.54 0.09,-7.08 0.29,-10.62 a 203.13,203.13 0 0 1 7.27,-44.78 196.79,196.79 0 0 0 13.87,36.26 206.88,206.88 0 0 0 185.28,114.92 200.23,200.23 0 0 0 22.87,-1.25 205.82,205.82 0 0 0 80.53,84.5 z"
|
||||
class="cls-11"
|
||||
style="fill:url(#linear-gradient-6)" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.1 KiB |
22
snikket_web/templates/about.html
Normal file
22
snikket_web/templates/about.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>About Snikket</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<h1>About Snikket</h1>
|
||||
<h2>What is Snikket?</h2>
|
||||
<p>Snikket is an easy-to-use and easy-to-setup Instant Messaging platform for you and your friends and family.</p>
|
||||
<h2>What is the Snikket Web Portal?</h2>
|
||||
<h2>Behind the Scenes and Licenses</h2>
|
||||
<h3>Quart Microframework</h3>
|
||||
<hr>
|
||||
<h1>h1</h1>
|
||||
<h2>h2</h2>
|
||||
<h3>h3</h3>
|
||||
<h4>h4</h4>
|
||||
<h5>h5</h5>
|
||||
<h6>h6</h6>
|
||||
</body>
|
||||
</html>
|
||||
19
snikket_web/templates/app.html
Normal file
19
snikket_web/templates/app.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/app.css') }}">
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div id="topbar">
|
||||
<header><a href="{{ url_for('user.index') }}"><span>{{ config["SNIKKET_DOMAIN"] }}</span></a></header>
|
||||
<div class="filler"></div>
|
||||
<nav class="usermenu">{{ user_info.username }}</nav>
|
||||
</div>
|
||||
<main>{% block content %}{% endblock %}</main>
|
||||
<footer>
|
||||
<ul><li>A <a href="{{ url_for('about') }}">Snikket</a> server</li></ul>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
12
snikket_web/templates/base.html
Normal file
12
snikket_web/templates/base.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% block head_lead %}{% endblock %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{% block style %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/common.css') }}">
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body{% if body_id | default(False) %} id="{{ body_id }}"{% endif %}{% if body_class | default(False) %} class="{{ body_class }}"{% endif %}>{% block body %}{% endblock %}</body>
|
||||
</html>
|
||||
178
snikket_web/templates/demo.html
Normal file
178
snikket_web/templates/demo.html
Normal file
@@ -0,0 +1,178 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "library.j2" import box %}
|
||||
{% set body_id = "no-lines" %}
|
||||
{% block head_lead %}
|
||||
<title>Theme Demo – Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/theme-demo.css') }}" type="text/css">
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<h1 id="dummy">Theme Demo</h1>
|
||||
<p>This page is to demonstrate the Snikket Web Portal theme and allow development. You should not see this during normal use.</p>
|
||||
<p><a id="disable-lines" href="#no-lines" class="button secondary">Disable rhythm lines</a><a id="enable-lines" href="#dummy" class="button secondary">Enable rhythm lines</a></p>
|
||||
<h2>Headings</h2>
|
||||
<p>This subsection is responsible for demonstrating the heading sizes, with the relation between the different headings and also the relation between headings and text.</p>
|
||||
<div class="demo-columns"><div class="demo-column">
|
||||
<h3>Sub-heading</h3>
|
||||
<p>Repudiandae voluptatem ratione voluptatem facere. Rerum recusandae nemo commodi provident praesentium est dignissimos. Aut provident nisi omnis tempore veritatis voluptatem minus esse. Non nulla consequatur id est doloribus quos voluptates. Quae suscipit fugiat minima.</p>
|
||||
<h4>Nested Sub—heading</h4>
|
||||
<p>Omnis sit temporibus soluta et inventore. Doloribus velit unde placeat aut necessitatibus distinctio. Sapiente sunt corporis neque ducimus officiis qui. Maxime officia et architecto dolor quos autem expedita. Omnis architecto atque facilis iste dolorem voluptatem consectetur. Cupiditate et officiis accusantium inventore.</p>
|
||||
<h5>Deeper Sub-heading</h5>
|
||||
<p>Perferendis vitae doloribus praesentium natus non. Itaque hic numquam dolorum non vero et excepturi consequatur. Accusantium doloribus molestias impedit laudantium quis accusantium. Repellendus et assumenda voluptate aut ipsa quod. Dolores rerum accusantium cumque voluptatem rerum iure.</p>
|
||||
<h6>Paragraph heading</h6>
|
||||
<p>Suscipit quis tempora officiis voluptatem sint. Sed vel perferendis libero similique pariatur. Quo corporis perferendis omnis laboriosam nesciunt. Ut fuga quis deserunt maiores voluptas id fugiat odio. Omnis et facilis officia. Rerum quia quia exercitationem qui quibusdam quia et.</p>
|
||||
<h4>Another nested Sub-heading</h4>
|
||||
<p>Saepe distinctio illo et illum quia quo. Maxime eveniet voluptate non voluptatibus commodi et. Dicta consequuntur voluptatum sint ab voluptatem tenetur. Ad rem et eveniet ea animi voluptatum laborum.</p>
|
||||
</div><div class="demo-column">
|
||||
<p>The other column of this demo demonstrates the headings right beneath each other.</p>
|
||||
<h1>Main Title (h1)</h1>
|
||||
<h2>Heading (h2)</h2>
|
||||
<h3>Sub-Heading (h3)</h3>
|
||||
<h4>Nested Sub-Heading (h4)</h4>
|
||||
<h5>Deep Sub-Heading (h5)</h5>
|
||||
<h6>Paragraph Heading (h6)</h6>
|
||||
</div></div>
|
||||
|
||||
<h2>Palette</h2>
|
||||
<div class="samplerow"><div class="samplehead">gray</div><div class="samplebox gray-100"></div><div class="samplebox gray-200"></div><div class="samplebox gray-300"></div><div class="samplebox gray-400"></div><div class="samplebox gray-500"></div><div class="samplebox gray-600"></div><div class="samplebox gray-700"></div><div class="samplebox gray-800"></div><div class="samplebox gray-900"></div></div>
|
||||
<div class="samplerow"><div class="samplehead">success</div><div class="samplebox success-100"></div><div class="samplebox success-200"></div><div class="samplebox success-300"></div><div class="samplebox success-400"></div><div class="samplebox success-500"></div><div class="samplebox success-600"></div><div class="samplebox success-700"></div><div class="samplebox success-800"></div><div class="samplebox success-900"></div></div>
|
||||
<div class="samplerow"><div class="samplehead">alert</div><div class="samplebox alert-100"></div><div class="samplebox alert-200"></div><div class="samplebox alert-300"></div><div class="samplebox alert-400"></div><div class="samplebox alert-500"></div><div class="samplebox alert-600"></div><div class="samplebox alert-700"></div><div class="samplebox alert-800"></div><div class="samplebox alert-900"></div></div>
|
||||
<div class="samplerow"><div class="samplehead">accent</div><div class="samplebox accent-100"></div><div class="samplebox accent-200"></div><div class="samplebox accent-300"></div><div class="samplebox accent-400"></div><div class="samplebox accent-500"></div><div class="samplebox accent-600"></div><div class="samplebox accent-700"></div><div class="samplebox accent-800"></div><div class="samplebox accent-900"></div></div>
|
||||
<div class="samplerow"><div class="samplehead">primary</div><div class="samplebox primary-100"></div><div class="samplebox primary-200"></div><div class="samplebox primary-300"></div><div class="samplebox primary-400"></div><div class="samplebox primary-500"></div><div class="samplebox primary-600"></div><div class="samplebox primary-700"></div><div class="samplebox primary-800"></div><div class="samplebox primary-900"></div></div>
|
||||
|
||||
<div class="samplerow dark"><div class="samplehead">gray</div><div class="samplebox gray-100"></div><div class="samplebox gray-200"></div><div class="samplebox gray-300"></div><div class="samplebox gray-400"></div><div class="samplebox gray-500"></div><div class="samplebox gray-600"></div><div class="samplebox gray-700"></div><div class="samplebox gray-800"></div><div class="samplebox gray-900"></div></div>
|
||||
<div class="samplerow dark"><div class="samplehead">success</div><div class="samplebox success-100"></div><div class="samplebox success-200"></div><div class="samplebox success-300"></div><div class="samplebox success-400"></div><div class="samplebox success-500"></div><div class="samplebox success-600"></div><div class="samplebox success-700"></div><div class="samplebox success-800"></div><div class="samplebox success-900"></div></div>
|
||||
<div class="samplerow dark"><div class="samplehead">alert</div><div class="samplebox alert-100"></div><div class="samplebox alert-200"></div><div class="samplebox alert-300"></div><div class="samplebox alert-400"></div><div class="samplebox alert-500"></div><div class="samplebox alert-600"></div><div class="samplebox alert-700"></div><div class="samplebox alert-800"></div><div class="samplebox alert-900"></div></div>
|
||||
<div class="samplerow dark"><div class="samplehead">accent</div><div class="samplebox accent-100"></div><div class="samplebox accent-200"></div><div class="samplebox accent-300"></div><div class="samplebox accent-400"></div><div class="samplebox accent-500"></div><div class="samplebox accent-600"></div><div class="samplebox accent-700"></div><div class="samplebox accent-800"></div><div class="samplebox accent-900"></div></div>
|
||||
<div class="samplerow dark"><div class="samplehead">primary</div><div class="samplebox primary-100"></div><div class="samplebox primary-200"></div><div class="samplebox primary-300"></div><div class="samplebox primary-400"></div><div class="samplebox primary-500"></div><div class="samplebox primary-600"></div><div class="samplebox primary-700"></div><div class="samplebox primary-800"></div><div class="samplebox primary-900"></div></div>
|
||||
|
||||
<h2>Boxes</h2>
|
||||
<p>Boxes can be used to draw the attention to the user to a specific thing. In general, they will be used to inform the user about the result of an action or about an action item.</p>
|
||||
<div class="demo-columns"><div class="demo-column">
|
||||
<h3>Full-size boxes</h3>
|
||||
<p>Full-size boxes visually separate the header and the following content into separate lines. This allows the use of all and multiple block format elements inside full-size boxes.</p>
|
||||
<p>The following box contains an error message:</p>
|
||||
{% call box("alert", "Password change failed") %}
|
||||
<p>You need to provide a new password.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a success message:</p>
|
||||
{% call box("success", "Bookmark created") %}
|
||||
<p>The channel was added to your list.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a notice:</p>
|
||||
{% call box("accent", "Quota warning") %}
|
||||
<p>You have nearly reached your HTTP upload storage quota.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a hint:</p>
|
||||
{% call box("primary", "Update available") %}
|
||||
<p>There is a new version of the Snikket Server available.</p>
|
||||
{% endcall %}
|
||||
<p>Finally, the following box has unspecified content:</p>
|
||||
{% call box("", "Something happened") %}
|
||||
<p>But we don’t know if it’s good or bad or anything.</p>
|
||||
{% endcall %}
|
||||
</div><div class="demo-column">
|
||||
<h3>Slim boxes</h3>
|
||||
<p>Slim boxes use inline elements only. They only support the <code><header/></code> and a single <code><p/></code>. Since, on the semantic level, the header and p are still separated, CSS is used to insert a colon for visual reading.</p>
|
||||
<p>The following box contains an error message:</p>
|
||||
{% call box("alert", "Password change failed", slim=True) %}
|
||||
<p>You need to provide a new password.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a success message:</p>
|
||||
{% call box("success", "Bookmark created", slim=True) %}
|
||||
<p>The channel was added to your list.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a notice:</p>
|
||||
{% call box("accent", "Quota warning", slim=True) %}
|
||||
<p>You have nearly reached your HTTP upload storage quota.</p>
|
||||
{% endcall %}
|
||||
<p>The following box contains a hint:</p>
|
||||
{% call box("primary", "Update available", slim=True) %}
|
||||
<p>There is a new version of the Snikket Server available.</p>
|
||||
{% endcall %}
|
||||
<p>Finally, the following box has unspecified content:</p>
|
||||
{% call box("", "Something happened", slim=True) %}
|
||||
<p>But we don’t know if it’s good or bad or anything.</p>
|
||||
{% endcall %}
|
||||
</div></div>
|
||||
|
||||
<h2>Elevation levels</h2>
|
||||
<p>Demonstrated with boxes:</p>
|
||||
<aside class="box primary el-1">
|
||||
<header>Elevation level 1</header>
|
||||
</aside>
|
||||
<aside class="box primary el-2">
|
||||
<header>Elevation level 2</header>
|
||||
</aside>
|
||||
<aside class="box primary el-3">
|
||||
<header>Elevation level 3</header>
|
||||
</aside>
|
||||
<aside class="box primary el-4">
|
||||
<header>Elevation level 4</header>
|
||||
</aside>
|
||||
<aside class="box primary el-5">
|
||||
<header>Elevation level 5</header>
|
||||
</aside>
|
||||
|
||||
<h2>Forms</h2>
|
||||
<h3>Standard Forms (Expanded)</h3>
|
||||
<p>Forms support a single title (on any h-level to fit semantically), a description text and fields. Fields and their labels are on separate lines by default.</p>
|
||||
<div class="form layout-expanded"><form>
|
||||
<h4 class="form-title">Random Preferences</h4>
|
||||
<p class="form-desc">This form illustrates the various controls supported by the theme, without being semantically useful.</p>
|
||||
<div class="f-ebox">
|
||||
<label for="fex-f1" class="required">Name</label>
|
||||
<input type="text" id="fex-f1" name="fex-f1">
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
<input type="checkbox" id="fex-f2" name="fex-f2"><label for="fex-f2">Enable fancy features</label>
|
||||
<input type="checkbox" id="fex-f3" name="fex-f3"><label for="fex-f3">Enable more features</label>
|
||||
<input type="checkbox" id="fex-f4" name="fex-f4"><label for="fex-f4">Also do that other thing</label>
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
<input type="radio" id="fex-f5" name="fex-rg1"><label for="fex-f5">High difficulty</label>
|
||||
<input type="radio" id="fex-f6" name="fex-rg1"><label for="fex-f6">Medium difficulty</label>
|
||||
<input type="radio" id="fex-f7" name="fex-rg1"><label for="fex-f7">Low difficulty</label>
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
<label for="fex-f8">Select dropdown:</label>
|
||||
<div class="select-wrap"><select id="fex-f8" name="fex-f8">
|
||||
<option>The good</option>
|
||||
<option>The bad</option>
|
||||
<option>The ugly</option>
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
<label for="fex-f9">Text area</label>
|
||||
<textarea rows="5"></textarea>
|
||||
</div>
|
||||
<p>The following demonstrate the different button styles. First normal buttons:</p>
|
||||
<div class="f-bbox">
|
||||
<button class="tertiary">Tertiary</button>
|
||||
<button class="secondary">Secondary</button>
|
||||
<button class="primary">Primary</button>
|
||||
</div>
|
||||
<p>Then the accentuated versions:</p>
|
||||
<div class="f-bbox">
|
||||
<button class="tertiary accent">Tertiary (Accent)</button>
|
||||
<button class="secondary accent">Secondary (Accent)</button>
|
||||
<button class="primary accent">Primary (Accent)</button>
|
||||
</div>
|
||||
<p>And finally, the Danger Zone:</p>
|
||||
<div class="f-bbox">
|
||||
<button class="tertiary danger">Tertiary (Danger)</button>
|
||||
<button class="secondary danger">Secondary (Danger)</button>
|
||||
<button class="primary danger">Primary (Danger)</button>
|
||||
</div>
|
||||
{#
|
||||
{% for style in ["primary", "secondary", "tertiary"] %}
|
||||
<p>The following demonstrate the <em>{{ style }}</em> button styles:</p>
|
||||
<div class="f-bbox">
|
||||
<button class="lv-{{ style }} c-gray">Unspecified</button><button class="lv-{{ style }} c-primary">Primary</button><button class="lv-{{ style }} c-alert">Alert</button><button class="lv-{{ style }} c-success">Success</button><button class="lv-{{ style }} c-accent">Accent</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
#}
|
||||
</form></div>
|
||||
|
||||
{% endblock %}
|
||||
3
snikket_web/templates/library.j2
Normal file
3
snikket_web/templates/library.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
{% macro box(type, title, slim=False, caller=None) %}
|
||||
<aside class="box{% if slim %} slim{% endif %} {{ type }}"><header>{{ title }}</header> {{ caller() }}</aside>
|
||||
{% endmacro %}
|
||||
@@ -1,13 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Snikket Web Portal</title>
|
||||
</head>
|
||||
<body>
|
||||
<form method="POST" action="{{ url_for('login') }}" name="login">
|
||||
<input type="text" name="address">
|
||||
<input type="password" name="password">
|
||||
<input type="submit" value="Login">
|
||||
</from>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "base.html" %}
|
||||
{% set body_id = "login" %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/app.css') }}">
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<main><div class="form layout-expanded">
|
||||
<h1 class="form-title">{{ config["SNIKKET_DOMAIN"] }}</h1>
|
||||
<p class="form-desc">Enter your Snikket address and password to manage your account.</p>
|
||||
<form method="POST" action="{{ url_for('login') }}" name="login">
|
||||
<div class="f-ebox">
|
||||
<label for="address" class="a11y-only">Address:</label>
|
||||
<input type="text" name="address" id="address" required="required" placeholder="Address">
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
<label for="password" class="a11y-only"`>Password:</label>
|
||||
<input type="password" name="password" required="required" placeholder="Password">
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
<button type="submit" class="primary">Login</button>
|
||||
</div>
|
||||
</from>
|
||||
</div></main>
|
||||
<footer>
|
||||
<ul><li>A <a href="{{ url_for('about') }}">Snikket</a> server</li></ul>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Snikket Web Portal</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome!</h1>
|
||||
<p>Welcome home, {{ user_info.username }}.</p>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('user.change_pw') }}">Change password</a></li>
|
||||
<li><a href="{{ url_for('user.logout') }}">Log out</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "app.html" %}
|
||||
{% block content %}
|
||||
<h1>Welcome!</h1>
|
||||
<p>Welcome home, {{ user_info.username }}.</p>
|
||||
<h2>Next?</h2>
|
||||
<p>What do you want to do today?</p>⎄
|
||||
<ul>
|
||||
<li><a href="{{ url_for('user.change_pw') }}">Change password</a></li>
|
||||
<li><a href="{{ url_for('user.logout') }}">Log out</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form method="POST">
|
||||
{{ form.csrf_token }}
|
||||
<input type="submit" value="Logout">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "app.html" %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="form layout-expanded"><form method="POST">
|
||||
<h2 class="form-title">Sign out of the Snikket Web Portal</h2>
|
||||
<p class="form-desc">Click below to log yourself out of the web portal. This does not affect any other connected devices.</p>
|
||||
{{ form.csrf_token }}
|
||||
<div class="f-bbox">
|
||||
<a href="{{ url_for('user.index') }}" class="button secondary">Back</a>
|
||||
<button type="submit" class="primary">Sign out</button>
|
||||
</div>
|
||||
</form></div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,19 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form method="POST">
|
||||
{{ form.csrf_token }}
|
||||
{{ form.current_password }}
|
||||
{{ form.new_password }}
|
||||
{{ form.new_password_confirm }}
|
||||
<ul>
|
||||
{% for field, errors in form.errors.items() %}
|
||||
{% for error in errors %}
|
||||
<li>{{ field }}: {{ error }}</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<input type="submit" value="Change password">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "app.html" %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="form layout-expanded"><form method="POST">
|
||||
<h2 class="form-title">Change your password</h2>
|
||||
<p class="form-desc weak">To change your password, you need to provide the current password as well as the new one. To reduce the chance of typos, we ask for your new password twice.</p>
|
||||
{{ form.csrf_token }}
|
||||
{% if form.errors %}
|
||||
<div class="box alert">
|
||||
<header>Password change failed</header>
|
||||
<ul>
|
||||
{% for field, errors in form.errors.items() %}
|
||||
{% for error in errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="f-ebox">
|
||||
{{ form.current_password.label(class="required") }}
|
||||
{{ form.current_password(class=("has-error" if form.current_password.name in form.errors else "")) }}
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
{{ form.new_password.label(class="required") }}
|
||||
{{ form.new_password }}
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
{{ form.new_password_confirm.label(class="required") }}
|
||||
{{ form.new_password_confirm(class=("has-error" if form.new_password_confirm.name in form.errors else "")) }}
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
<a href="{{ url_for('user.index') }}" class="button secondary">Back</a>
|
||||
<button type="submit" class="primary">Change password</button>
|
||||
</div>
|
||||
</form></div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -10,18 +10,33 @@ from snikket_web.prosodyclient import client
|
||||
user_bp = Blueprint('user', __name__, url_prefix="/user")
|
||||
|
||||
|
||||
@user_bp.context_processor
|
||||
async def proc():
|
||||
return {"user_info": await client.get_user_info()}
|
||||
|
||||
|
||||
class ChangePasswordForm(FlaskForm):
|
||||
current_password = wtforms.PasswordField(
|
||||
# TODO(i18n)
|
||||
"Current password",
|
||||
validators=[wtforms.validators.InputRequired()]
|
||||
)
|
||||
|
||||
new_password = wtforms.PasswordField(
|
||||
# TODO(i18n)
|
||||
"New password",
|
||||
validators=[wtforms.validators.InputRequired()]
|
||||
)
|
||||
|
||||
new_password_confirm = wtforms.PasswordField(
|
||||
# TODO(i18n)
|
||||
"Confirm new password",
|
||||
validators=[wtforms.validators.InputRequired(),
|
||||
wtforms.validators.EqualTo("new_password")]
|
||||
wtforms.validators.EqualTo(
|
||||
"new_password",
|
||||
# TODO(i18n)
|
||||
"The new passwords must match."
|
||||
)]
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user