diff options
Diffstat (limited to 'frontend/style.css')
-rw-r--r-- | frontend/style.css | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/frontend/style.css b/frontend/style.css new file mode 100644 index 0000000..15c3add --- /dev/null +++ b/frontend/style.css @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2024 Runxi Yu <https://runxiyu.org> + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +/* + * TODO: Remove all uses of !important. These are obviously bad practice, but + * it's not always trivial to get the precedence right. + */ + +:root { + --primary-bg: white; + --primary-fg: #212529; + --border: #ced4da; + --anchor-underline-color: lightgray; + --anchor-color: #0062cc; + --theme: #0062cc; + --theme-contrast: white; + --box: #f2f2f2; + --box-contrast: var(--primary-fg); + --danger: #d32535; + --danger-contrast: white; + --white: white; + --white-contrast: #222222; + --header-fg: black; + --header-bg: #f2f2f2; +} + +@media (prefers-color-scheme: dark) { + :root { + --primary-bg: #212529; + --primary-fg: #f8f9fa; + --border: #495057; + --anchor-underline-color: #4F4F4F; + --anchor-color: #3294fe; + --theme: #0062cc; + --theme-contrast: #f8f9fa; + --box: #30363B; + --box-contrast: #f8f9fa; + --danger: #d32535; + --danger-contrast: #f8f9fa; + --white: #202020; + --white-contrast: #f8f9fa; + --header-fg: #f8f9fa; + --header-bg: #30363b; + } +} + +html { + font-family: system-ui, sans-serif; + line-height: 1.2; + background-color: var(--primary-bg); + color: var(--primary-fg); +} + +body { + margin: 0; + padding: 0; +} + +main, +body > section, +.reading-width, +footer { + margin: 1rem auto; + padding-left: 1rem; + padding-right: 1rem; + max-width: 60rem; +} + +/* + * For accessibility reasons, we still want anchors to be underlined, but + * perhaps not as profound of an underline as the default. + */ +a { + color: var(--anchor-color); + text-decoration: underline; + text-decoration-color: var(--anchor-underline-color); +} + +/* + * However, although the site title will be an anchor, it should not be + * underlined. + */ +#site-title { + text-decoration: none; +} + +/* + * Navigation is a simple bulleted list with bullets in the middle only. + * This should probably be revamped. + */ +nav ul { + list-style-type: none; + margin: 0; + padding: 0; + display: flex; +} +nav ul > li { + display: inline-block; +} +nav ul > li:not(:last-child)::after { + content:"\2000" +} + +/* + * The header should stick to the top of the page. + */ +header { + position: -webkit-sticky; + position: sticky; + top: 0; + left: 0; + color: var(--header-fg); + background-color: var(--header-bg); + z-index: 1000; + width: 100%; +} + +/* + * We don't want underlined anchors in the header in general, since it should + * be obvious that things in it are links. + */ +header a { + text-decoration: none; + color: var(--header-fg); +} +.header-content { + padding-left: 1rem; + padding-right: 1rem; + max-width: 60rem; + display: flex; + justify-content: space-between; + align-items: center; + margin: 0 auto; +} +header img { + vertical-align: middle; + max-height: 40px; +} +header h1 { + font-size: 25px; /* TODO: Specifying font sizes in pixels is bad */ +} + +/* + * The table, the most important element in my site design... + */ +table { + margin-top: 0.4em; + margin-bottom: 0.4em; + border-collapse: collapse; + border: 1px solid var(--border); +} +table.wide { + width: 100%; +} +th[scope~="row"] { + text-align: left; +} +th[scope~="col"] { +} +td { + border: 1px solid; + text-align: left; + height: 1.25rem; + border: 1px solid var(--border); + padding: 3px 5px; +} +table.fat td { + padding: 6px 5px; +} +td.th-like, th { + background-color: var(--box) !important; + border: 1px solid var(--border); + font-weight: bold; + padding: 3px 5px; +} +th.min, td.min { + width: 0; + min-width: fit-content; + white-space: nowrap; +} + +/* + * Input elements, which are usually in tables anyway + */ +textarea { + box-sizing: border-box; + background-color: var(--box); + resize: vertical; +} +textarea, +input[type=text], +input[type=password] { + font-family: sans-serif; + font-size: smaller; + background-color: var(--box); + color: var(--box-contrast); + border: none; + padding: 0.3rem; + width: 100%; + box-sizing: border-box; +} +td.tdinput, th.tdinput { + padding: 0rem !important; +} +td.tdinput textarea, +td.tdinput input[type=text], +td.tdinput input[type=password], +th.tdinput textarea, +th.tdinput input[type=text], +th.tdinput input[type=password] { + background-color: transparent !important; +} + +/* + * Button definitions. + * + * Each button should contain the .btn class and a .btn-type class, where type + * is one of primary, danger, white, and normal. + */ +.btn-primary { + background: var(--theme); + color: var(--theme-contrast); + border: var(--border) 1px solid; + font-weight: bold; +} +.btn-danger { + background: var(--danger); + color: var(--danger-contrast); + border: var(--border) 1px solid; + font-weight: bold; +} +.btn-white { + background: var(--white); + color: var(--white-contrast); + border: var(--border) 1px solid; +} +.btn-normal, +input[type=file]::file-selector-button { + background: var(--box-contrast); + border: var(--border) 1px solid !important; + color: var(--box-contrast); +} +.btn, +input[type=submit], +input[type=file]::file-selector-button { + display: inline-block; + width: auto; + min-width: fit-content; + border-radius: 0; + padding: .1rem .75rem; + font-size: 0.9rem; + transition: background .1s linear; + cursor: pointer; +} +a.btn { + text-decoration: none; +} + + +/* + * Multiple columns, flexible wrapping + */ +.multicols { + display: flex; + flex-direction: row; + @media(max-width: 50rem) { + flex-wrap: wrap; + gap: 0rem; + } + gap: 2rem; + align-items: stretch; +} + +.multicols div { + min-width: 18em; + /* max-width: 40rem; */ + width: 100%; + margin-left: auto; + margin-right: auto; +} + +/* + * Spanning elements across a flex container with equal space in between + */ +.flex-justify { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0 auto; + border: none; +} + +.message-box { + margin: auto; + max-width: 30rem; + border: solid 1px var(--border); + background-color: var(--box); + padding: 0rem 1rem; +} + +table#table-of-courses { + width: 100%; +} + +/* + * .need-connection is the content that should actually display when we are + * connected via WebSocket. The JavaScript would change display from none to + * block when fully connected to WebSocket. + */ +.need-connection { + display: none; +} + +/* + * Same for script-required, though the JavaScript hides this as soon as it's + * loaded. + */ +.script-required { + display: none; +} + +/* + * .broken-connection displays a message telling users to refresh the page, + * after their WebSocket connection breaks. It should be hidden by default. + */ +.broken-connection { + display: none; +} + +/* + * This site heavily uses CSS styling to display and hide messages, so by + * default we put a big warning about CSS being broken, which disappears + * once the main CSS, i.e. this file, is completely loaded. Therefore it's + * probably best to put this at the bottom of this file. + */ +.broken-styling-warning { + display: none; +} |