diff --git a/app/controllers/Dev.scala b/app/controllers/Dev.scala index 7b393fd083..98bcd53d3c 100644 --- a/app/controllers/Dev.scala +++ b/app/controllers/Dev.scala @@ -62,4 +62,8 @@ object Dev extends LilaController { private def runAs(user: lila.user.User.ID, command: String): Fu[String] = Env.mod.logApi.cli(user, command) >> Env.api.cli(command.split(" ").toList) + + def ui = Open { implicit ctx => + Ok(html.dev.ui()).fuccess + } } diff --git a/app/ui/scalatags.scala b/app/ui/scalatags.scala index f98674edf6..18cb8e1780 100644 --- a/app/ui/scalatags.scala +++ b/app/ui/scalatags.scala @@ -65,7 +65,7 @@ trait ScalatagsTemplate extends Styles with ScalatagsPrefix { val trans = lila.i18n.I18nKeys - val main = tag("main") + def main = scalatags.Text.tags2.main } object ScalatagsTemplate extends ScalatagsTemplate diff --git a/app/views/dev/ui.scala b/app/views/dev/ui.scala new file mode 100644 index 0000000000..64ff41d258 --- /dev/null +++ b/app/views/dev/ui.scala @@ -0,0 +1,30 @@ +package views.html.dev + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object ui { + + def apply()(implicit ctx: Context) = views.html.base.layout( + title = "UI test", + moreCss = responsiveCssTag("palette"), + responsive = true + ) { + main(cls := "ui-test box box-pad")( + h1("H1 header title"), + h2("H2 header title"), + h3("H3 header title"), + h4("H4 header title"), + p( + "

Random quotes: ", + (1 to 10).map(_ => lila.quote.Quote.one.text).mkString(" ") + ), + div(cls := "palette")( + List("background", "primary", "secondary", "accent", "brag", "error", "fancy", "font").map { c => + div(cls := s"color $c")(div(cls := "variants")) + } + ) + ) + }.toHtml +} diff --git a/app/views/game/importGame.scala b/app/views/game/importGame.scala index 4a9d2e8b5e..18de076ffb 100644 --- a/app/views/game/importGame.scala +++ b/app/views/game/importGame.scala @@ -19,7 +19,7 @@ object importGame { openGraph = lila.app.ui.OpenGraph( title = "Paste PGN chess game", url = s"$netBaseUrl${routes.Importer.importGame.url}", - description = "When pasting a game PGN, you get a browsable replay, a computer analysis, a game chat and a sharable URL" + description = trans.importGameExplanation.txt() ).some, responsive = true ) { diff --git a/conf/routes b/conf/routes index fe62557972..ee24ae0e91 100644 --- a/conf/routes +++ b/conf/routes @@ -589,6 +589,7 @@ POST /dev/cli controllers.Dev.cliPost POST /cli controllers.Dev.command GET /dev/settings controllers.Dev.settings POST /dev/settings/:id controllers.Dev.settingsPost(id: String) +GET /dev/ui controllers.Dev.ui # Mobile Push POST /mobile/register/:platform/:deviceId controllers.Main.mobileRegister(platform: String, deviceId: String) diff --git a/translation/source/site.xml b/translation/source/site.xml index 17909df04f..b2a7a4beb3 100644 --- a/translation/source/site.xml +++ b/translation/source/site.xml @@ -338,8 +338,8 @@ From position Continue from here Import game - When pasting a game PGN you get a browsable replay, -a computer analysis, a game chat and a shareable URL. + Paste a game PGN to get a browsable replay, +computer analysis, game chat and shareable URL. %s imported game %s imported games diff --git a/ui/common/css/_lichess.scss b/ui/common/css/_lichess.scss index 46c3ccc71b..5de1bbf648 100644 --- a/ui/common/css/_lichess.scss +++ b/ui/common/css/_lichess.scss @@ -7,10 +7,12 @@ @import 'abstracts/mixins'; @import 'abstracts/extends'; @import 'abstracts/z-index'; +@import 'abstracts/fluid-size'; @import 'base/reset'; @import 'base/fonts'; @import 'base/elements'; +@import 'base/typography'; @import 'base/layout'; @import 'base/data-icon'; diff --git a/ui/common/css/abstracts/_extends.scss b/ui/common/css/abstracts/_extends.scss index 1a80ddd21a..4b3f3447c2 100644 --- a/ui/common/css/abstracts/_extends.scss +++ b/ui/common/css/abstracts/_extends.scss @@ -3,10 +3,12 @@ padding-bottom: 100%; width: 100%; } +%box-radius { + @include box-radius; +} %box-shadow { - box-shadow: $box-shadow; + @include box-shadow; } %box-neat { - box-shadow: $box-shadow; - border-radius: $border-radius; + @include box-neat; } diff --git a/ui/common/css/abstracts/_fluid-size.scss b/ui/common/css/abstracts/_fluid-size.scss new file mode 100644 index 0000000000..595304b33f --- /dev/null +++ b/ui/common/css/abstracts/_fluid-size.scss @@ -0,0 +1,22 @@ +@function strip-unit($value) { + @return $value / ($value * 0 + 1); +} + +@mixin fluid-size($min-vw, $max-vw, $min-font-size, $max-font-size) { + $u1: unit($min-vw); + $u2: unit($max-vw); + $u3: unit($min-font-size); + $u4: unit($max-font-size); + + @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 { + & { + font-size: $min-font-size; + @media screen and (min-width: $min-vw) { + font-size: calc(#{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} * ((100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)})); + } + @media screen and (min-width: $max-vw) { + font-size: $max-font-size; + } + } + } +} diff --git a/ui/common/css/abstracts/_media-queries.scss b/ui/common/css/abstracts/_media-queries.scss index c9308a3cf1..6ba88d0173 100644 --- a/ui/common/css/abstracts/_media-queries.scss +++ b/ui/common/css/abstracts/_media-queries.scss @@ -25,6 +25,8 @@ $mq-hover-no: (hover none); /* Aliases */ +$mq-main-margin: $mq-medium; + $mq-topnav-visible: $mq-medium; $mq-topnav-hidden: $mq-not-medium; diff --git a/ui/common/css/abstracts/_mixins.scss b/ui/common/css/abstracts/_mixins.scss index 10d8f5269e..5c299d7ce3 100644 --- a/ui/common/css/abstracts/_mixins.scss +++ b/ui/common/css/abstracts/_mixins.scss @@ -1,6 +1,12 @@ -@mixin box-neat { +@mixin box-radius { + border-radius: $box-radius-size; +} +@mixin box-shadow { box-shadow: $box-shadow; - border-radius: $border-radius; +} +@mixin box-neat { + @include box-radius; + @include box-shadow; } @mixin board-scale-config { diff --git a/ui/common/css/abstracts/_variables.scss b/ui/common/css/abstracts/_variables.scss index 3096c5b67a..576c66fd32 100644 --- a/ui/common/css/abstracts/_variables.scss +++ b/ui/common/css/abstracts/_variables.scss @@ -2,7 +2,7 @@ $font-path: "../font"; $block-gap: 1.5vmin; -$border-radius: 3px; +$box-radius-size: 3px; $site-header-tall-height: 60px; $site-header-short-height: 40px; diff --git a/ui/common/css/base/_elements.scss b/ui/common/css/base/_elements.scss index 79c96bb31e..5dff910364 100644 --- a/ui/common/css/base/_elements.scss +++ b/ui/common/css/base/_elements.scss @@ -1,18 +1,9 @@ -html { - font: 1rem/1.6 'Noto Sans', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif; -} - body { background: $c-background linear-gradient(to bottom, $c-body-gradient, $c-background 116px) no-repeat; color: $c-font; overflow-x: hidden; } -h1 { - font: 3rem 'Roboto'; - font-weight: normal; -} - a { color: $c-link; text-decoration: none; diff --git a/ui/common/css/base/_layout.scss b/ui/common/css/base/_layout.scss index f7cdad4ca0..2bccca6592 100644 --- a/ui/common/css/base/_layout.scss +++ b/ui/common/css/base/_layout.scss @@ -5,7 +5,7 @@ body { } --main-margin: 0; - @include breakpoint($mq-medium) { + @include breakpoint($mq-main-margin) { --main-margin: #{$block-gap}; margin-bottom: $block-gap; } diff --git a/ui/common/css/base/_typography.scss b/ui/common/css/base/_typography.scss new file mode 100644 index 0000000000..687dcac2de --- /dev/null +++ b/ui/common/css/base/_typography.scss @@ -0,0 +1,37 @@ +/* Viewport limits */ +$vp-min-width: 320px; +$vp-max-width: 1200px; + +html { + // font-family: 'Noto Sans', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif; + // font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", 'Noto Sans', Roboto, Ubuntu, "Helvetica Neue", sans-serif; + font-family: 'Noto Sans', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; + @include fluid-size($vp-min-width, $vp-max-width, 14px, 16px); + font-smoothing: antialiased; +} +// html { +// font: 1rem/1.6 'Noto Sans', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif; +// } + +h1, +h2, +h3, +h4 { + font-family: 'Roboto'; + font-weight: normal; +} +h1 { + @include fluid-size($vp-min-width, $vp-max-width, 27px, 50px); +} +h2 { + @include fluid-size($vp-min-width, $vp-max-width, 23px, 40px); +} +h3 { + font-weight: bold; + color: $c-font-dim; + @include fluid-size($vp-min-width, $vp-max-width, 20px, 30px); +} +h4 { + color: $c-font-dim; + @include fluid-size($vp-min-width, $vp-max-width, 20px, 26px); +} diff --git a/ui/common/css/components/_box.scss b/ui/common/css/components/_box.scss index 95b85058f4..5bf5aa9b66 100644 --- a/ui/common/css/components/_box.scss +++ b/ui/common/css/components/_box.scss @@ -1,8 +1,14 @@ .box { - @extend %box-neat; background: $c-background-clear; + @extend %box-shadow; &-pad { padding: 3vh 3vw; } } + +@include breakpoint($mq-main-margin) { + main.box { + @include box-radius; + } +} diff --git a/ui/common/css/components/_site-header.scss b/ui/common/css/components/_site-header.scss index d44112d184..6b648eb0a5 100644 --- a/ui/common/css/components/_site-header.scss +++ b/ui/common/css/components/_site-header.scss @@ -103,6 +103,7 @@ body.dark #clinput input { } #reconnecting { + display: none; opacity: 0; } body.offline #reconnecting, diff --git a/ui/common/css/components/_subnav.scss b/ui/common/css/components/_subnav.scss index a029ea7899..9ac54ea680 100644 --- a/ui/common/css/components/_subnav.scss +++ b/ui/common/css/components/_subnav.scss @@ -14,7 +14,7 @@ display: flex; align-items: center; background: $c-background-clear; - border-radius: $border-radius; + @include box-radius; &:hover { color: $c-link; } @@ -37,7 +37,7 @@ border-bottom: 1px solid $c-link; } &.active { - border-radius: 3px 0 0 3px; + border-radius: $box-radius-size 0 0 $box-radius-size; background: $c-background-clear; font-weight: bold; box-shadow: $box-shadow; diff --git a/ui/site/css/_importer.scss b/ui/site/css/_importer.scss index 10201421bc..48d13dc915 100644 --- a/ui/site/css/_importer.scss +++ b/ui/site/css/_importer.scss @@ -29,7 +29,7 @@ main.importer { } & button.submit { - margin: 1em auto 0 auto; + margin: 0 auto; display: block; } diff --git a/ui/site/css/_palette.scss b/ui/site/css/_palette.scss new file mode 100644 index 0000000000..83f72a99be --- /dev/null +++ b/ui/site/css/_palette.scss @@ -0,0 +1,131 @@ +$palette-colors: ( +'background': ( +'dim': $c-background-dim, +'base': $c-background, +'clear': $c-background-clear +), +'primary': ( +'dim': c-dimmer($c-primary), +'base': $c-primary, +'clear': c-clearer($c-primary) +), +'secondary': ( +'dim': c-dimmer($c-secondary), +'base': $c-secondary, +'clear': c-clearer($c-secondary) +), +'accent': ( +'dim': c-dimmer($c-accent), +'base': $c-accent, +'clear': c-clearer($c-accent) +), +'brag': ( +'dim': c-dimmer($c-brag), +'base': $c-brag, +'clear': c-clearer($c-brag) +), +'error': ( +'dim': c-dimmer($c-error), +'base': $c-error, +'clear': c-clearer($c-error) +), +'fancy': ( +'dim': c-dimmer($c-fancy), +'base': $c-fancy, +'clear': c-clearer($c-fancy) +), +'font': ( +'dim': c-dimmer($c-font), +'base': $c-font, +'clear': c-clearer($c-font) +), +); + +$variant-height: 2.5rem; + +.palette { + display: grid; + grid-column-gap: $block-gap; + grid-row-gap: $block-gap; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + + & *, + & *:before, + & *:after { + position: relative; + } + + & .color { + height: 16rem; + display: block; + @extend %box-neat; + + &:before, &:after { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 30%; + bottom: 0; + left: 0; + border-top: $borders; + padding: 0.5rem; + text-transform: uppercase; + overflow: hidden; + } + + &:before { + background-color: $c-background-clear; + border-radius: 0 0 $box-radius-size $box-radius-size; + font-weight: bold; + } + + &:after { + padding-top: 2rem; + font-size: 80%; + } + + @each $color-key, $color-variants in $palette-colors { + $base-color-value: map-get($color-variants, 'base'); + + &.#{$color-key} { + background-color: $base-color-value; + + &:before { content: "#{$color-key}"; } + &:after { content: "#{$base-color-value}"; } + + $variant-gradient: (unquote("to bottom"),); + + $index: 0; + @each $variant-name, $variant-value in $color-variants { + $variant-gradient: append($variant-gradient, $variant-value $index * $variant-height); + $index: $index + 1; + $variant-gradient: append($variant-gradient, $variant-value $index * $variant-height); + } + + .variants { + border-left: 1px solid white; + border-bottom: 1px solid white; + border-radius: 0 0 0 $box-radius-size; + position: absolute; + height: $variant-height * length($color-variants); + width: 60%; + right: 0; + top: 0; + background: linear-gradient(#{$variant-gradient}); + overflow: hidden; + &::before { + line-height: 2.5rem; + content: 'Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris.'; + left: .5rem; + } + color: #fff; + } + } + } + &.background .variants { + color: $c-font; + } + } +} + diff --git a/ui/site/css/build/_palette.scss b/ui/site/css/build/_palette.scss new file mode 100644 index 0000000000..cb686bce70 --- /dev/null +++ b/ui/site/css/build/_palette.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/lichess'; +@import '../../../common/css/components/form3'; +@import '../palette'; diff --git a/ui/site/css/build/palette.dark.scss b/ui/site/css/build/palette.dark.scss new file mode 100644 index 0000000000..33f132a03d --- /dev/null +++ b/ui/site/css/build/palette.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/themes/dark'; +@import 'palette'; diff --git a/ui/site/css/build/palette.light.scss b/ui/site/css/build/palette.light.scss new file mode 100644 index 0000000000..a2548e6785 --- /dev/null +++ b/ui/site/css/build/palette.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/themes/light'; +@import 'palette'; diff --git a/ui/site/css/build/palette.transp.scss b/ui/site/css/build/palette.transp.scss new file mode 100644 index 0000000000..d7105bad19 --- /dev/null +++ b/ui/site/css/build/palette.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/themes/transp'; +@import 'palette';