From 4c5d2e4afe02479dcfb770fa1d6cfccb499e4fff Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 13 Oct 2023 19:59:06 +0200 Subject: Clean up stylesheet and improve layout on small and large screens. Use variables for color theming. --- public/style.css | 351 ++++++++++++++++++++++++++++++++--------------- views/contacts.pug | 15 +- views/create.pug | 6 +- views/forum_search.pug | 2 +- views/forum_view.pug | 7 +- views/game_stats.pug | 2 +- views/games_active.pug | 2 +- views/games_finished.pug | 2 +- views/games_public.pug | 2 +- views/head.pug | 2 +- views/index.pug | 20 ++- views/join.pug | 24 ++-- views/message_inbox.pug | 18 ++- views/message_outbox.pug | 10 +- views/message_send.pug | 2 - views/stats.pug | 5 +- views/user.pug | 5 +- views/user_stats.pug | 4 +- 18 files changed, 304 insertions(+), 175 deletions(-) diff --git a/public/style.css b/public/style.css index c334e86..165e854 100644 --- a/public/style.css +++ b/public/style.css @@ -1,140 +1,279 @@ -html, input, textarea { - font-family: "Source Serif", "Georgia", "Noto Emoji", "Dingbats", serif; - font-size: 16px; -} -button, select, option { - font-family: "Source Sans", "Verdana", "Noto Emoji", "Dingbats", sans-serif; - font-size: 16px; -} +/* RALLY THE TROOPS - MAIN SITE STYLE */ -html, body { margin: 0 } -h1 { margin: 16px 0 16px -1px; font-size: 24px; } -h2 { margin: 16px 0 16px -1px; font-size: 20px; } -h3 { margin: 16px 0 8px -1px; font-size: 16px; } -a { color: blue; } -a.black { text-decoration: none; color: black; } -a.black:hover { text-decoration: underline; color: blue; } -.w { white-space: nowrap; } -.r { text-align: right; } +:root { + --font-normal: "Source Serif", "Georgia", "Noto Emoji", "Dingbats", serif; + --font-small: "Source Serif SmText", "Georgia", "Noto Emoji", "Dingbats", serif; + --font-widget: "Source Sans", "Verdana", "Noto Emoji", "Dingbats", sans-serif; -header { - display: flex; - align-items: center; - justify-content: space-between; - border-bottom: 2px solid brown; - padding-right: 1em; -} -header img { - display: block; - margin: 4px 0 -2px 2px; + --drop-shadow: 1px 1px 4px #0004; + + --thin-border: 1px solid black; + + --color-black: black; + + --color-table-active: hsla(55, 100%, 50%, 0.15); + --color-table-invite: hsla(120, 100%, 50%, 0.15); + --color-table-danger: hsla(350, 100%, 50%, 0.15); } -header nav { - display: flex; - flex-wrap: wrap; - justify-content: end; + +/* light gray */ +:root { + --color-head: hsl(0, 0%, 85%); + --color-body: hsl(0, 0%, 95%); + --color-text: hsl(0, 0%, 100%); + + --color-post-head: hsl(0, 0%, 85%); + --color-post-body: hsl(0, 0%, 98%); + + --color-table-head: hsl(0, 0%, 85%); + --color-table-foot: hsl(0, 0%, 90%); + --color-table-body: hsl(0, 0%, 98%); + --color-table-stripe: hsl(0, 0%, 96%); + + --color-focus: hsl(210, 40%, 65%); + + --color-blue: hsl(240, 100%, 50%); + --color-red: hsl(0, 100%, 35%); + --color-green: hsl(120, 100%, 30%); + + --color-accent: hsl(0, 60%, 40%); } -header nav a { display: block; margin: 0 12px; color: black } -header nav a:hover { color: blue } -article { margin: 2em; } -article p, article dl, article ul { max-width: 50rem; } -div.logo { - float: left; - margin: 0 20px 5px 0; - min-width: 150px; +/* dark gray */ +@media (prefers-color-scheme: dark) { +:root { + --color-head: hsl(0, 0%, 75%); + --color-body: hsl(0, 0%, 85%); + --color-text: hsl(0, 0%, 95%); + + --color-post-head: hsl(0, 0%, 75%); + --color-post-body: hsl(0, 0%, 90%); + + --color-table-head: hsl(0, 0%, 75%); + --color-table-foot: hsl(0, 0%, 80%); + --color-table-body: hsl(0, 0%, 90%); + --color-table-stripe: hsl(0, 0%, 88%); + + --color-focus: hsl(210, 40%, 60%); + + --color-blue: hsl(240, 100%, 40%); + --color-red: hsl(0, 100%, 35%); + --color-green: hsl(120, 100%, 30%); + + --color-accent: hsl(0, 60%, 35%); +}} + +/* WIDGETS */ + +html, input, textarea { + font-family: var(--font-normal); + font-size: 16px; } -div.logo img { - box-shadow: 1px 2px 4px 0px #0004; + +button, select, option { + font-family: var(--font-widget); + font-size: 16px; } input[type="checkbox"], input[type="radio"] { margin-right: 7px; - accent-color: black; + accent-color: currentcolor; } + input[type="text"], input[type="password"], input[type="email"], textarea { + background-color: var(--color-text); + color: var(--color-black); + border: var(--thin-border); padding: 5px; margin: 5px 0; - border: 1px solid black; + max-width: calc(100% - 12px); vertical-align: middle; } + input:focus, textarea:focus { - outline: 2px solid lightsteelblue; + outline: 2px solid var(--color-focus); } + +select:focus, button:focus { + box-shadow: 0 0 0 3px var(--color-focus); +} + +option { + background-color: var(--color-text); + color: var(--color-black); +} + button, select { margin: 5px 10px 5px 0; padding: 1px 10px; - background-color: gainsboro; vertical-align: middle; border: 2px solid; + + background-color: gainsboro; border-color: white darkgray darkgray white; - outline: 1px solid black; + outline: 1px solid var(--color-black); } + button:enabled:active:hover, select:active { border-color: darkgray white white darkgray; padding: 2px 9px 0px 11px; } -option { - background-color: white; - color: black; -} + button:disabled { color: gray; border-color: gainsboro; outline-color: gray; } -.error { color: brown; font-style: italic; white-space: pre-wrap; } -.warning { color: brown; } +/* PAGE LAYOUT */ + +html, body { margin: 0 } +h1 { margin: 16px 0 16px -1px; font-size: 24px; } +h2 { margin: 16px 0 16px -1px; font-size: 20px; } +h3 { margin: 16px 0 8px -1px; font-size: 16px; } + +html { + overflow-y: scroll; +} + +body { + background-color: var(--color-body); + color: var(--color-black); +} + +header { + display: flex; + align-items: center; + justify-content: space-between; + padding-right: 1em; + background-color: var(--color-head); + border-bottom: 2px solid var(--color-accent); +} + +header img { + display: block; + margin: 4px 0 -2px 2px; +} + +header nav { + display: flex; + flex-wrap: wrap; + justify-content: end; +} + +header nav > * { + display: block; + padding: 0 8px; +} + +article { + margin: 0 auto; + padding: 0 16px; + max-width: 830px; +} + +@media (min-width: 1340px) { + article.wide { max-width: 1250px; } +} + +article hr { border: none; border-top: 2px dotted brown; } +article hr + p { font-style: italic; } + +/* COMMON ELEMENTS */ + +a { color: var(--color-blue); } +nav a, a.black { color: var(--color-black); text-decoration: none; } +nav a:hover, a.black:hover { color: var(--color-blue); text-decoration: underline; } + +table a.black { color: var(--color-black); text-decoration: none; } +table a.black:hover { color: var(--color-blue); text-decoration: underline; } + +.error { color: var(--color-red); font-style: italic; white-space: pre-wrap; } +.warning { color: var(--color-red); } p.warning::before { content: "\26a0 "; } +@media (min-width: 500px) { + div.logo { + float: right; + margin: -20px 0px 8px 16px; + min-width: 150px; + } +} + +div.logo img { + box-shadow: var(--drop-shadow); + border: var(--thin-border); +} + /* TABLES */ table { - background-color: white; - min-width: min(50rem,100%); + background-color: var(--color-table-body); border-collapse: collapse; - border: 1px solid black; - box-shadow: 1px 2px 4px #0004; + border: var(--thin-border); + box-shadow: var(--drop-shadow); margin: 1em 0; } + +table.wide { + width: 100%; +} + +table.half { + min-width: 50%; +} + +thead, th { + background-color: var(--color-table-head); +} + +tfoot { + background-color: var(--color-table-foot); +} + thead, tfoot { - background-color: gainsboro; - border: 1px solid black; + border: var(--thin-border); } + th, td { vertical-align: top; text-align: left; padding: 5px 10px; } -tbody tr:nth-child(2n) { - background-color: whitesmoke; + +table.striped tr:nth-child(2n) { + background-color: var(--color-table-stripe); } -td.is_active { background-color: lemonchiffon; } + +td.r, th.r { text-align: right; } +td.w, th.w { white-space: nowrap; } /* FORUM AND MESSAGE POSTS */ div.post { - background-color: white; - max-width: 50em; + background-color: var(--color-post-body); margin-top: 24px; - border: 1px solid black; - box-shadow: 1px 2px 4px #0004; + border: var(--thin-border); + box-shadow: var(--drop-shadow); } + div.post > div.head { display: flex; justify-content: space-between; padding: 5px 10px; - background-color: gainsboro; - border-bottom: 1px solid black; + background-color: var(--color-post-head); + border-bottom: var(--thin-border); } -div.post > div.head a { font-weight: bold; } -div.post > div.head a:not(:hover) { color: black; text-decoration: none; } -div.post > div.body { padding: 15px; white-space: pre-wrap; } -div.post + div.edit { max-width: 50em; margin-top: 5px; text-align:right; } -article hr { max-width: 50rem; margin-right: auto; margin-left: 0; } -article hr { border: none; border-top: 2px dotted brown; } -article hr + p { font-style: italic; } +div.post > div.body { + padding: 15px; + white-space: pre-wrap; +} + +div.post + div.edit { + margin-top: 5px; + text-align: right; +} /* GAME BOXES */ @@ -144,77 +283,63 @@ article hr + p { font-style: italic; } gap: 24px; margin: 16px 0; } + .game_item { - border: 1px solid black; - box-shadow: 1px 2px 4px #0004; + border: var(--thin-border); + box-shadow: var(--drop-shadow); + color: black; } + .game_head, .game_main { display: flex; justify-content: space-between; padding: 4px 8px; } + .game_head { - border-bottom: 1px solid black; + border-bottom: var(--thin-border); line-height: 23px; } + .game_info { - font-family: "Source Serif SmText", "Georgia", "Noto Emoji", "Dingbats", serif; + font-family: var(--font-small); font-size: 14px; line-height: 20px; } -.game_item a:not(:hover) { text-decoration: none; color: black; } -.game_item a.command { text-decoration: underline; font-weight: bold } -.game_info .is_active { text-decoration: underline } -.game_info .is_invite { opacity: 0.5 } + +.game_item a { text-decoration: none; color: black; } +.game_item a:hover { text-decoration: underline; } +.game_item .game_main a:hover { color: blue; } +.game_info .is_active { text-decoration: underline; } +.game_info .is_invite { opacity: 60%; } .game_info div { text-indent: -20px; padding-left: 20px; } + .game_main img { display: block; height: 72px; margin: 4px 0 4px 4px; - border: 1px solid black; + border: var(--thin-border); } -.game_head { background-color: gainsboro } -.game_main { background-color: whitesmoke } -.game_main a:hover { color: mediumblue } +/* LIGHT MODE - GAME BOXES */ + +.game_item .game_head { background-color: gainsboro } +.game_item .game_main { background-color: whitesmoke } .game_item.open .game_head { background-color: lightskyblue } .game_item.open .game_main { background-color: aliceblue } -.game_item.open a:hover { color: royalblue } - .game_item.ready .game_head { background-color: darkseagreen } .game_item.ready .game_main { background-color: mintcream } -.game_item.ready a:hover { color: seagreen } - .game_item.replacement .game_head { background-color: thistle } .game_item.replacement .game_main { background-color: lavenderblush } -.game_item.replacement a:hover { color: purple } - -.game_item.active .game_head { background-color: gainsboro } -.game_item.active .game_main { background-color: whitesmoke } -.game_item.active a:hover { color: mediumblue } - +.game_item.active .game_head { background-color: tan } +.game_item.active .game_main { background-color: floralwhite } .game_item.finished .game_head { background-color: silver } .game_item.finished .game_main { background-color: gainsboro } -.game_item.finished a:hover { color: mediumblue } - -.game_item.archived .game_head { background-color: silver } -.game_item.archived .game_main { background-color: gainsboro } -.game_item.archived a:hover { color: mediumblue } - +.game_item.archived .game_head { background-color: darkgray } +.game_item.archived .game_main { background-color: lightgray } .game_item.your_turn .game_head { background-color: gold } .game_item.your_turn .game_main { background-color: lightyellow } -.game_item.your_turn a:hover { color: #860 } - -/* DARK MODE */ -@media (prefers-color-scheme: dark) { - body { background-color: silver } - header { background-color: darkgray } - table, div.post { background-color: gainsboro } - thead, tfoot, div.post > div.head { background-color: darkgray } - input, textarea { background-color: gainsboro } - input:focus, textarea:focus { outline-color: cornflowerblue } -} diff --git a/views/contacts.pug b/views/contacts.pug index 64d39d0..8b42e73 100644 --- a/views/contacts.pug +++ b/views/contacts.pug @@ -5,17 +5,16 @@ html include head title Contacts style. - table { min-width: 400px } - td a.red { text-decoration: none; color: brown; font-size: 14px; margin-left: 8px; } - td a.blue { text-decoration: none; color: black; font-size: 16px; margin-left: 8px; } - td a.blue:hover { color: blue; } + td a.red { text-decoration: none; color: var(--color-red); font-size: 14px; margin-left: 8px; } + td a.blue { text-decoration: none; color: var(--color-black); font-size: 16px; margin-left: 8px; } + td a.blue:hover { color: var(--color-blue); } body include header article h1 Friends & Enemies - table + table.half.striped thead tr th Friends @@ -26,8 +25,8 @@ html tr td a.black(href="/user/"+who.name)= who.name - td= who.atime - td.r + td.w= who.atime + td.w.r a.blue(href="/message/send/"+who.name) 📝 a.red(href="/contacts/remove/"+who.name) ❌ else @@ -37,7 +36,7 @@ html if enemies.length > 0 p - table + table.half.striped thead tr th Blacklist diff --git a/views/create.pug b/views/create.pug index 95e0ea0..717c4f0 100644 --- a/views/create.pug +++ b/views/create.pug @@ -4,11 +4,10 @@ html head include head title= title.title_name - style. - form { margin-left: 200px; width: calc(50rem - 200px); } body include header article + h1= title.title_name div.logo @@ -23,11 +22,12 @@ html option(value=scenario)= scenario else input(type="hidden" name="scenario" value=scenarios[0]) + | !{ title.create_html } p Notice: br - input(type="text" autocomplete="off" name="notice" size=50 placeholder="What are you looking for?") + input(type="text" autocomplete="off" name="notice" size=45 placeholder="What are you looking for?") p Pace: br diff --git a/views/forum_search.pug b/views/forum_search.pug index f7d1b42..18df6b0 100644 --- a/views/forum_search.pug +++ b/views/forum_search.pug @@ -9,7 +9,7 @@ html article h1 Forum Search Results - table + table.wide.striped thead tr th Author diff --git a/views/forum_view.pug b/views/forum_view.pug index 1f70c8c..983ccf2 100644 --- a/views/forum_view.pug +++ b/views/forum_view.pug @@ -8,12 +8,17 @@ html style. .unread { font-weight: bold } tbody a { display: block } + @media (max-width: 400px) { + td:nth-child(2) { display: none } + th:nth-child(2) { display: none } + } + body include header article h1 Forum - table + table.wide.striped thead tr th Subject diff --git a/views/game_stats.pug b/views/game_stats.pug index a60d7cb..692c30b 100644 --- a/views/game_stats.pug +++ b/views/game_stats.pug @@ -9,7 +9,7 @@ html article h1 #{title_name} - Ranking - table(style="min-width:auto") + table.striped thead tr th Player diff --git a/views/games_active.pug b/views/games_active.pug index 9e4b909..a65f9be 100644 --- a/views/games_active.pug +++ b/views/games_active.pug @@ -11,7 +11,7 @@ html meta(http-equiv="refresh" content=600) body include header - article + article.wide h1 Your games if open_games.length > 0 diff --git a/views/games_finished.pug b/views/games_finished.pug index 26d0378..8d71717 100644 --- a/views/games_finished.pug +++ b/views/games_finished.pug @@ -6,7 +6,7 @@ html title= SITE_NAME body include header - article + article.wide if user && user.user_id === who.user_id h1 Your finished games else diff --git a/views/games_public.pug b/views/games_public.pug index 62cdfcf..cf102f0 100644 --- a/views/games_public.pug +++ b/views/games_public.pug @@ -8,7 +8,7 @@ html meta(http-equiv="refresh" content=900) body include header - article + article.wide h1 Public Games h2 Open diff --git a/views/head.pug b/views/head.pug index cffc55a..b10c3ce 100644 --- a/views/head.pug +++ b/views/head.pug @@ -21,7 +21,7 @@ mixin gamecover(title_id) mixin forumpost(row,show_buttons) .post(id=row.post_id) .head - .from: a(href="/user/"+row.author_name)= row.author_name + .from: b: a.black(href="/user/"+row.author_name)= row.author_name .time= row.ctime if row.edited | diff --git a/views/index.pug b/views/index.pug index 190018b..60da6ac 100644 --- a/views/index.pug +++ b/views/index.pug @@ -8,30 +8,26 @@ html title= SITE_NAME style. div.list { - display: flex; - flex-wrap: wrap; - gap: 12px; + margin: 24px 0; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + gap: 24px 12px; } div.i { - width: 170px; height: 200px; text-align: center; margin-bottom: 6px; } div.t { text-align: center; - width: 170px; - } - div.t a:not(:hover) { - color: black; - text-decoration: none; } div.i img { - box-shadow: 2px 2px 4px 0px rgba(0,0,0,0.5); + box-shadow: var(--drop-shadow); + border: var(--thin-border); } body include header - article + article.wide h1= SITE_NAME p #{SITE_NAME} is a website where you can play historic board games online. @@ -45,7 +41,7 @@ html div.i +gamecover(title.title_id) div.t - a(href="/"+title.title_id)= title.title_name + a.black(href="/"+title.title_id)= title.title_name p!= process.env.SITE_INVITE diff --git a/views/join.pug b/views/join.pug index 621ab0a..d75ef4d 100644 --- a/views/join.pug +++ b/views/join.pug @@ -8,17 +8,16 @@ html game.title_id) title= game.title_name style. - table { min-width: 0; } - th,td { border: 1px solid black; } - a.red { text-decoration: none; color: brown; font-size: 15px; float: right; } - a.green { text-decoration: none; color: green; font-size: 15px; float: right; } - th { white-space: nowrap; background-color: gainsboro; } - td { width: 180px; background-color: white; } - #message { background-color: whitesmoke; } + th,td { border: var(--table-border); } + a.red { text-decoration: none; color: var(--color-red); font-size: 15px; float: right; } + a.green { text-decoration: none; color: var(--color-green); font-size: 15px; float: right; } + td, th { border: var(--thin-border); } + td { width: 180px; } .hide { display: none; } - td.is_invite { background-color: honeydew } - td.enemy { background-color: #f66 } - td.enemy::before { content: "\1f6ab "; color: #000; font-size: 15px; } + td.is_invite { background-color: var(--color-table-invite); } + td.is_active { background-color: var(--color-table-active); } + td.enemy { background-color: var(--color-table-danger); } + td.enemy::before { content: "\1f6ab "; font-size: 15px; } script. let game = !{ JSON.stringify(game) } let roles = !{ JSON.stringify(roles) } @@ -73,8 +72,6 @@ html p i= game.notice - br(clear="left") - dialog(id="invite") | Invite a friend: br @@ -92,8 +89,9 @@ html tbody each role in roles tr - th(id="role_"+role.replace(/ /g, "_")+"_name")= role + th.w(id="role_"+role.replace(/ /g, "_")+"_name")= role td(id="role_"+role.replace(/ /g, "_")) - + tfoot tr td#message(colspan=2) - diff --git a/views/message_inbox.pug b/views/message_inbox.pug index 0e39ea2..c6001f5 100644 --- a/views/message_inbox.pug +++ b/views/message_inbox.pug @@ -7,6 +7,10 @@ html style. .unread { font-weight: bold } td a { display: block } + @media (max-width: 400px) { + td:nth-child(3) { display: none } + th:nth-child(3) { display: none } + } body include header article @@ -15,7 +19,7 @@ html p a(href="/message/send") Send message - table + table.wide.striped thead tr th From @@ -23,12 +27,12 @@ html th Date tbody each row in messages - tr - td - a.black(href="/user/"+row.from_name)= row.from_name - td(class=row.is_read?"read":"unread") - a.black(href="/message/read/"+row.message_id)= row.subject - td= row.time + - let subject = row.subject + - if (subject.length > 50) subject = subject.substring(0,40) + "..." + tr(class=row.is_read?"read":"unread") + td: a.black(href="/user/"+row.from_name)= row.from_name + td: a.black(href="/message/read/"+row.message_id)= subject + td.w= row.time else tr td(colspan=3) No messages. diff --git a/views/message_outbox.pug b/views/message_outbox.pug index f305d83..f42ef7f 100644 --- a/views/message_outbox.pug +++ b/views/message_outbox.pug @@ -6,6 +6,10 @@ html title Outbox style. td a { display: block } + @media (max-width: 400px) { + td:nth-child(3) { display: none } + th:nth-child(3) { display: none } + } script. function delete_all() { let warning = "Are you sure you want to delete ALL the messages?" @@ -20,7 +24,7 @@ html p a(href="/message/send") Send message - table + table.wide.striped thead tr th From @@ -30,8 +34,8 @@ html each row in messages tr td: a.black(href="/user/"+row.to_name)= row.to_name - td: a.black(href="/message/read/"+row.message_id)= row.subject - td= row.time + td.e: a.black(href="/message/read/"+row.message_id)= row.subject + td.w= row.time else tr td(colspan=3) No messages. diff --git a/views/message_send.pug b/views/message_send.pug index 48e7b64..fbabd71 100644 --- a/views/message_send.pug +++ b/views/message_send.pug @@ -4,8 +4,6 @@ html head include head title Send Message - style. - input, textarea { width: min(45rem,100%) } script. function next(event,sel) { if (event.keyCode === 13) { diff --git a/views/stats.pug b/views/stats.pug index 6c8a268..ececb85 100644 --- a/views/stats.pug +++ b/views/stats.pug @@ -5,18 +5,17 @@ html include head title Game Statistics style. - table { min-width: auto; margin-bottom: 30px; } + table { margin-bottom: 30px; } td:not(:first-child) { text-align: right; } th:not(:first-child) { text-align: right; } td:not(:first-child) { width: 50px; } - td:first-child { width: 400px; } body include header article h1 Game Statistics - function p(t,r) { return r > 0 ? Math.round(r*100/t) + "%" : "" } each row in stats - table + table.half.striped thead tr th diff --git a/views/user.pug b/views/user.pug index abb7865..dbadd36 100644 --- a/views/user.pug +++ b/views/user.pug @@ -12,8 +12,9 @@ html white-space: pre-wrap; font-style: italic; padding: 8px 12px; - border-left: 4px solid silver; - background-color: whitesmoke; + border: var(--thin-border); + box-shadow: var(--drop-shadow); + background-color: var(--color-text); } body include header diff --git a/views/user_stats.pug b/views/user_stats.pug index dee2883..3b201ef 100644 --- a/views/user_stats.pug +++ b/views/user_stats.pug @@ -11,7 +11,7 @@ html article h1 Statistics for #{who.name} - table(style="min-width:auto") + table.striped thead tr th Title @@ -37,7 +37,7 @@ html td.r= all_total td.r= Math.round(all_won*100/all_total) + "%" - table(style="min-width:auto") + table.striped thead tr th Title -- cgit v1.2.3