summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2020-04-20 20:20:52 +0200
committerDaniel Friesel <derf@finalrewind.org>2020-04-20 20:20:52 +0200
commiteeedb40bdc0510dec0e2ddca149e82bff7495d0a (patch)
treeb80eb0f9908016382e8a36d9dd9f321cdd44473f
parent375f02ad634c10030f47af94f0530dda0d2d044d (diff)
switch to a proper dark theme using javascript and sass3.1.0
The dark=1 option is still supported, but no longer visible in the UI.
-rw-r--r--lib/DBInfoscreen.pm18
-rw-r--r--lib/DBInfoscreen/Controller/Stationboard.pm1
-rw-r--r--public/static/css/dark.min.css1
-rw-r--r--public/static/css/light.min.css1
-rw-r--r--sass/app.scss (renamed from public/static/css/app.css)223
-rw-r--r--sass/dark.scss39
-rw-r--r--sass/light.scss39
-rw-r--r--templates/app.html.ep7
-rw-r--r--templates/layouts/app.html.ep45
-rw-r--r--templates/wagenreihung.html.ep4
10 files changed, 210 insertions, 168 deletions
diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm
index 6be6e2c..1828737 100644
--- a/lib/DBInfoscreen.pm
+++ b/lib/DBInfoscreen.pm
@@ -26,6 +26,24 @@ my %default = (
sub startup {
my ($self) = @_;
+ $self->hook(
+ before_dispatch => sub {
+ my ($self) = @_;
+
+ # The "theme" cookie is set client-side if the theme we delivered was
+ # changed by dark mode detection or by using the theme switcher. It's
+ # not part of Mojolicious' session data (and can't be, due to
+ # signing and HTTPOnly), so we need to add it here.
+
+ for my $cookie ( @{ $self->req->cookies } ) {
+ if ( $cookie->name eq 'theme' ) {
+ $self->session( theme => $cookie->value );
+ return;
+ }
+ }
+ }
+ );
+
$self->attr(
cache_hafas => sub {
my ($self) = @_;
diff --git a/lib/DBInfoscreen/Controller/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm
index 8ac8101..4a9c94d 100644
--- a/lib/DBInfoscreen/Controller/Stationboard.pm
+++ b/lib/DBInfoscreen/Controller/Stationboard.pm
@@ -517,7 +517,6 @@ sub handle_request {
my $show_details = $self->param('detailed') // 0;
my $backend = $self->param('backend') // 'iris';
my $admode = $self->param('admode') // 'deparr';
- my $dark_layout = $self->param('dark') // 0;
my $apiver = $self->param('version') // 0;
my $callback = $self->param('callback');
my $with_related = !$self->param('no_related');
diff --git a/public/static/css/dark.min.css b/public/static/css/dark.min.css
new file mode 100644
index 0000000..2c386b0
--- /dev/null
+++ b/public/static/css/dark.min.css
@@ -0,0 +1 @@
+body{margin:0;color:#fff;background-color:#000}html{font-family:Sans-Serif}a{color:#99f;text-decoration:none}p,div.about,div.input-field,div.notes{max-width:94%;margin-left:auto;margin-right:auto}p{text-align:justify}div.content{width:100%;margin:0}.wagonorder{position:relative;width:100%;height:100ex}.wagonorder .section{position:absolute;left:1em;width:2em;text-align:center}.wagonorder .wagon{position:absolute;left:3em;min-width:6em;border:1px solid #999;padding-left:0.2em;padding-right:0.2em}.wagonorder .wagon~.wagon{border-top:none}.wagonorder .firstclass{background-color:#330}.wagonorder .powercar{background-color:#222}.wagonorder .wagon .material-icons{color:#bbb}.wagonorder .wagon .direction{position:absolute;left:0.2em;bottom:0;right:0;text-align:center;color:#bbb}.wagonorder .nondestwagon{border-style:dashed}.wagonorder .details{position:absolute;padding-top:0.5ex;left:10em;right:0em}.wagonorder .details .type{display:inline-block;width:5em;color:#bbb}.wagonorder .details .uicunknown{color:#999}.wagonorder .details .uicexchange{margin-right:0.2em;color:#999}.wagonorder .details .uiccountry{margin-right:0.2em;color:#999}.wagonorder .details .uic5{margin-right:0.2em;color:#999}.wagonorder .details .uic56{color:#bbb;font-weight:bold}.wagonorder .details .uic78{margin-right:0.2em;color:#bbb;font-weight:bold}.wagonorder .details .uic78::before{content:"-"}.wagonorder .details .uictype{margin-right:0.2em;color:#bbb;font-weight:bold}.wagonorder .details .uicno{color:#bbb}.wagonorder .details .uiccheck{color:#999}.wagonorder .details .uiccheck::before{content:"-"}div.app{border-width:1px 2px;width:100%;margin-bottom:5em}div.app>ul{position:relative;width:100%;list-style-type:none;margin:0;padding:0}div.app>ul>li{min-height:7em;display:block;width:100%;position:relative;cursor:pointer;border-bottom:1px solid #999;background-color:#000}div.app li .line{font-size:2.7em;position:absolute;bottom:5px;left:2px;max-width:6em;max-height:3ex;overflow:hidden}div.app li .line .trainsubtype{font-weight:normal;font-size:70%;position:relative;vertical-align:baseline;top:-0.6ex;left:-0.5ex}div.app li .line .trainno{font-weight:normal}div.app li .line .trainno_sub{font-weight:normal;font-size:0.6em;text-align:center;margin-top:-0.2em}div.app li .sbahn .trainno_sub{font-weight:normal;font-size:0.5em;text-align:center;margin-top:-0.25em}div.app li .lineinfo{color:#fff;font-size:2em;position:absolute;top:0px;left:2px}div.app .replacement{color:#afa}div.app .replaced{color:#faa}div.app .sbahn{font-weight:bold;border-radius:30px;padding:3px 6px 2px 6px;background-color:#151}div.app .bahn,div.app .fern,div.app .ext{font-weight:bold;border-radius:5px;padding:3px 5px 2px 5px}div.app .bahn{background-color:#333}div.app .fern{background-color:#511}div.app .ext{background-color:#511;border:2px solid #933}div.app li .route{background-color:transparent;font-size:2.1em;position:absolute;top:1px;left:7.7em;height:1.2em;width:70%;overflow:hidden;color:#ddd}div.app li .info{color:#f77;background-color:transparent;font-size:2.1em;position:absolute;top:1px;left:7.7em;height:1.2em;width:70%;overflow:hidden}div.app .moreinfo{font-size:2.1em;position:fixed;left:0;right:0;bottom:0em;z-index:5;overflow:auto;cursor:default;background-color:#000}div.app .moreinfo .mheader,div.app .moreinfo .mfooter{max-width:50em;margin-left:auto;margin-right:auto}div.app .collapsed-moreinfo{display:none}div.app .expanded-moreinfo{display:block}div.app .moreinfo .mheader{text-align:center;font-size:120%;padding-top:0.5em;padding-bottom:0.5em;padding-left:1em;padding-right:1em;border-bottom:0.1em dashed #cccccc}div.app .moreinfo .mfooter{padding-top:1em;padding-left:1em;padding-right:1em}div.app .moreinfo .loading{text-align:center;width:100%;color:#888888}div.app .moreinfo .reason,div.app .moreinfo .minfo{color:#f77}div.app .moreinfo .verbose{margin-bottom:0.6em}div.app .moreinfo .timeinfo{margin-bottom:0.6em}div.app .moreinfo .mroute .important-stop{color:#fff}div.app .moreinfo .mroute .generic-stop{color:#bbb}div.app .moreinfo .mroute .additional-stop{color:#7f7}div.app .moreinfo .mroute .cancelled-stop{color:#f77}div.app li .dest{background-color:transparent;font-size:4em;position:absolute;top:0.62em;left:4em;bottom:0px;width:70%;overflow:hidden;color:#fff}div.app li.cancelled{background-color:#512f00}div.app li .countdown{background-color:transparent;font-size:3em;position:absolute;right:5px;bottom:2px;padding-left:0.2em;color:#fff}div.app li .header{color:#fff;font-size:2em;font-weight:bold;padding-top:8px;border-width-top:0;display:block;text-align:center}div.app li .head{border-bottom-width:0}div.app li .countdown .delay{font-size:1em;color:#f77;background-color:transparent;padding-right:7px}div.app li .countdown .undelay{font-size:1em;color:#7f7;padding-right:7px}div.app li .countdown .delaynorm{font-size:0.9em;color:#d99;padding-right:7px}div.app li .countdown .undelaynorm{font-size:0.9em;color:#9d9;padding-right:7px}div.app li .countdown .platform{font-weight:bold}div.app li .countdown .changed-platform{color:#f77}div.app li .time{background-color:transparent;font-size:2.3em;position:absolute;right:5px;top:4px;padding-left:0.2em;color:#fff}div.app span.delayed{color:#f77;background-color:transparent}ul.ui-autocomplete{max-height:20em;overflow-x:hidden;overflow-y:auto}div.geolocation{text-align:center}div.candidatestatus{text-align:center;color:#999999}div.candidatelist a{display:block;text-decoration:none;font-size:1.4em;padding-top:0.3em;text-align:center;border-bottom:1px solid #999999}div.candidatelist a .distance:after{content:" km"}div.candidatelist a .distance{font-size:0.6em;color:#999999;padding-top:0.2em;padding-bottom:0.3em}div.about{margin-top:2em;font-family:Sans-Serif;color:#bbb}div.about a{color:#99f;text-decoration:none}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;margin-bottom:20px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.container{max-width:60em;margin-left:auto;margin-right:auto}pre{margin-bottom:2em}span.optional,span.notes{color:#bbb}.moresettings-header{cursor:pointer}.moresettings-header-collapsed:before{content:"▹ "}.moresettings-header-expanded:before{content:"▿ "}.moresettings-collapsed{display:none}.moresettings-expanded{display:block}.developers-header{cursor:pointer}.developers-header-collapsed:before{content:"▹ "}.developers-header-expanded:before{content:"▿ "}.developers-collapsed{display:none}.developers-expanded{display:block}div.break{height:1em}div.field{margin-top:0.3em;margin-bottom:0.6em}input,select,.button{display:inline-block;width:60em;max-width:100%;min-height:1.8em;border-radius:4px;color:#fff;background-color:#000;border:1px solid #444;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);font-size:90%;text-align:center;vertical-align:middle}input[type="text"]{width:59em;padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}select{min-height:2em}input[type="checkbox"]{width:1.5em;box-shadow:none}input[type="submit"],.button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none;padding-top:0.9ex;padding-bottom:0.9ex}.button{padding-top:1.1ex;padding-bottom:0}input[type="submit"]:active,input[type="submit"]:focus,input[type="submit"]:hover,.button:active,.button:focus,.button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="submit"]:active,.button.active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.button-light{color:#ddd;background-color:#000;border-color:#444}.button-light:active,.button-light:focus,.button-light:hover{color:#ddd;background-color:#111;border-color:#333}div.notes{margin-top:2em}div.notes ul{margin-top:1em}div.app{max-width:60em;margin-left:auto;margin-right:auto}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed}nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2)}nav{width:100%;overflow:hidden}nav .nav-wrapper{position:relative;height:100%}nav i,nav i.material-icons{display:block;font-size:24px}nav .brand-logo{position:absolute;display:inline-block;padding-left:0.5rem;z-index:-1}nav ul{margin:0;padding-left:0;list-style-type:none}nav ul li{transition:background-color .3s;float:left;padding:0;list-style-type:none;background-color:#00838f}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}@media only screen and (max-width: 600px){div.app>ul>li{font-size:35%}div.navbar-fixed{height:56px}.moreinfo{top:56px}nav{height:56px;line-height:56px}nav .brand-logo{font-size:1.5rem}nav .nav-wrapper i{height:56px;line-height:56px}}@media only screen and (min-width: 600px){div.app>ul>li{font-size:40%}div.navbar-fixed{height:64px}.moreinfo{top:64px}nav{height:64px;line-height:64px}nav .brand-logo{font-size:2.1rem}nav .nav-wrapper i{height:64px;line-height:64px}}div.app .moreinfo{font-size:100%}
diff --git a/public/static/css/light.min.css b/public/static/css/light.min.css
new file mode 100644
index 0000000..742244f
--- /dev/null
+++ b/public/static/css/light.min.css
@@ -0,0 +1 @@
+body{margin:0;color:#000;background-color:#fff}html{font-family:Sans-Serif}a{color:#009;text-decoration:none}p,div.about,div.input-field,div.notes{max-width:94%;margin-left:auto;margin-right:auto}p{text-align:justify}div.content{width:100%;margin:0}.wagonorder{position:relative;width:100%;height:100ex}.wagonorder .section{position:absolute;left:1em;width:2em;text-align:center}.wagonorder .wagon{position:absolute;left:3em;min-width:6em;border:1px solid #999;padding-left:0.2em;padding-right:0.2em}.wagonorder .wagon~.wagon{border-top:none}.wagonorder .firstclass{background-color:#ff9}.wagonorder .powercar{background-color:#ccc}.wagonorder .wagon .material-icons{color:#666}.wagonorder .wagon .direction{position:absolute;left:0.2em;bottom:0;right:0;text-align:center;color:#666}.wagonorder .nondestwagon{border-style:dashed}.wagonorder .details{position:absolute;padding-top:0.5ex;left:10em;right:0em}.wagonorder .details .type{display:inline-block;width:5em;color:#666}.wagonorder .details .uicunknown{color:#999}.wagonorder .details .uicexchange{margin-right:0.2em;color:#999}.wagonorder .details .uiccountry{margin-right:0.2em;color:#999}.wagonorder .details .uic5{margin-right:0.2em;color:#999}.wagonorder .details .uic56{color:#666;font-weight:bold}.wagonorder .details .uic78{margin-right:0.2em;color:#666;font-weight:bold}.wagonorder .details .uic78::before{content:"-"}.wagonorder .details .uictype{margin-right:0.2em;color:#666;font-weight:bold}.wagonorder .details .uicno{color:#666}.wagonorder .details .uiccheck{color:#999}.wagonorder .details .uiccheck::before{content:"-"}div.app{border-width:1px 2px;width:100%;margin-bottom:5em}div.app>ul{position:relative;width:100%;list-style-type:none;margin:0;padding:0}div.app>ul>li{min-height:7em;display:block;width:100%;position:relative;cursor:pointer;border-bottom:1px solid #999;background-color:#fff}div.app li .line{font-size:2.7em;position:absolute;bottom:5px;left:2px;max-width:6em;max-height:3ex;overflow:hidden}div.app li .line .trainsubtype{font-weight:normal;font-size:70%;position:relative;vertical-align:baseline;top:-0.6ex;left:-0.5ex}div.app li .line .trainno{font-weight:normal}div.app li .line .trainno_sub{font-weight:normal;font-size:0.6em;text-align:center;margin-top:-0.2em}div.app li .sbahn .trainno_sub{font-weight:normal;font-size:0.5em;text-align:center;margin-top:-0.25em}div.app li .lineinfo{color:#000;font-size:2em;position:absolute;top:0px;left:2px}div.app .replacement{color:#060}div.app .replaced{color:#600}div.app .sbahn{font-weight:bold;border-radius:30px;padding:3px 6px 2px 6px;background-color:#95d79f}div.app .bahn,div.app .fern,div.app .ext{font-weight:bold;border-radius:5px;padding:3px 5px 2px 5px}div.app .bahn{background-color:#eee}div.app .fern{background-color:#fdd}div.app .ext{background-color:#fdd;border:2px solid #f66}div.app li .route{background-color:transparent;font-size:2.1em;position:absolute;top:1px;left:7.7em;height:1.2em;width:70%;overflow:hidden;color:#444}div.app li .info{color:red;background-color:transparent;font-size:2.1em;position:absolute;top:1px;left:7.7em;height:1.2em;width:70%;overflow:hidden}div.app .moreinfo{font-size:2.1em;position:fixed;left:0;right:0;bottom:0em;z-index:5;overflow:auto;cursor:default;background-color:#fff}div.app .moreinfo .mheader,div.app .moreinfo .mfooter{max-width:50em;margin-left:auto;margin-right:auto}div.app .collapsed-moreinfo{display:none}div.app .expanded-moreinfo{display:block}div.app .moreinfo .mheader{text-align:center;font-size:120%;padding-top:0.5em;padding-bottom:0.5em;padding-left:1em;padding-right:1em;border-bottom:0.1em dashed #cccccc}div.app .moreinfo .mfooter{padding-top:1em;padding-left:1em;padding-right:1em}div.app .moreinfo .loading{text-align:center;width:100%;color:#888888}div.app .moreinfo .reason,div.app .moreinfo .minfo{color:red}div.app .moreinfo .verbose{margin-bottom:0.6em}div.app .moreinfo .timeinfo{margin-bottom:0.6em}div.app .moreinfo .mroute .important-stop{color:#000}div.app .moreinfo .mroute .generic-stop{color:#666}div.app .moreinfo .mroute .additional-stop{color:#090}div.app .moreinfo .mroute .cancelled-stop{color:#c00}div.app li .dest{background-color:transparent;font-size:4em;position:absolute;top:0.62em;left:4em;bottom:0px;width:70%;overflow:hidden;color:#000}div.app li.cancelled{background-color:#ffe7d0}div.app li .countdown{background-color:transparent;font-size:3em;position:absolute;right:5px;bottom:2px;padding-left:0.2em;color:#000}div.app li .header{color:#000;font-size:2em;font-weight:bold;padding-top:8px;border-width-top:0;display:block;text-align:center}div.app li .head{border-bottom-width:0}div.app li .countdown .delay{font-size:1em;color:red;background-color:transparent;padding-right:7px}div.app li .countdown .undelay{font-size:1em;color:#060;padding-right:7px}div.app li .countdown .delaynorm{font-size:0.9em;color:#b33;padding-right:7px}div.app li .countdown .undelaynorm{font-size:0.9em;color:#383;padding-right:7px}div.app li .countdown .platform{font-weight:bold}div.app li .countdown .changed-platform{color:red}div.app li .time{background-color:transparent;font-size:2.3em;position:absolute;right:5px;top:4px;padding-left:0.2em;color:#000}div.app span.delayed{color:red;background-color:transparent}ul.ui-autocomplete{max-height:20em;overflow-x:hidden;overflow-y:auto}div.geolocation{text-align:center}div.candidatestatus{text-align:center;color:#999999}div.candidatelist a{display:block;text-decoration:none;font-size:1.4em;padding-top:0.3em;text-align:center;border-bottom:1px solid #999999}div.candidatelist a .distance:after{content:" km"}div.candidatelist a .distance{font-size:0.6em;color:#999999;padding-top:0.2em;padding-bottom:0.3em}div.about{margin-top:2em;font-family:Sans-Serif;color:#666}div.about a{color:#009;text-decoration:none}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;margin-bottom:20px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.container{max-width:60em;margin-left:auto;margin-right:auto}pre{margin-bottom:2em}span.optional,span.notes{color:#666}.moresettings-header{cursor:pointer}.moresettings-header-collapsed:before{content:"▹ "}.moresettings-header-expanded:before{content:"▿ "}.moresettings-collapsed{display:none}.moresettings-expanded{display:block}.developers-header{cursor:pointer}.developers-header-collapsed:before{content:"▹ "}.developers-header-expanded:before{content:"▿ "}.developers-collapsed{display:none}.developers-expanded{display:block}div.break{height:1em}div.field{margin-top:0.3em;margin-bottom:0.6em}input,select,.button{display:inline-block;width:60em;max-width:100%;min-height:1.8em;border-radius:4px;color:#000;background-color:#fff;border:1px solid #ccc;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);font-size:90%;text-align:center;vertical-align:middle}input[type="text"]{width:59em;padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}select{min-height:2em}input[type="checkbox"]{width:1.5em;box-shadow:none}input[type="submit"],.button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none;padding-top:0.9ex;padding-bottom:0.9ex}.button{padding-top:1.1ex;padding-bottom:0}input[type="submit"]:active,input[type="submit"]:focus,input[type="submit"]:hover,.button:active,.button:focus,.button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="submit"]:active,.button.active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.button-light{color:#333;background-color:#fff;border-color:#ccc}.button-light:active,.button-light:focus,.button-light:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}div.notes{margin-top:2em}div.notes ul{margin-top:1em}div.app{max-width:60em;margin-left:auto;margin-right:auto}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed}nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2)}nav{width:100%;overflow:hidden}nav .nav-wrapper{position:relative;height:100%}nav i,nav i.material-icons{display:block;font-size:24px}nav .brand-logo{position:absolute;display:inline-block;padding-left:0.5rem;z-index:-1}nav ul{margin:0;padding-left:0;list-style-type:none}nav ul li{transition:background-color .3s;float:left;padding:0;list-style-type:none;background-color:#00838f}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}@media only screen and (max-width: 600px){div.app>ul>li{font-size:35%}div.navbar-fixed{height:56px}.moreinfo{top:56px}nav{height:56px;line-height:56px}nav .brand-logo{font-size:1.5rem}nav .nav-wrapper i{height:56px;line-height:56px}}@media only screen and (min-width: 600px){div.app>ul>li{font-size:40%}div.navbar-fixed{height:64px}.moreinfo{top:64px}nav{height:64px;line-height:64px}nav .brand-logo{font-size:2.1rem}nav .nav-wrapper i{height:64px;line-height:64px}}div.app .moreinfo{font-size:100%}
diff --git a/public/static/css/app.css b/sass/app.scss
index 5ea9767..e9969d2 100644
--- a/public/static/css/app.css
+++ b/sass/app.scss
@@ -1,5 +1,7 @@
body {
margin: 0;
+ color: $fg;
+ background-color: $bg;
}
html {
@@ -7,7 +9,7 @@ html {
}
a {
- color: #000099;
+ color: $link-color;
text-decoration: none;
}
@@ -46,7 +48,7 @@ div.content {
position: absolute;
left: 3em;
min-width: 6em;
- border: 1px solid #999999;
+ border: 1px solid $fg3;
padding-left: 0.2em;
padding-right: 0.2em;
}
@@ -55,8 +57,16 @@ div.content {
border-top: none;
}
+.wagonorder .firstclass {
+ background-color: $firstclass-wagon-color;
+}
+
+.wagonorder .powercar {
+ background-color: $powercar-wagon-color;
+}
+
.wagonorder .wagon .material-icons {
- color: #666666;
+ color: $fg2;
}
.wagonorder .wagon .direction {
@@ -65,7 +75,7 @@ div.content {
bottom: 0;
right: 0;
text-align: center;
- color: #666666;
+ color: $fg2;
}
.wagonorder .nondestwagon {
@@ -82,36 +92,36 @@ div.content {
.wagonorder .details .type {
display: inline-block;
width: 5em;
- color: #666666;
+ color: $fg2;
}
.wagonorder .details .uicunknown {
- color: #999999;
+ color: $fg3;
}
.wagonorder .details .uicexchange {
margin-right: 0.2em;
- color: #999999;
+ color: $fg3;
}
.wagonorder .details .uiccountry {
margin-right: 0.2em;
- color: #999999;
+ color: $fg3;
}
.wagonorder .details .uic5 {
margin-right: 0.2em;
- color: #999999;
+ color: $fg3;
}
.wagonorder .details .uic56 {
- color: #666666;
+ color: $fg2;
font-weight: bold;
}
.wagonorder .details .uic78 {
margin-right: 0.2em;
- color: #666666;
+ color: $fg2;
font-weight: bold;
}
@@ -121,16 +131,16 @@ div.content {
.wagonorder .details .uictype {
margin-right: 0.2em;
- color: #666666;
+ color: $fg2;
font-weight: bold;
}
.wagonorder .details .uicno {
- color: #666666;
+ color: $fg2;
}
.wagonorder .details .uiccheck {
- color: #999999;
+ color: $fg3;
}
.wagonorder .details .uiccheck::before {
@@ -158,16 +168,8 @@ div.app > ul > li {
width:100%;
position:relative;
cursor: pointer;
-}
-
-div.appdark > ul > li {
- border-bottom: 1px solid #999999;
- background-color: #000000;
-}
-
-div.applight > ul > li {
- border-bottom: 1px solid #999999;
- background-color: #ffffff;
+ border-bottom: 1px solid $li-border-color;
+ background-color: $bg;
}
div.app li .line {
@@ -208,7 +210,7 @@ div.app li .sbahn .trainno_sub {
}
div.app li .lineinfo {
- color:#000000;
+ color:$fg;
font-size: 2em;
position:absolute;
top:0px;
@@ -216,25 +218,18 @@ div.app li .lineinfo {
}
div.app .replacement {
- color: #006600;
+ color: $replacement-color;
}
div.app .replaced {
- color: #660000;
+ color: $replaced-color;
}
div.app .sbahn {
font-weight:bold;
border-radius: 30px;
padding:3px 6px 2px 6px;
-}
-
-div.applight .sbahn {
- background-color:#95d79f;
-}
-
-div.appdark .sbahn {
- background-color:#115511;
+ background-color: $sbahn-color;
}
div.app .bahn,
@@ -245,30 +240,17 @@ div.app .ext {
padding:3px 5px 2px 5px;
}
-div.applight .bahn {
- background-color: #eeeeee;
-}
-
-div.appdark .bahn {
- background-color: #333333;
-}
-
-div.applight .fern {
- background-color: #ffdddd;
+div.app .bahn {
+ background-color: $bahn-color;
}
-div.appdark .fern {
- background-color: #551111;
+div.app .fern {
+ background-color: $fern-color;
}
-div.applight .ext {
- background-color: #ffdddd;
- border: 2px solid #ff6666;
-}
-
-div.appdark .ext {
- background-color: #551111;
- border: 2px solid #993333;
+div.app .ext {
+ background-color: $fern-color;
+ border: 2px solid $ext-border-color;
}
div.app li .route {
@@ -280,18 +262,11 @@ div.app li .route {
height: 1.2em;
width: 70%;
overflow: hidden;
-}
-
-div.applight li .route {
- color:#444444;
-}
-
-div.appdark li .route {
- color:#bbbbbb;
+ color: $route-color;
}
div.app li .info {
- color:#ff0000;
+ color: $info-color;
background-color: transparent;
font-size:2.1em;
position:absolute;
@@ -311,6 +286,7 @@ div.app .moreinfo {
z-index: 5;
overflow: auto;
cursor: default;
+ background-color: $bg;
}
div.app .moreinfo .mheader,
@@ -320,14 +296,6 @@ div.app .moreinfo .mfooter {
margin-right: auto;
}
-div.applight .moreinfo {
- background-color: #ffffff;
-}
-
-div.appdark .moreinfo {
- background-color: #000000;
-}
-
div.app .collapsed-moreinfo {
display: none;
}
@@ -360,7 +328,7 @@ div.app .moreinfo .loading {
div.app .moreinfo .reason,
div.app .moreinfo .minfo {
- color: #ff0000;
+ color: $info-color;
}
div.app .moreinfo .verbose {
@@ -371,36 +339,20 @@ div.app .moreinfo .timeinfo {
margin-bottom: 0.6em;
}
-div.applight .moreinfo .mroute .important-stop {
- color: #000000;
+div.app .moreinfo .mroute .important-stop {
+ color: $fg;
}
-div.appdark .moreinfo .mroute .important-stop {
- color: #ffffff;
+div.app .moreinfo .mroute .generic-stop {
+ color: $fg2;
}
-div.applight .moreinfo .mroute .generic-stop {
- color: #555555;
+div.app .moreinfo .mroute .additional-stop {
+ color: $additional-stop-color;
}
-div.appdark .moreinfo .mroute .generic-stop {
- color: #999999;
-}
-
-div.applight .moreinfo .mroute .additional-stop {
- color: #009900;
-}
-
-div.appdark .moreinfo .mroute .additional-stop {
- color: #009900;
-}
-
-div.applight .moreinfo .mroute .cancelled-stop {
- color: #cc0000;
-}
-
-div.appdark .moreinfo .mroute .cancelled-stop {
- color: #cc0000;
+div.app .moreinfo .mroute .cancelled-stop {
+ color: $cancelled-stop-color;
}
div.app li .dest {
@@ -412,22 +364,11 @@ div.app li .dest {
bottom:0px;
width: 70%;
overflow: hidden;
+ color: $fg;
}
-div.applight li .dest {
- color:#000000;
-}
-
-div.appdark li .dest {
- color:#ffffff;
-}
-
-div.applight li.cancelled {
- background-color: #ffe7d0;
-}
-
-div.appdark li.cancelled {
- background-color: #512f00;
+div.app li.cancelled {
+ background-color: $cancelled-bg-color;
}
div.app li .countdown {
@@ -437,18 +378,11 @@ div.app li .countdown {
right: 5px;
bottom: 2px;
padding-left: 0.2em;
-}
-
-div.applight li .countdown {
- color: #000000;
-}
-
-div.appdark li .countdown {
- color: #ffffff;
+ color: $fg;
}
div.app li .header {
- color:#000000;
+ color:$fg;
font-size:2em;
font-weight:bold;
padding-top:8px;
@@ -463,26 +397,26 @@ div.app li .head {
div.app li .countdown .delay {
font-size:1em;
- color:#FF0000;
+ color: $delay-color;
background-color: transparent;
padding-right:7px;
}
div.app li .countdown .undelay {
font-size:1em;
- color:#006600;
+ color: $undelay-color;
padding-right:7px;
}
div.app li .countdown .delaynorm {
font-size:0.9em;
- color:#BB3333;
+ color: $delaynorm-color;
padding-right:7px;
}
div.app li .countdown .undelaynorm {
font-size:0.9em;
- color:#338833;
+ color: $undelaynorm-color;
padding-right:7px;
}
@@ -491,7 +425,7 @@ div.app li .countdown .platform {
}
div.app li .countdown .changed-platform {
- color:#ff0000;
+ color: $info-color;
}
div.app li .time {
@@ -501,18 +435,11 @@ div.app li .time {
right:5px;
top:4px;
padding-left: 0.2em;
-}
-
-div.applight li .time {
- color:#000000;
-}
-
-div.appdark li .time {
- color:#ffffff;
+ color: $fg;
}
div.app span.delayed {
- color: #ff0000;
+ color: $delay-color;
background-color: transparent;
}
@@ -554,11 +481,11 @@ div.candidatelist a .distance {
div.about {
margin-top: 2em;
font-family: Sans-Serif;
- color: #666666;
+ color: $fg2;
}
div.about a {
- color: #000066;
+ color: $link-color;
text-decoration: none;
}
@@ -614,7 +541,7 @@ pre {
span.optional,
span.notes {
- color: #666666;
+ color: $fg2;
}
.moresettings-header {
@@ -672,9 +599,9 @@ input, select, .button {
max-width: 100%;
min-height: 1.8em;
border-radius: 4px;
- color: #000;
- background-color: #fff;
- border: 1px solid #ccc;
+ color: $fg;
+ background-color: $bg;
+ border: 1px solid $bg1;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
font-size: 90%;
text-align: center;
@@ -699,6 +626,7 @@ input[type="checkbox"] {
}
input[type="submit"], .button {
+ transition: background-color .3s;
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
@@ -730,18 +658,18 @@ input[type="submit"]:active,
}
.button-light {
- color: #333;
- background-color: #fff;
- border-color: #ccc;
+ color: $fg1;
+ background-color: $bg;
+ border-color: $bg1;
}
.button-light:active,
.button-light:focus,
.button-light:hover
{
- color: #333;
- background-color: #e6e6e6;
- border-color: #adadad;
+ color: $fg1;
+ background-color: $button-hover;
+ border-color: $button-hover-border;
}
div.notes {
@@ -864,6 +792,3 @@ nav ul a {
div.app .moreinfo {
font-size: 100%;
}
-
-.content {
-}
diff --git a/sass/dark.scss b/sass/dark.scss
new file mode 100644
index 0000000..b30da63
--- /dev/null
+++ b/sass/dark.scss
@@ -0,0 +1,39 @@
+$bg: #000000;
+$fg: #ffffff;
+$link-color: #9999ff;
+$fg3: #999999;
+$fg2: #bbbbbb;
+$fg1: #dddddd;
+$bg1: #444444;
+
+$li-border-color: $fg3;
+
+$replacement-color: #aaffaa;
+$replaced-color: #ffaaaa;
+
+$wagon-border-color: $fg3;
+$wagon-material-color: $fg2;
+
+$sbahn-color: #115511;
+$bahn-color: #333333;
+$fern-color: #551111;
+$ext-border-color: #993333;
+
+$route-color: #dddddd;
+
+$info-color: #ff7777;
+$delay-color: #ff7777;
+$undelay-color: #77ff77;
+$delaynorm-color: #dd9999;
+$undelaynorm-color: #99dd99;
+
+$additional-stop-color: #77ff77;
+$cancelled-stop-color: #ff7777;
+
+$cancelled-bg-color: #512f00;
+
+$firstclass-wagon-color: #333300;
+$powercar-wagon-color: #222222;
+
+$button-hover: #111111;
+$button-hover-border: #333333;
diff --git a/sass/light.scss b/sass/light.scss
new file mode 100644
index 0000000..52ff65e
--- /dev/null
+++ b/sass/light.scss
@@ -0,0 +1,39 @@
+$bg: #ffffff;
+$fg: #000000;
+$link-color: #000099;
+$fg3: #999999;
+$fg2: #666666;
+$fg1: #333333;
+$bg1: #cccccc;
+
+$li-border-color: $fg3;
+
+$replacement-color: #006600;
+$replaced-color: #660000;
+
+$wagon-border-color: $fg3;
+$wagon-material-color: $fg2;
+
+$sbahn-color: #95d79f;
+$bahn-color: #eeeeee;
+$fern-color: #ffdddd;
+$ext-border-color: #ff6666;
+
+$route-color: #444444;
+
+$info-color: #ff0000;
+$delay-color: #ff0000;
+$undelay-color: #006600;
+$delaynorm-color: #bb3333;
+$undelaynorm-color: #338833;
+
+$additional-stop-color: #009900;
+$cancelled-stop-color: #cc0000;
+
+$cancelled-bg-color: #ffe7d0;
+
+$firstclass-wagon-color: #ffff99;
+$powercar-wagon-color: #cccccc;
+
+$button-hover: #e6e6e6;
+$button-hover-border: #adadad;
diff --git a/templates/app.html.ep b/templates/app.html.ep
index fd7c1f1..5ceec12 100644
--- a/templates/app.html.ep
+++ b/templates/app.html.ep
@@ -1,12 +1,7 @@
% if (@{$departures}) {
% if (not param('ajax')) {
-% if (param('dark')) {
-<div class="app appdark">
-% }
-% else {
-<div class="app applight">
-% }
+<div class="app">
<div class="moreinfo collapsed-moreinfo">
<div class="mheader">
<div>
diff --git a/templates/layouts/app.html.ep b/templates/layouts/app.html.ep
index 258c6fd..6485a22 100644
--- a/templates/layouts/app.html.ep
+++ b/templates/layouts/app.html.ep
@@ -19,7 +19,37 @@
% }
% my $av = 'v28'; # asset version
- %= stylesheet "/static/${av}/css/app.css"
+ % if (session('theme') and session('theme') eq 'dark' or param('dark')) {
+ %= stylesheet "/static/${av}/css/dark.min.css", id => 'theme'
+ % }
+ % else {
+ %= stylesheet "/static/${av}/css/light.min.css", id => 'theme'
+ % }
+ <script>
+ function addStyleSheet(name, id) {
+ var path = '/static/<%=$av%>/css/' + name + '.min.css';
+ var old = document.getElementById(id);
+ if (old && (old.href != path)) {
+ old.href = path;
+ document.cookie = 'theme=' + name;
+ }
+ }
+ var otherTheme = {
+ 'dark': 'light',
+ 'light': 'dark',
+ };
+ var currentTheme = localStorage.getItem('theme');
+ if (!otherTheme.hasOwnProperty(currentTheme)) {
+ currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+ }
+ addStyleSheet(currentTheme, 'theme');
+
+ function toggleTheme() {
+ currentTheme = otherTheme[currentTheme] || 'light';
+ localStorage.setItem('theme', currentTheme);
+ addStyleSheet(currentTheme, 'theme');
+ }
+ </script>
%= stylesheet "/static/${av}/css/material-icons.css"
%= stylesheet "/static/${av}/css/jquery-ui.min.css"
%= javascript '/static/js/jquery-3.4.1.min.js', defer => undef
@@ -33,7 +63,7 @@
%= javascript "/static/${av}/leaflet/leaflet.js"
% }
</head>
-<body style="<%= (param('dark') ? 'background-color: #000000; color: #ffffff;' : q{}) %>">
+<body>
<div class="navbar-fixed">
<nav style="color: #ffffff; background-color: #00838f;">
@@ -42,6 +72,9 @@
%= stash('title') || 'DBF'
</span>
<ul id="nav-mobile" style="float: right;">
+ <li class="waves-effect waves-light">
+ <a onClick="javascript:toggleTheme()"><i class="material-icons" aria-label="Farbschema invertieren">invert_colors</i></a>
+ </li>
% if (stash('hide_opts')) {
<li><a href="/"><i class="material-icons">edit</i></a></li>
% }
@@ -139,14 +172,6 @@ Bitte eine Station aus der Liste auswählen</div>
</div>
<div class="field">
<div class="desc">
- %= check_box 'dark' => 1, id => 'id_dark'
- <label for="id_dark">
- Dunkles Layout (experimentell)
- </label>
- </div>
- </div>
- <div class="field">
- <div class="desc">
%= check_box 'hide_opts' => 1, id => 'id_hide_opts'
<label for="id_hide_opts">
Formular verstecken (für Infoscreens)
diff --git a/templates/wagenreihung.html.ep b/templates/wagenreihung.html.ep
index 53be3a1..c4fade8 100644
--- a/templates/wagenreihung.html.ep
+++ b/templates/wagenreihung.html.ep
@@ -64,10 +64,10 @@
% my $bg = '';
% my $extra_class = '';
% if ($wagon->is_first_class) {
-% $bg = 'background-color: #ffff99;';
+% $extra_class .= ' firstclass';
% }
% if ($wagon->is_locomotive or $wagon->is_powercar) {
-% $bg = 'background-color: #cccccc;';
+% $extra_class .= ' powercar';
% }
% if ($wagon->train_no ne $train_no) {
% $extra_class .= ' nondestwagon';