diff --git a/.github/workflows/lint-frontend.yaml b/.github/workflows/lint-frontend.yaml index b816941eb..ed106d6a8 100644 --- a/.github/workflows/lint-frontend.yaml +++ b/.github/workflows/lint-frontend.yaml @@ -27,7 +27,7 @@ jobs: # See .stylelintignore for files that are not linted. - name: Run stylelint run: > - npx stylelint bookwyrm/static/css/*.scss \ + npx stylelint bookwyrm/static/css/*.scss bookwyrm/static/css/bookwyrm/**/*.scss \ --config dev-tools/.stylelintrc.js # See .eslintignore for files that are not linted. diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 5b5d77025..3747e30a1 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _ env = Env() env.read_env() DOMAIN = env("DOMAIN") -VERSION = "0.3.0" +VERSION = "0.3.1" RELEASE_API = env( "RELEASE_API", @@ -21,7 +21,7 @@ RELEASE_API = env( PAGE_LENGTH = env("PAGE_LENGTH", 15) DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English") -JS_CACHE = "7eb9174b" +JS_CACHE = "a60e5a55" # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") diff --git a/bookwyrm/static/css/bookwyrm.scss b/bookwyrm/static/css/bookwyrm.scss index 772636900..6b5e7e6b5 100644 --- a/bookwyrm/static/css/bookwyrm.scss +++ b/bookwyrm/static/css/bookwyrm.scss @@ -1,1488 +1,7 @@ @charset "utf-8"; @import "instance-settings"; +@import "themes/light.scss"; @import "vendor/bulma/bulma.sass"; @import "vendor/icons.css"; - -html { - scroll-behavior: smooth; -} - -body { - min-height: 100vh; - display: flex; - flex-direction: column; -} - -button { - border: none; - margin: 0; - padding: 0; - width: auto; - overflow: visible; - background: transparent; - - /* inherit font, color & alignment from ancestor */ - color: inherit; - font: inherit; - text-align: inherit; - - /* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */ - line-height: normal; - - /* Corrects font smoothing for webkit */ - -webkit-font-smoothing: inherit; - -moz-osx-font-smoothing: inherit; - - /* Corrects inability to style clickable `input` types in iOS */ - -webkit-appearance: none; - - /* Generalizes pointer cursor */ - cursor: pointer; -} - -button::-moz-focus-inner { - /* Remove excess padding and border in Firefox 4+ */ - border: 0; - padding: 0; -} - -/* Better accessibility for keyboard users */ -*:focus-visible { - outline-style: auto !important; -} - -.image { - overflow: hidden; -} - -.navbar .logo { - max-height: 50px; -} - -.card { - overflow: visible; -} - -.card.has-border { - border: 1px solid #eee; -} - -.scroll-x { - overflow: hidden; - overflow-x: auto; -} - -.modal-card { - pointer-events: none; -} - -.modal-card > * { - pointer-events: all; -} - -/* stylelint-disable no-descending-specificity */ -.modal-card:focus { - outline-style: auto; -} - -.modal-card:focus:not(:focus-visible) { - outline-style: initial; -} - -.modal-card:focus-visible { - outline-style: auto; -} -/* stylelint-enable no-descending-specificity */ - -.modal-card.is-fullwidth { - min-width: 75% !important; -} - -@media only screen and (min-width: 769px) { - .modal-card.is-thin { - width: 350px !important; - } -} - -.modal-card-body { - max-height: 70vh; -} - -.clip-text { - max-height: 35em; - overflow: hidden; -} - -/** Utilities not covered by Bulma - ******************************************************************************/ - -@media only screen and (max-width: 768px) { - .is-sr-only-mobile { - border: none !important; - clip: rect(0, 0, 0, 0) !important; - height: 0.01em !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - white-space: nowrap !important; - width: 0.01em !important; - } - - .m-0-mobile { - margin: 0 !important; - } - - .card-footer.is-stacked-mobile { - flex-direction: column; - } - - .card-footer.is-stacked-mobile .card-footer-item:not(:last-child) { - border-bottom: 1px solid #ededed; - border-right: 0; - } - - .is-flex-direction-row-mobile { - flex-direction: row !important; - } - - .is-flex-direction-column-mobile { - flex-direction: column !important; - } -} - -.tag.is-small { - height: auto; -} - -.button.is-transparent { - background-color: transparent; -} - -.card.is-stretchable { - display: flex; - flex-direction: column; - height: 100%; -} - -.card.is-stretchable .card-content { - flex-grow: 1; -} - -.preserve-whitespace p { - white-space: pre-wrap !important; -} - -.display-inline p { - display: inline !important; -} - -button .button-invisible-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - padding: 1rem; - box-sizing: border-box; - display: flex; - align-items: center; - flex-direction: column; - justify-content: center; - background: rgba(0, 0, 0, 0.66); - color: white; - opacity: 0; - transition: opacity 0.2s ease; -} - -button:hover .button-invisible-overlay, -button:active .button-invisible-overlay, -button:focus-visible .button-invisible-overlay { - opacity: 1; -} - -/** File input styles - ******************************************************************************/ - -input[type="file"]::file-selector-button { - -moz-appearance: none; - -webkit-appearance: none; - background-color: #fff; - border-radius: 4px; - border: 1px solid #dbdbdb; - box-shadow: none; - color: #363636; - cursor: pointer; - font-size: 1rem; - height: 2.5em; - justify-content: center; - line-height: 1.5; - padding-bottom: calc(0.5em - 1px); - padding-left: 1em; - padding-right: 1em; - padding-top: calc(0.5em - 1px); - text-align: center; - white-space: nowrap; -} - -input[type="file"]::file-selector-button:hover { - border-color: #b5b5b5; - color: #363636; -} - -/** General `details` element styles - ******************************************************************************/ - -details summary { - cursor: pointer; -} - -summary::-webkit-details-marker { - display: none; -} - -details summary::marker { - content: none; -} - -details.detail-pinned-button summary { - position: absolute; - right: 0; -} - -details.detail-pinned-button form { - float: left; - width: 100%; - margin-top: 1em; -} - -/** Dropdown w/ Details element - ******************************************************************************/ - -details.dropdown[open] summary.dropdown-trigger::before { - content: ""; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -details.dropdown .dropdown-menu { - display: block !important; -} - -details.dropdown .dropdown-menu button { - /* Fix weird Safari defaults */ - box-sizing: border-box; -} - -details.dropdown .dropdown-menu button:focus-visible, -details.dropdown .dropdown-menu a:focus-visible { - outline-style: auto; - outline-offset: -2px; -} - -@media only screen and (max-width: 768px) { - details.dropdown[open] summary.dropdown-trigger::before { - background-color: rgba(0, 0, 0, 0.5); - z-index: 30; - } - - details .dropdown-menu { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex !important; - align-items: center; - justify-content: center; - pointer-events: none; - z-index: 100; - } - - details .dropdown-menu > * { - pointer-events: all; - } -} - -/** Bookwyrm Tabs - ******************************************************************************/ - -.bw-tabs { - -webkit-overflow-scrolling: touch; - -webkit-touch-callout: none; - position: relative; - align-items: center; - display: flex; - font-size: 1rem; - justify-content: flex-start; - overflow-x: auto; - overflow-y: hidden; - user-select: none; - white-space: nowrap; -} - -.bw-tabs::before { - border-bottom-color: #dbdbdb; - border-bottom-style: solid; - border-bottom-width: 1px; - bottom: 0; - content: ""; - position: absolute; - width: 100%; -} - -.bw-tabs:not(:last-child) { - margin-bottom: 1.5rem; -} - -.bw-tabs a { - align-items: center; - border-bottom-color: #dbdbdb; - border-bottom-style: solid; - border-bottom-width: 1px; - color: #4a4a4a; - display: flex; - justify-content: center; - margin-bottom: -1px; - padding: 0.5em 1em; - position: relative; -} - -.bw-tabs a:hover { - border-bottom-color: transparent; - color: #363636; -} - -.bw-tabs a.is-active { - border-bottom-color: transparent; - color: #3273dc; -} - -.bw-tabs.is-left { - padding-right: 0.75em; -} - -.bw-tabs.is-center { - flex: none; - justify-content: center; - padding-left: 0.75em; - padding-right: 0.75em; -} - -.bw-tabs.is-right { - justify-content: flex-end; - padding-left: 0.75em; -} - -.bw-tabs .icon:first-child { - margin-right: 0.5em; -} - -.bw-tabs .icon:last-child { - margin-left: 0.5em; -} - -.bw-tabs.is-centered { - justify-content: center; -} - -.bw-tabs.is-boxed a { - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} - -.bw-tabs.is-boxed a:hover { - background-color: #f5f5f5; - border-bottom-color: #dbdbdb; -} - -.bw-tabs.is-boxed a.is-active { - background-color: #fff; - border-color: #dbdbdb; - border-bottom-color: #fff !important; -} - -.bw-tabs.is-fullwidth a { - flex-grow: 1; - flex-shrink: 0; -} - -.bw-tabs.is-toggle a { - border-color: #dbdbdb; - border-style: solid; - border-width: 1px; - margin-bottom: 0; - position: relative; -} - -.bw-tabs.is-toggle a:hover { - background-color: #f5f5f5; - border-color: #b5b5b5; - z-index: 2; -} - -.bw-tabs.is-toggle a + a { - margin-left: -1px; -} - -.bw-tabs.is-toggle a:first-child { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; -} - -.bw-tabs.is-toggle a:last-child { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.bw-tabs.is-toggle a.is-active { - background-color: #3273dc; - border-color: #3273dc; - color: #fff; - z-index: 1; -} - -.bw-tabs.is-toggle { - border-bottom: none; -} - -.bw-tabs.is-toggle.is-toggle-rounded a:first-child { - border-bottom-left-radius: 290486px; - border-top-left-radius: 290486px; - padding-left: 1.25em; -} - -.bw-tabs.is-toggle.is-toggle-rounded a:last-child { - border-bottom-right-radius: 290486px; - border-top-right-radius: 290486px; - padding-right: 1.25em; -} - -.bw-tabs.is-small { - font-size: 0.75rem; -} - -.bw-tabs.is-medium { - font-size: 1.25rem; -} - -.bw-tabs.is-large { - font-size: 1.5rem; -} - -.bw-tabs.has-aside-text a { - margin-top: 1.5rem; -} - -.bw-tabs a .aside-text { - position: absolute; - top: calc(-0.75rem - 0.75rem); - left: 0; - color: #4a4a4a; -} - -/** Details panel - ******************************************************************************/ - -details.details-panel { - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); - transition: box-shadow 0.2s ease; - padding: 0.75rem; -} - -details[open].details-panel, -details.details-panel:hover { - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); -} - -details.details-panel summary { - position: relative; -} - -details summary .details-close { - position: absolute; - right: 0; - top: 0; - transform: rotate(45deg); - transition: transform 0.2s ease; -} - -details[open] summary .details-close { - transform: rotate(0deg); -} - -@media only screen and (min-width: 769px) { - .details-panel .filters-field:not(:last-child) { - border-right: 1px solid rgba(0, 0, 0, 0.1); - margin-top: 0.75rem; - margin-bottom: 0.75rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } -} - -/** Shelving - ******************************************************************************/ - -/** @todo Replace icons with SVG symbols. - @see https://www.youtube.com/watch?v=9xXBYcWgCHA */ -.shelf-option:disabled > *::after { - font-family: icomoon; /* stylelint-disable font-family-no-missing-generic-family-keyword */ - content: "\e919"; /* icon-check */ - margin-left: 0.5em; -} - -/** Toggles - ******************************************************************************/ - -.toggle-button[aria-pressed="true"], -.toggle-button[aria-pressed="true"]:hover { - background-color: hsl(171deg, 100%, 41%); - color: white; -} - -.hide-active[aria-pressed="true"], -.hide-inactive[aria-pressed="false"] { - display: none; -} - -.transition-x.is-hidden, -.transition-y.is-hidden { - display: block !important; - visibility: hidden !important; - height: 0 !important; - width: 0 !important; - margin: 0 !important; - padding: 0 !important; - overflow: auto; -} - -.transition-x, -.transition-y { - transition-duration: 0.5s; - transition-timing-function: ease; -} - -.transition-x { - transition-property: width, margin-left, margin-right, padding-left, padding-right; -} - -.transition-y { - transition-property: height, margin-top, margin-bottom, padding-top, padding-bottom; -} - -@media (prefers-reduced-motion: reduce) { - .transition-x, - .transition-y { - transition-duration: 0.001ms !important; - } -} - -/** Stars - ******************************************************************************/ - -.stars { - white-space: nowrap; -} - -/** Stars in a review form - * - * Specificity makes hovering taking over checked inputs. - * - * \e9d9: filled star - * \e9d7: empty star; - * -------------------------------------------------------------------------- */ - -.form-rate-stars { - width: max-content; -} - -/* All stars are visually filled by default. */ -.form-rate-stars .icon::before { - content: "\e9d9"; /* icon-star-full */ -} - -/* Icons directly following half star inputs are marked as half */ -.form-rate-stars input.half:checked ~ .icon::before { - content: "\e9d8"; /* icon-star-half */ -} - -/* stylelint-disable no-descending-specificity */ -.form-rate-stars input.half:checked + input + .icon:hover::before { - content: "\e9d8" !important; /* icon-star-half */ -} - -/* Icons directly following half check inputs that follow the checked input are emptied. */ -.form-rate-stars input.half:checked + input + .icon ~ .icon::before { - content: "\e9d7"; /* icon-star-empty */ -} - -/* Icons directly following inputs that follow the checked input are emptied. */ -.form-rate-stars input:checked ~ input + .icon::before { - content: "\e9d7"; /* icon-star-empty */ -} - -/* When a label is hovered, repeat the fill-all-then-empty-following pattern. */ -.form-rate-stars:hover .icon.icon::before { - content: "\e9d9" !important; /* icon-star-full */ -} - -.form-rate-stars .icon:hover ~ .icon::before { - content: "\e9d7" !important; /* icon-star-empty */ -} - -/** Book covers - * - * - .is-cover gives the behaviour of the cover and its surrounding. (optional) - * - .cover-container gives the dimensions and position (for borders, image and other elements). - * - .book-cover is positioned and sized based on its container. - * - * To have the cover within specific dimensions, specify a width or height for - * standard bulma’s named breapoints: - * - * `is-(w|h)-(auto|xs|s|m|l|xl|xxl)[-(mobile|tablet|desktop)]` - * - * The cover will be centered horizontally and vertically within those dimensions. - * - * When using `.column.is-N`, add `.is-w-auto` to the container so that the flex - * calculations are not biased by the default `max-content`. - ******************************************************************************/ - -.column.is-cover { - flex-grow: 0 !important; -} - -.column.is-cover, -.column.is-cover + .column { - flex-basis: auto !important; -} - -.cover-container { - display: flex; - justify-content: center; - align-items: center; - position: relative; - width: max-content; - max-width: 100%; - overflow: hidden; -} - -/* Book cover - * -------------------------------------------------------------------------- */ - -.book-cover { - display: block; - max-width: 100%; - max-height: 100%; - - /* Useful when stretching under-sized images. */ - image-rendering: optimizequality; - image-rendering: smooth; -} - -/* Cover caption - * -------------------------------------------------------------------------- */ - -.no-cover .cover-caption { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 0.5em; - font-size: 0.75em; - color: white; - background-color: #002549; - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - gap: 1em; - white-space: initial; - text-align: center; -} - -/** Avatars - ******************************************************************************/ - -.avatar { - vertical-align: middle; - display: inline; -} - -/** Statuses: Quotes - * - * \e906: icon-quote-open - * \e905: icon-quote-close - * - * The `content` class on the blockquote allows to apply styles to markdown - * generated HTML in the quote: https://bulma.io/documentation/elements/content/ - * - * ```html - *
- *
- * User generated quote in markdown… - *
- * - *

Book Title by Author

- *
- * ``` - ******************************************************************************/ - -.quote > blockquote { - position: relative; - padding-left: 2em; -} - -.quote > blockquote::before, -.quote > blockquote::after { - font-family: icomoon; - position: absolute; -} - -.quote > blockquote::before { - content: "\e907"; /* icon-quote-open */ - top: 0; - left: 0; -} - -.quote > blockquote::after { - content: "\e906"; /* icon-quote-close */ - right: 0; -} - -/** Animations and transitions - ******************************************************************************/ - -@keyframes turning { - from { transform: rotateZ(0deg); } - to { transform: rotateZ(360deg); } -} - -.is-processing .icon-spinner::before { - animation: turning 1.5s infinite linear; -} - -.icon-spinner { - display: none; -} - -.is-processing .icon-spinner { - display: flex; -} - -@media (prefers-reduced-motion: reduce) { - .is-processing .icon::before { - transition-duration: 0.001ms !important; - } -} - -/** Transient notification - ******************************************************************************/ - -#live-messages { - position: fixed; - bottom: 1em; - right: 1em; -} - -/** Tooltips - ******************************************************************************/ - -.tooltip { - width: 100%; -} - -/** States - ******************************************************************************/ - -/* "disabled" for non-buttons */ - -.is-disabled { - background-color: #dbdbdb; - border-color: #dbdbdb; - box-shadow: none; - color: #7a7a7a; - opacity: 0.5; - cursor: not-allowed; -} - -/* Book preview table - ******************************************************************************/ - -.book-preview td { - vertical-align: middle; -} - -@media only screen and (max-width: 768px) { - table.is-mobile, - table.is-mobile tbody { - display: block; - } - - table.is-mobile tr { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - border-top: 1px solid #dbdbdb; - } - - table.is-mobile td { - display: block; - box-sizing: border-box; - flex: 1 0 100%; - order: 2; - border-bottom: 0; - } - - table.is-mobile td.book-preview-top-row { - order: 1; - flex-basis: auto; - } - - table.is-mobile td[data-title]:not(:empty)::before { - content: attr(data-title); - display: block; - font-size: 0.75em; - font-weight: bold; - } - - table.is-mobile td:empty { - padding: 0; - } - - table.is-mobile th, - table.is-mobile thead { - display: none; - } -} - -/* Book list - ******************************************************************************/ - -ol.ordered-list { - list-style: none; - counter-reset: list-counter; -} - -ol.ordered-list li { - counter-increment: list-counter; -} - -ol.ordered-list li::before { - content: counter(list-counter); - position: absolute; - left: -20px; - width: 20px; - height: 24px; - background-color: #fff; - border: 1px solid #dbdbdb; - border-right: 0; - border-top-left-radius: 2px; - border-top-right-radius: 2px; - display: flex; - justify-content: center; - align-items: center; - color: #888; - font-size: 0.8em; - font-weight: bold; -} - -@media only screen and (max-width: 768px) { - ol.ordered-list li::before { - left: 0; - z-index: 1; - border: 0; - border-right: 1px solid #dbdbdb; - border-bottom: 1px solid #dbdbdb; - border-radius: 0; - border-bottom-right-radius: 2px; - } -} - -.overflow-wrap-anywhere { - overflow-wrap: anywhere; - min-width: 10em; -} - -/* Threads - ******************************************************************************/ - -.thread .is-main .card { - box-shadow: 0 0.5em 1em -0.125em rgba(50, 115, 220, 0.35), 0 0 0 1px rgba(50, 115, 220, 0.02); -} - -.thread::after { - content: ""; - position: absolute; - z-index: -1; - top: 0; - bottom: 0; - left: 2.5em; - border-left: 2px solid #e0e0e0; -} - -/* Breadcrumbs - ******************************************************************************/ - -.breadcrumb li:first-child * { - padding-left: 0; -} - -.breadcrumb li > * { - align-items: center; - display: flex; - justify-content: center; - padding: 0 0.75em; -} - -/* Notifications page - ******************************************************************************/ - -.notification a.icon { - text-decoration: none !important; -} - -/* Breadcrumbs - ******************************************************************************/ - -.books-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 1rem; - align-items: end; - justify-items: stretch; -} - -.books-grid > .is-big { - grid-column: span 2; - grid-row: span 2; - justify-self: stretch; -} - -.books-grid .book-cover { - width: 100%; -} - -.books-grid .book-title { - --height-basis: 1.35rem; - - display: block; - margin-top: 0.5rem; - line-height: var(--height-basis); - min-height: calc(2 * var(--height-basis)); -} - -@media only screen and (min-width: 769px) { - .books-grid { - gap: 1.5rem; - grid-template-columns: repeat(auto-fill, minmax(8em, 1fr)); - } -} - -/* Copy - ******************************************************************************/ - -.horizontal-copy { - display: flex; - flex-direction: row; - align-items: center; - gap: 0.75rem; -} - -.horizontal-copy textarea { - min-width: initial; - white-space: nowrap; -} - -.horizontal-copy button { - align-self: stretch; - height: unset; -} - -.vertical-copy { - display: flex; - flex-direction: column; - align-items: stretch; - gap: 0.75rem; -} - -.vertical-copy button { - width: 100%; -} - -/* Dimensions - * @todo These could be in rem. - ******************************************************************************/ - -.is-32x32 { - min-width: 32px !important; - min-height: 32px !important; -} - -.is-96x96 { - min-width: 96px !important; - min-height: 96px !important; -} - -.is-w-auto { - width: auto !important; -} - -.is-w-xs { - width: 80px !important; -} - -.is-w-s { - width: 100px !important; -} - -.is-w-m { - width: 150px !important; -} - -.is-w-l { - width: 200px !important; -} - -.is-w-xl { - width: 250px !important; -} - -.is-w-xxl { - width: 500px !important; -} - -.is-h-xs { - height: 80px !important; -} - -.is-h-s { - height: 100px !important; -} - -.is-h-m { - height: 150px !important; -} - -.is-h-l { - height: 200px !important; -} - -.is-h-xl { - height: 250px !important; -} - -.is-h-xxl { - height: 500px !important; -} - -@media only screen and (max-width: 768px) { - .is-w-auto-mobile { - width: auto !important; - } - - .is-w-xs-mobile { - width: 80px !important; - } - - .is-w-s-mobile { - width: 100px !important; - } - - .is-w-m-mobile { - width: 150px !important; - } - - .is-w-l-mobile { - width: 200px !important; - } - - .is-w-xl-mobile { - width: 250px !important; - } - - .is-w-xxl-mobile { - width: 500px !important; - } - - .is-h-xs-mobile { - height: 80px !important; - } - - .is-h-s-mobile { - height: 100px !important; - } - - .is-h-m-mobile { - height: 150px !important; - } - - .is-h-l-mobile { - height: 200px !important; - } - - .is-h-xl-mobile { - height: 250px !important; - } - - .is-h-xxl-mobile { - height: 500px !important; - } -} - -@media only screen and (min-width: 769px) { - .is-w-auto-tablet { - width: auto !important; - } - - .is-w-xs-tablet { - width: 80px !important; - } - - .is-w-s-tablet { - width: 100px !important; - } - - .is-w-m-tablet { - width: 150px !important; - } - - .is-w-l-tablet { - width: 200px !important; - } - - .is-w-xl-tablet { - width: 250px !important; - } - - .is-w-xxl-tablet { - width: 500px !important; - } - - .is-h-xs-tablet { - height: 80px !important; - } - - .is-h-s-tablet { - height: 100px !important; - } - - .is-h-m-tablet { - height: 150px !important; - } - - .is-h-l-tablet { - height: 200px !important; - } - - .is-h-xl-tablet { - height: 250px !important; - } - - .is-h-xxl-tablet { - height: 500px !important; - } -} - -@media only screen and (min-width: 1024px) { - .is-w-auto-desktop { - width: auto !important; - } - - .is-w-xs-desktop { - width: 80px !important; - } - - .is-w-s-desktop { - width: 100px !important; - } - - .is-w-m-desktop { - width: 150px !important; - } - - .is-w-l-desktop { - width: 200px !important; - } - - .is-w-xl-desktop { - width: 250px !important; - } - - .is-w-xxl-desktop { - width: 500px !important; - } - - .is-h-xs-desktop { - height: 80px !important; - } - - .is-h-s-desktop { - height: 100px !important; - } - - .is-h-m-desktop { - height: 150px !important; - } - - .is-h-l-desktop { - height: 200px !important; - } - - .is-h-xl-desktop { - height: 250px !important; - } - - .is-h-xxl-desktop { - height: 500px !important; - } -} - -/* Alignments - * - * Use them with `.align.to-(c|t|r|b|l)[-(mobile|tablet)]` - ******************************************************************************/ - -/* Flex item position - * -------------------------------------------------------------------------- */ - -.align { - display: flex !important; - flex-direction: row !important; -} - -.align.to-c { - justify-content: center !important; -} - -.align.to-t { - align-items: flex-start !important; -} - -.align.to-r { - justify-content: flex-end !important; -} - -.align.to-b { - align-items: flex-end !important; -} - -.align.to-l { - justify-content: flex-start !important; -} - -@media screen and (max-width: 768px) { - .align.to-c-mobile { - justify-content: center !important; - } - - .align.to-t-mobile { - align-items: flex-start !important; - } - - .align.to-r-mobile { - justify-content: flex-end !important; - } - - .align.to-b-mobile { - align-items: flex-end !important; - } - - .align.to-l-mobile { - justify-content: flex-start !important; - } -} - -@media screen and (min-width: 769px) { - .align.to-c-tablet { - justify-content: center !important; - } - - .align.to-t-tablet { - align-items: flex-start !important; - } - - .align.to-r-tablet { - justify-content: flex-end !important; - } - - .align.to-b-tablet { - align-items: flex-end !important; - } - - .align.to-l-tablet { - justify-content: flex-start !important; - } -} - -/* Spacings - * - * Those are supplementary rules to Bulma’s. They follow the same conventions. - * Add those you’ll need. - ******************************************************************************/ - -.mr-auto { - margin-right: auto !important; -} - -.ml-auto { - margin-left: auto !important; -} - -@media screen and (max-width: 768px) { - .m-0-mobile { - margin: 0 !important; - } - - .mr-auto-mobile { - margin-right: auto !important; - } - - .ml-auto-mobile { - margin-left: auto !important; - } - - .mt-3-mobile { - margin-top: 0.75rem !important; - } - - .ml-3-mobile { - margin-left: 0.75rem !important; - } - - .mx-3-mobile { - margin-right: 0.75rem !important; - margin-left: 0.75rem !important; - } - - .my-3-mobile { - margin-top: 0.75rem !important; - margin-bottom: 0.75rem !important; - } -} - -@media screen and (min-width: 769px) { - .m-0-tablet { - margin: 0 !important; - } - - .mr-auto-tablet { - margin-right: auto !important; - } - - .ml-auto-tablet { - margin-left: auto !important; - } - - .mt-3-tablet { - margin-top: 0.75rem !important; - } - - .ml-3-tablet { - margin-left: 0.75rem !important; - } - - .mx-3-tablet { - margin-right: 0.75rem !important; - margin-left: 0.75rem !important; - } - - .my-3-tablet { - margin-top: 0.75rem !important; - margin-bottom: 0.75rem !important; - } -} - -/* Gaps (for Flexbox and Grid) - * - * Those are supplementary rules to Bulma’s. They follow the same conventions. - * Add those you’ll need. - ******************************************************************************/ - -.is-gap-0 { - gap: 0; -} - -.is-gap-1 { - gap: 0.25rem; -} - -.is-gap-2 { - gap: 0.5rem; -} - -.is-gap-3 { - gap: 0.75rem; -} - -.is-gap-4 { - gap: 1rem; -} - -.is-gap-5 { - gap: 1.5rem; -} - -.is-gap-6 { - gap: 3rem; -} - -.is-row-gap-0 { - row-gap: 0; -} - -.is-row-gap-1 { - row-gap: 0.25rem; -} - -.is-row-gap-2 { - row-gap: 0.5rem; -} - -.is-row-gap-3 { - row-gap: 0.75rem; -} - -.is-row-gap-4 { - row-gap: 1rem; -} - -.is-row-gap-5 { - row-gap: 1.5rem; -} - -.is-row-gap-6 { - row-gap: 3rem; -} - -.is-column-gap-0 { - column-gap: 0; -} - -.is-column-gap-1 { - column-gap: 0.25rem; -} - -.is-column-gap-2 { - column-gap: 0.5rem; -} - -.is-column-gap-3 { - column-gap: 0.75rem; -} - -.is-column-gap-4 { - column-gap: 1rem; -} - -.is-column-gap-5 { - column-gap: 1.5rem; -} - -.is-column-gap-6 { - column-gap: 3rem; -} +@import "bookwyrm/all.scss"; diff --git a/bookwyrm/static/css/bookwyrm/_all.scss b/bookwyrm/static/css/bookwyrm/_all.scss new file mode 100644 index 000000000..11d7e403d --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/_all.scss @@ -0,0 +1,159 @@ +/** Imports + ******************************************************************************/ +@import "components/avatar"; +@import "components/book_cover"; +@import "components/book_grid"; +@import "components/book_list"; +@import "components/book_preview_table"; +@import "components/breadcrumbs"; +@import "components/copy"; +@import "components/details"; +@import "components/file_input"; +@import "components/live_message"; +@import "components/shelving"; +@import "components/stars"; +@import "components/status"; +@import "components/tabs"; +@import "components/toggle"; + +@import "overrides/bulma_overrides"; + +@import "utilities/a11y"; +@import "utilities/alignments"; +@import "utilities/colors"; +@import "utilities/size"; +@import "utilities/spacings"; +@import "utilities/transitions"; + +html { + scroll-behavior: smooth; +} + +body { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +button { + border: none; + margin: 0; + padding: 0; + width: auto; + overflow: visible; + background: transparent; + + /* inherit font, color & alignment from ancestor */ + color: inherit; + font: inherit; + text-align: inherit; + + /* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */ + line-height: normal; + + /* Corrects font smoothing for webkit */ + -webkit-font-smoothing: inherit; + -moz-osx-font-smoothing: inherit; + + /* Corrects inability to style clickable `input` types in iOS */ + -webkit-appearance: none; + + /* Generalizes pointer cursor */ + cursor: pointer; +} + +button::-moz-focus-inner { + /* Remove excess padding and border in Firefox 4+ */ + border: 0; + padding: 0; +} + +/* Better accessibility for keyboard users */ +*:focus-visible { + outline-style: auto !important; +} + +/** Utilities not covered by Bulma + ******************************************************************************/ + + +.tag.is-small { + height: auto; +} + +.button.is-transparent { + background-color: transparent; +} + +.card.is-stretchable { + display: flex; + flex-direction: column; + height: 100%; +} + +.card.is-stretchable .card-content { + flex-grow: 1; +} + +.preserve-whitespace p { + white-space: pre-wrap !important; +} + +.display-inline p { + display: inline !important; +} + +button .button-invisible-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 1rem; + box-sizing: border-box; + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + background: rgba($scheme-invert, 0.66); + color: white; + opacity: 0; + transition: opacity 0.2s ease; +} + +button:hover .button-invisible-overlay, +button:active .button-invisible-overlay, +button:focus-visible .button-invisible-overlay { + opacity: 1; +} + + + +/** Tooltips + ******************************************************************************/ + +.tooltip { + width: 100%; +} + +/** States + ******************************************************************************/ + +/* "disabled" for non-buttons */ + +.is-disabled { + background-color: $pagination-disabled-background-color; + border-color: $pagination-disabled-border-color; + box-shadow: none; + color: $pagination-disabled-color; + opacity: 0.5; + cursor: not-allowed; +} + + +/* Notifications page + ******************************************************************************/ + +.notification a.icon { + text-decoration: none !important; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_avatar.css b/bookwyrm/static/css/bookwyrm/components/_avatar.css new file mode 100644 index 000000000..433b8946e --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_avatar.css @@ -0,0 +1,7 @@ +/** Avatars + ******************************************************************************/ + +.avatar { + vertical-align: middle; + display: inline; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_book_cover.scss b/bookwyrm/static/css/bookwyrm/components/_book_cover.scss new file mode 100644 index 000000000..d1125197e --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_book_cover.scss @@ -0,0 +1,70 @@ +/** Book covers + * + * - .is-cover gives the behaviour of the cover and its surrounding. (optional) + * - .cover-container gives the dimensions and position (for borders, image and other elements). + * - .book-cover is positioned and sized based on its container. + * + * To have the cover within specific dimensions, specify a width or height for + * standard bulma’s named breapoints: + * + * `is-(w|h)-(auto|xs|s|m|l|xl|xxl)[-(mobile|tablet|desktop)]` + * + * The cover will be centered horizontally and vertically within those dimensions. + * + * When using `.column.is-N`, add `.is-w-auto` to the container so that the flex + * calculations are not biased by the default `max-content`. + ******************************************************************************/ + +.column.is-cover { + flex-grow: 0 !important; +} + +.column.is-cover, +.column.is-cover + .column { + flex-basis: auto !important; +} + +.cover-container { + display: flex; + justify-content: center; + align-items: center; + position: relative; + width: max-content; + max-width: 100%; + overflow: hidden; +} + +/* Book cover + * -------------------------------------------------------------------------- */ + +.book-cover { + display: block; + max-width: 100%; + max-height: 100%; + + /* Useful when stretching under-sized images. */ + image-rendering: optimizequality; + image-rendering: smooth; +} + +/* Cover caption + * -------------------------------------------------------------------------- */ + +.no-cover .cover-caption { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 0.5em; + font-size: 0.75em; + color: white; + background-color: $no-cover-color; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 1em; + white-space: initial; + text-align: center; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_book_grid.scss b/bookwyrm/static/css/bookwyrm/components/_book_grid.scss new file mode 100644 index 000000000..5993bb43c --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_book_grid.scss @@ -0,0 +1,36 @@ +/* Books grid + ******************************************************************************/ + +.books-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1rem; + align-items: end; + justify-items: stretch; +} + +.books-grid > .is-big { + grid-column: span 2; + grid-row: span 2; + justify-self: stretch; +} + +.books-grid .book-cover { + width: 100%; +} + +.books-grid .book-title { + --height-basis: 1.35rem; + + display: block; + margin-top: 0.5rem; + line-height: var(--height-basis); + min-height: calc(2 * var(--height-basis)); +} + +@media only screen and (min-width: 769px) { + .books-grid { + gap: 1.5rem; + grid-template-columns: repeat(auto-fill, minmax(8em, 1fr)); + } +} diff --git a/bookwyrm/static/css/bookwyrm/components/_book_list.scss b/bookwyrm/static/css/bookwyrm/components/_book_list.scss new file mode 100644 index 000000000..0b1093489 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_book_list.scss @@ -0,0 +1,47 @@ +/* Book list + ******************************************************************************/ + +ol.ordered-list { + list-style: none; + counter-reset: list-counter; +} + +ol.ordered-list li { + counter-increment: list-counter; +} + +ol.ordered-list li::before { + content: counter(list-counter); + position: absolute; + left: -20px; + width: 20px; + height: 24px; + background-color: $scheme-main; + border: 1px solid $border; + border-right: 0; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + display: flex; + justify-content: center; + align-items: center; + color: $text-light; + font-size: 0.8em; + font-weight: bold; +} + +@media only screen and (max-width: 768px) { + ol.ordered-list li::before { + left: 0; + z-index: 1; + border: 0; + border-right: 1px solid $border; + border-bottom: 1px solid $border; + border-radius: 0; + border-bottom-right-radius: 2px; + } +} + +.overflow-wrap-anywhere { + overflow-wrap: anywhere; + min-width: 10em; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_book_preview_table.scss b/bookwyrm/static/css/bookwyrm/components/_book_preview_table.scss new file mode 100644 index 000000000..fdbb29f0e --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_book_preview_table.scss @@ -0,0 +1,49 @@ +/* Book preview table + ******************************************************************************/ + +.book-preview td { + vertical-align: middle; +} + +@media only screen and (max-width: 768px) { + table.is-mobile, + table.is-mobile tbody { + display: block; + } + + table.is-mobile tr { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + border-top: 1px solid $border; + } + + table.is-mobile td { + display: block; + box-sizing: border-box; + flex: 1 0 100%; + order: 2; + border-bottom: 0; + } + + table.is-mobile td.book-preview-top-row { + order: 1; + flex-basis: auto; + } + + table.is-mobile td[data-title]:not(:empty)::before { + content: attr(data-title); + display: block; + font-size: 0.75em; + font-weight: bold; + } + + table.is-mobile td:empty { + padding: 0; + } + + table.is-mobile th, + table.is-mobile thead { + display: none; + } +} diff --git a/bookwyrm/static/css/bookwyrm/components/_breadcrumbs.scss b/bookwyrm/static/css/bookwyrm/components/_breadcrumbs.scss new file mode 100644 index 000000000..9d445629d --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_breadcrumbs.scss @@ -0,0 +1,13 @@ +/* Breadcrumbs + ******************************************************************************/ + +.breadcrumb li:first-child * { + padding-left: 0; +} + +.breadcrumb li > * { + align-items: center; + display: flex; + justify-content: center; + padding: 0 0.75em; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_copy.scss b/bookwyrm/static/css/bookwyrm/components/_copy.scss new file mode 100644 index 000000000..e0c4246e6 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_copy.scss @@ -0,0 +1,30 @@ +/* Copy + ******************************************************************************/ + +.horizontal-copy { + display: flex; + flex-direction: row; + align-items: center; + gap: 0.75rem; +} + +.horizontal-copy textarea { + min-width: initial; + white-space: nowrap; +} + +.horizontal-copy button { + align-self: stretch; + height: unset; +} + +.vertical-copy { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 0.75rem; +} + +.vertical-copy button { + width: 100%; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_details.scss b/bookwyrm/static/css/bookwyrm/components/_details.scss new file mode 100644 index 000000000..645de4a1d --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_details.scss @@ -0,0 +1,116 @@ +/** General `details` element styles + ******************************************************************************/ + +details summary { + cursor: pointer; +} + +summary::-webkit-details-marker { + display: none; +} + +details summary::marker { + content: none; +} + +details.detail-pinned-button summary { + position: absolute; + right: 0; +} + +details.detail-pinned-button form { + float: left; + width: 100%; + margin-top: 1em; +} + +/** Dropdown w/ Details element + ******************************************************************************/ + +details.dropdown[open] summary.dropdown-trigger::before { + content: ""; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +details.dropdown .dropdown-menu { + display: block !important; +} + +details.dropdown .dropdown-menu button { + /* Fix weird Safari defaults */ + box-sizing: border-box; +} + +details.dropdown .dropdown-menu button:focus-visible, +details.dropdown .dropdown-menu a:focus-visible { + outline-style: auto; + outline-offset: -2px; +} + +@media only screen and (max-width: 768px) { + details.dropdown[open] summary.dropdown-trigger::before { + background-color: rgba($scheme-invert, 0.5); + z-index: 30; + } + + details .dropdown-menu { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex !important; + align-items: center; + justify-content: center; + pointer-events: none; + z-index: 100; + } + + details .dropdown-menu > * { + pointer-events: all; + } +} + +/** Details panel + ******************************************************************************/ + +details.details-panel { + box-shadow: 0 0 0 1px $border; + transition: box-shadow 0.2s ease; + padding: 0.75rem; +} + +details[open].details-panel, +details.details-panel:hover { + box-shadow: 0 0 0 1px $border; +} + +details.details-panel summary { + position: relative; +} + +details summary .details-close { + position: absolute; + right: 0; + top: 0; + transform: rotate(45deg); + transition: transform 0.2s ease; +} + +details[open] summary .details-close { + transform: rotate(0deg); +} + +@media only screen and (min-width: 769px) { + .details-panel .filters-field:not(:last-child) { + border-right: 1px solid $border; + margin-top: 0.75rem; + margin-bottom: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } +} diff --git a/bookwyrm/static/css/bookwyrm/components/_file_input.scss b/bookwyrm/static/css/bookwyrm/components/_file_input.scss new file mode 100644 index 000000000..3ccc70f5b --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_file_input.scss @@ -0,0 +1,28 @@ +/** File input styles + ******************************************************************************/ + +input[type="file"]::file-selector-button { + -moz-appearance: none; + -webkit-appearance: none; + background-color: $scheme-main; + border-radius: 4px; + border: 1px solid $border; + box-shadow: none; + color: $text; + cursor: pointer; + font-size: 1rem; + height: 2.5em; + justify-content: center; + line-height: 1.5; + padding-bottom: calc(0.5em - 1px); + padding-left: 1em; + padding-right: 1em; + padding-top: calc(0.5em - 1px); + text-align: center; + white-space: nowrap; +} + +input[type="file"]::file-selector-button:hover { + border-color: $border-hover; + color: text; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_live_message.scss b/bookwyrm/static/css/bookwyrm/components/_live_message.scss new file mode 100644 index 000000000..5d8680cc6 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_live_message.scss @@ -0,0 +1,8 @@ +/** Transient notification + ******************************************************************************/ + +#live-messages { + position: fixed; + bottom: 1em; + right: 1em; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_shelving.scss b/bookwyrm/static/css/bookwyrm/components/_shelving.scss new file mode 100644 index 000000000..15b01e552 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_shelving.scss @@ -0,0 +1,10 @@ +/** Shelving + ******************************************************************************/ + +/** @todo Replace icons with SVG symbols. + @see https://www.youtube.com/watch?v=9xXBYcWgCHA */ +.shelf-option:disabled > *::after { + font-family: icomoon; /* stylelint-disable font-family-no-missing-generic-family-keyword */ + content: "\e919"; /* icon-check */ + margin-left: 0.5em; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_stars.scss b/bookwyrm/static/css/bookwyrm/components/_stars.scss new file mode 100644 index 000000000..1a8e3680f --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_stars.scss @@ -0,0 +1,52 @@ +/** Stars + ******************************************************************************/ + +.stars { + white-space: nowrap; +} + +/** Stars in a review form + * + * Specificity makes hovering taking over checked inputs. + * + * \e9d9: filled star + * \e9d7: empty star; + * -------------------------------------------------------------------------- */ + +.form-rate-stars { + width: max-content; +} + +/* All stars are visually filled by default. */ +.form-rate-stars .icon::before { + content: "\e9d9"; /* icon-star-full */ +} + +/* Icons directly following half star inputs are marked as half */ +.form-rate-stars input.half:checked ~ .icon::before { + content: "\e9d8"; /* icon-star-half */ +} + +/* stylelint-disable no-descending-specificity */ +.form-rate-stars input.half:checked + input + .icon:hover::before { + content: "\e9d8" !important; /* icon-star-half */ +} + +/* Icons directly following half check inputs that follow the checked input are emptied. */ +.form-rate-stars input.half:checked + input + .icon ~ .icon::before { + content: "\e9d7"; /* icon-star-empty */ +} + +/* Icons directly following inputs that follow the checked input are emptied. */ +.form-rate-stars input:checked ~ input + .icon::before { + content: "\e9d7"; /* icon-star-empty */ +} + +/* When a label is hovered, repeat the fill-all-then-empty-following pattern. */ +.form-rate-stars:hover .icon.icon::before { + content: "\e9d9" !important; /* icon-star-full */ +} + +.form-rate-stars .icon:hover ~ .icon::before { + content: "\e9d7" !important; /* icon-star-empty */ +} diff --git a/bookwyrm/static/css/bookwyrm/components/_status.scss b/bookwyrm/static/css/bookwyrm/components/_status.scss new file mode 100644 index 000000000..3ec679cd9 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_status.scss @@ -0,0 +1,57 @@ +/** Statuses: Quotes + * + * \e906: icon-quote-open + * \e905: icon-quote-close + * + * The `content` class on the blockquote allows to apply styles to markdown + * generated HTML in the quote: https://bulma.io/documentation/elements/content/ + * + * ```html + *
+ *
+ * User generated quote in markdown… + *
+ * + *

Book Title by Author

+ *
+ * ``` + ******************************************************************************/ + +.quote > blockquote { + position: relative; + padding-left: 2em; +} + +.quote > blockquote::before, +.quote > blockquote::after { + font-family: icomoon; /* stylelint-disable font-family-no-missing-generic-family-keyword */ + position: absolute; +} + +.quote > blockquote::before { + content: "\e907"; /* icon-quote-open */ + top: 0; + left: 0; +} + +.quote > blockquote::after { + content: "\e906"; /* icon-quote-close */ + right: 0; +} + +/* Threads + ******************************************************************************/ + +.thread .is-main .card { + box-shadow: 0 0.5em 1em -0.125em rgba($link, 0.35), 0 0 0 1px rgba($link, 0.02); +} + +.thread::after { + content: ""; + position: absolute; + z-index: -1; + top: 0; + bottom: 0; + left: 2.5em; + border-left: 2px solid $border; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_tabs.scss b/bookwyrm/static/css/bookwyrm/components/_tabs.scss new file mode 100644 index 000000000..8e00f6a88 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_tabs.scss @@ -0,0 +1,176 @@ +/** Bookwyrm Tabs + ******************************************************************************/ + +.bw-tabs { + -webkit-overflow-scrolling: touch; + -webkit-touch-callout: none; + position: relative; + align-items: center; + display: flex; + font-size: 1rem; + justify-content: flex-start; + overflow-x: auto; + overflow-y: hidden; + user-select: none; + white-space: nowrap; +} + +.bw-tabs::before { + border-bottom-color: $border; + border-bottom-style: solid; + border-bottom-width: 1px; + bottom: 0; + content: ""; + position: absolute; + width: 100%; +} + +.bw-tabs:not(:last-child) { + margin-bottom: 1.5rem; +} + +.bw-tabs a { + align-items: center; + border-bottom-color: $border; + border-bottom-style: solid; + border-bottom-width: 1px; + color: $text; + display: flex; + justify-content: center; + margin-bottom: -1px; + padding: 0.5em 1em; + position: relative; +} + +.bw-tabs a:hover { + border-bottom-color: transparent; + color: $text; +} + +.bw-tabs a.is-active { + border-bottom-color: transparent; + color: $link; +} + +.bw-tabs.is-left { + padding-right: 0.75em; +} + +.bw-tabs.is-center { + flex: none; + justify-content: center; + padding-left: 0.75em; + padding-right: 0.75em; +} + +.bw-tabs.is-right { + justify-content: flex-end; + padding-left: 0.75em; +} + +.bw-tabs .icon:first-child { + margin-right: 0.5em; +} + +.bw-tabs .icon:last-child { + margin-left: 0.5em; +} + +.bw-tabs.is-centered { + justify-content: center; +} + +.bw-tabs.is-boxed a { + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.bw-tabs.is-boxed a:hover { + background-color: $background-secondary; + border-bottom-color: $border-hover; +} + +.bw-tabs.is-boxed a.is-active { + background-color: $background-body; + border-color: $border; + border-bottom-color: $border !important; +} + +.bw-tabs.is-fullwidth a { + flex-grow: 1; + flex-shrink: 0; +} + +.bw-tabs.is-toggle a { + border-color: $border; + border-style: solid; + border-width: 1px; + margin-bottom: 0; + position: relative; +} + +.bw-tabs.is-toggle a:hover { + background-color: $background-secondary; + border-color: $border; + z-index: 2; +} + +.bw-tabs.is-toggle a + a { + margin-left: -1px; +} + +.bw-tabs.is-toggle a:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.bw-tabs.is-toggle a:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.bw-tabs.is-toggle a.is-active { + background-color: $link-background; + border-color: $link; + color: $text; + z-index: 1; +} + +.bw-tabs.is-toggle { + border-bottom: none; +} + +.bw-tabs.is-toggle.is-toggle-rounded a:first-child { + border-bottom-left-radius: 290486px; + border-top-left-radius: 290486px; + padding-left: 1.25em; +} + +.bw-tabs.is-toggle.is-toggle-rounded a:last-child { + border-bottom-right-radius: 290486px; + border-top-right-radius: 290486px; + padding-right: 1.25em; +} + +.bw-tabs.is-small { + font-size: 0.75rem; +} + +.bw-tabs.is-medium { + font-size: 1.25rem; +} + +.bw-tabs.is-large { + font-size: 1.5rem; +} + +.bw-tabs.has-aside-text a { + margin-top: 1.5rem; +} + +.bw-tabs a .aside-text { + position: absolute; + top: calc(-0.75rem - 0.75rem); + left: 0; + color: $text; +} diff --git a/bookwyrm/static/css/bookwyrm/components/_toggle.scss b/bookwyrm/static/css/bookwyrm/components/_toggle.scss new file mode 100644 index 000000000..c2c07dfb8 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/components/_toggle.scss @@ -0,0 +1,45 @@ +/** Toggles + ******************************************************************************/ + +.toggle-button[aria-pressed="true"], +.toggle-button[aria-pressed="true"]:hover { + background-color: hsl(171deg, 100%, 41%); + color: white; +} + +.hide-active[aria-pressed="true"], +.hide-inactive[aria-pressed="false"] { + display: none; +} + +.transition-x.is-hidden, +.transition-y.is-hidden { + display: block !important; + visibility: hidden !important; + height: 0 !important; + width: 0 !important; + margin: 0 !important; + padding: 0 !important; + overflow: auto; +} + +.transition-x, +.transition-y { + transition-duration: 0.5s; + transition-timing-function: ease; +} + +.transition-x { + transition-property: width, margin-left, margin-right, padding-left, padding-right; +} + +.transition-y { + transition-property: height, margin-top, margin-bottom, padding-top, padding-bottom; +} + +@media (prefers-reduced-motion: reduce) { + .transition-x, + .transition-y { + transition-duration: 0.001ms !important; + } +} diff --git a/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss b/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss new file mode 100644 index 000000000..f46e7b957 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss @@ -0,0 +1,61 @@ +.image { + overflow: hidden; +} + +.navbar .logo { + max-height: 50px; +} + +.card { + overflow: visible; +} + +.card.has-border { + border: 1px solid $border; +} + +.scroll-x { + overflow: hidden; + overflow-x: auto; +} + +.modal-card { + pointer-events: none; +} + +.modal-card > * { + pointer-events: all; +} + +/* stylelint-disable no-descending-specificity */ +.modal-card:focus { + outline-style: auto; +} + +.modal-card:focus:not(:focus-visible) { + outline-style: initial; +} + +.modal-card:focus-visible { + outline-style: auto; +} +/* stylelint-enable no-descending-specificity */ + +.modal-card.is-fullwidth { + min-width: 75% !important; +} + +@media only screen and (min-width: 769px) { + .modal-card.is-thin { + width: 350px !important; + } +} + +.modal-card-body { + max-height: 70vh; +} + +.clip-text { + max-height: 35em; + overflow: hidden; +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_a11y.scss b/bookwyrm/static/css/bookwyrm/utilities/_a11y.scss new file mode 100644 index 000000000..cf4ef6ab0 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_a11y.scss @@ -0,0 +1,33 @@ +@media only screen and (max-width: 768px) { + .is-sr-only-mobile { + border: none !important; + clip: rect(0, 0, 0, 0) !important; + height: 0.01em !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + white-space: nowrap !important; + width: 0.01em !important; + } + + .m-0-mobile { + margin: 0 !important; + } + + .card-footer.is-stacked-mobile { + flex-direction: column; + } + + .card-footer.is-stacked-mobile .card-footer-item:not(:last-child) { + border-bottom: 1px solid $background-tertiary; + border-right: 0; + } + + .is-flex-direction-row-mobile { + flex-direction: row !important; + } + + .is-flex-direction-column-mobile { + flex-direction: column !important; + } +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_alignments.scss b/bookwyrm/static/css/bookwyrm/utilities/_alignments.scss new file mode 100644 index 000000000..34e36b3bb --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_alignments.scss @@ -0,0 +1,76 @@ +/* Alignments + * + * Use them with `.align.to-(c|t|r|b|l)[-(mobile|tablet)]` + ******************************************************************************/ + +/* Flex item position + * -------------------------------------------------------------------------- */ + +.align { + display: flex !important; + flex-direction: row !important; +} + +.align.to-c { + justify-content: center !important; +} + +.align.to-t { + align-items: flex-start !important; +} + +.align.to-r { + justify-content: flex-end !important; +} + +.align.to-b { + align-items: flex-end !important; +} + +.align.to-l { + justify-content: flex-start !important; +} + +@media screen and (max-width: 768px) { + .align.to-c-mobile { + justify-content: center !important; + } + + .align.to-t-mobile { + align-items: flex-start !important; + } + + .align.to-r-mobile { + justify-content: flex-end !important; + } + + .align.to-b-mobile { + align-items: flex-end !important; + } + + .align.to-l-mobile { + justify-content: flex-start !important; + } +} + +@media screen and (min-width: 769px) { + .align.to-c-tablet { + justify-content: center !important; + } + + .align.to-t-tablet { + align-items: flex-start !important; + } + + .align.to-r-tablet { + justify-content: flex-end !important; + } + + .align.to-b-tablet { + align-items: flex-end !important; + } + + .align.to-l-tablet { + justify-content: flex-start !important; + } +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_colors.scss b/bookwyrm/static/css/bookwyrm/utilities/_colors.scss new file mode 100644 index 000000000..e44efee95 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_colors.scss @@ -0,0 +1,25 @@ +/* Semantic color classes */ + +.has-background-primary-highlight { + background-color: $primary-highlight; +} + +.has-background-info-highlight { + background-color: $info-highlight; +} + +.has-background-success-highlight { + background-color: $success-highlight; +} + +.has-background-body { + background-color: $background-body; +} + +.has-background-secondary { + background-color: $background-secondary !important; +} + +.has-background-tertiary { + background-color: $background-tertiary !important; +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_size.scss b/bookwyrm/static/css/bookwyrm/utilities/_size.scss new file mode 100644 index 000000000..cbc74d7ab --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_size.scss @@ -0,0 +1,227 @@ +/* Dimensions + * @todo These could be in rem. + ******************************************************************************/ + +.is-32x32 { + min-width: 32px !important; + min-height: 32px !important; +} + +.is-96x96 { + min-width: 96px !important; + min-height: 96px !important; +} + +.is-w-auto { + width: auto !important; +} + +.is-w-xs { + width: 80px !important; +} + +.is-w-s { + width: 100px !important; +} + +.is-w-m { + width: 150px !important; +} + +.is-w-l { + width: 200px !important; +} + +.is-w-xl { + width: 250px !important; +} + +.is-w-xxl { + width: 500px !important; +} + +.is-h-xs { + height: 80px !important; +} + +.is-h-s { + height: 100px !important; +} + +.is-h-m { + height: 150px !important; +} + +.is-h-l { + height: 200px !important; +} + +.is-h-xl { + height: 250px !important; +} + +.is-h-xxl { + height: 500px !important; +} + +@media only screen and (max-width: 768px) { + .is-w-auto-mobile { + width: auto !important; + } + + .is-w-xs-mobile { + width: 80px !important; + } + + .is-w-s-mobile { + width: 100px !important; + } + + .is-w-m-mobile { + width: 150px !important; + } + + .is-w-l-mobile { + width: 200px !important; + } + + .is-w-xl-mobile { + width: 250px !important; + } + + .is-w-xxl-mobile { + width: 500px !important; + } + + .is-h-xs-mobile { + height: 80px !important; + } + + .is-h-s-mobile { + height: 100px !important; + } + + .is-h-m-mobile { + height: 150px !important; + } + + .is-h-l-mobile { + height: 200px !important; + } + + .is-h-xl-mobile { + height: 250px !important; + } + + .is-h-xxl-mobile { + height: 500px !important; + } +} + +@media only screen and (min-width: 769px) { + .is-w-auto-tablet { + width: auto !important; + } + + .is-w-xs-tablet { + width: 80px !important; + } + + .is-w-s-tablet { + width: 100px !important; + } + + .is-w-m-tablet { + width: 150px !important; + } + + .is-w-l-tablet { + width: 200px !important; + } + + .is-w-xl-tablet { + width: 250px !important; + } + + .is-w-xxl-tablet { + width: 500px !important; + } + + .is-h-xs-tablet { + height: 80px !important; + } + + .is-h-s-tablet { + height: 100px !important; + } + + .is-h-m-tablet { + height: 150px !important; + } + + .is-h-l-tablet { + height: 200px !important; + } + + .is-h-xl-tablet { + height: 250px !important; + } + + .is-h-xxl-tablet { + height: 500px !important; + } +} + +@media only screen and (min-width: 1024px) { + .is-w-auto-desktop { + width: auto !important; + } + + .is-w-xs-desktop { + width: 80px !important; + } + + .is-w-s-desktop { + width: 100px !important; + } + + .is-w-m-desktop { + width: 150px !important; + } + + .is-w-l-desktop { + width: 200px !important; + } + + .is-w-xl-desktop { + width: 250px !important; + } + + .is-w-xxl-desktop { + width: 500px !important; + } + + .is-h-xs-desktop { + height: 80px !important; + } + + .is-h-s-desktop { + height: 100px !important; + } + + .is-h-m-desktop { + height: 150px !important; + } + + .is-h-l-desktop { + height: 200px !important; + } + + .is-h-xl-desktop { + height: 250px !important; + } + + .is-h-xxl-desktop { + height: 500px !important; + } +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_spacings.scss b/bookwyrm/static/css/bookwyrm/utilities/_spacings.scss new file mode 100644 index 000000000..f1a1645bc --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_spacings.scss @@ -0,0 +1,167 @@ +/* Spacings + * + * Those are supplementary rules to Bulma’s. They follow the same conventions. + * Add those you’ll need. + ******************************************************************************/ + +.mr-auto { + margin-right: auto !important; +} + +.ml-auto { + margin-left: auto !important; +} + +@media screen and (max-width: 768px) { + .m-0-mobile { + margin: 0 !important; + } + + .mr-auto-mobile { + margin-right: auto !important; + } + + .ml-auto-mobile { + margin-left: auto !important; + } + + .mt-3-mobile { + margin-top: 0.75rem !important; + } + + .ml-3-mobile { + margin-left: 0.75rem !important; + } + + .mx-3-mobile { + margin-right: 0.75rem !important; + margin-left: 0.75rem !important; + } + + .my-3-mobile { + margin-top: 0.75rem !important; + margin-bottom: 0.75rem !important; + } +} + +@media screen and (min-width: 769px) { + .m-0-tablet { + margin: 0 !important; + } + + .mr-auto-tablet { + margin-right: auto !important; + } + + .ml-auto-tablet { + margin-left: auto !important; + } + + .mt-3-tablet { + margin-top: 0.75rem !important; + } + + .ml-3-tablet { + margin-left: 0.75rem !important; + } + + .mx-3-tablet { + margin-right: 0.75rem !important; + margin-left: 0.75rem !important; + } + + .my-3-tablet { + margin-top: 0.75rem !important; + margin-bottom: 0.75rem !important; + } +} + +/* Gaps (for Flexbox and Grid) + * + * Those are supplementary rules to Bulma’s. They follow the same conventions. + * Add those you’ll need. + ******************************************************************************/ + +.is-gap-0 { + gap: 0; +} + +.is-gap-1 { + gap: 0.25rem; +} + +.is-gap-2 { + gap: 0.5rem; +} + +.is-gap-3 { + gap: 0.75rem; +} + +.is-gap-4 { + gap: 1rem; +} + +.is-gap-5 { + gap: 1.5rem; +} + +.is-gap-6 { + gap: 3rem; +} + +.is-row-gap-0 { + row-gap: 0; +} + +.is-row-gap-1 { + row-gap: 0.25rem; +} + +.is-row-gap-2 { + row-gap: 0.5rem; +} + +.is-row-gap-3 { + row-gap: 0.75rem; +} + +.is-row-gap-4 { + row-gap: 1rem; +} + +.is-row-gap-5 { + row-gap: 1.5rem; +} + +.is-row-gap-6 { + row-gap: 3rem; +} + +.is-column-gap-0 { + column-gap: 0; +} + +.is-column-gap-1 { + column-gap: 0.25rem; +} + +.is-column-gap-2 { + column-gap: 0.5rem; +} + +.is-column-gap-3 { + column-gap: 0.75rem; +} + +.is-column-gap-4 { + column-gap: 1rem; +} + +.is-column-gap-5 { + column-gap: 1.5rem; +} + +.is-column-gap-6 { + column-gap: 3rem; +} diff --git a/bookwyrm/static/css/bookwyrm/utilities/_transitions.scss b/bookwyrm/static/css/bookwyrm/utilities/_transitions.scss new file mode 100644 index 000000000..18f4bc7f4 --- /dev/null +++ b/bookwyrm/static/css/bookwyrm/utilities/_transitions.scss @@ -0,0 +1,25 @@ +/** Animations and transitions + ******************************************************************************/ + +@keyframes turning { + from { transform: rotateZ(0deg); } + to { transform: rotateZ(360deg); } +} + +.is-processing .icon-spinner::before { + animation: turning 1.5s infinite linear; +} + +.icon-spinner { + display: none; +} + +.is-processing .icon-spinner { + display: flex; +} + +@media (prefers-reduced-motion: reduce) { + .is-processing .icon::before { + transition-duration: 0.001ms !important; + } +} diff --git a/bookwyrm/static/css/themes/dark.scss b/bookwyrm/static/css/themes/dark.scss new file mode 100644 index 000000000..8df4ce500 --- /dev/null +++ b/bookwyrm/static/css/themes/dark.scss @@ -0,0 +1,55 @@ +@import "../vendor/bulma/sass/utilities/derived-variables.sass"; + +/* Colors + ******************************************************************************/ + +/* states */ +$primary: #016a5b; +$info: #1f4666; +$success: #246447; +$warning: #8b6c15; +$danger: #872538; + +/* book cover standins */ +$no-cover-color: #002549; + +/* background colors */ +$scheme-main: $grey-darker; +$scheme-main-bis: $black-ter; +$background-body: $grey-darker; +$background-secondary: $grey-dark; +$background-tertiary: #555; + +/* highlight colors */ +$primary-highlight: $primary; +$info-highlight: $info; +$success-highlight: $success; + +/* borders */ +$border: $grey; +$border-hover: $grey-light; +$border-light: $grey; +$border-light-hover: $grey-light; + +/* text */ +$text: $grey-lightest; +$text-light: $grey-lighter; +$text-strong: $white-ter; + +/* links */ +$link: $white; +$link-background: $background-tertiary; +$link-hover: $white-bis; +$link-focus: $white-bis; +$link-active: $white-bis; + +/* misc */ + +/* bulma overrides */ +$background: $background-secondary; +$menu-item-active-background-color: $link-background; + +/* Fonts + ******************************************************************************/ +$family-primary: $family-sans-serif; +$family-secondary: $family-sans-serif; diff --git a/bookwyrm/static/css/themes/light.scss b/bookwyrm/static/css/themes/light.scss new file mode 100644 index 000000000..339fc2c36 --- /dev/null +++ b/bookwyrm/static/css/themes/light.scss @@ -0,0 +1,53 @@ +@import "../vendor/bulma/sass/utilities/derived-variables.sass"; + +/* Colors + ******************************************************************************/ + +/* states */ +$primary: $turquoise; +$info: $cyan; +$success: $green; +$warning: $yellow; +$danger: $red; + +/* book cover standins */ +$no-cover-color: #002549; + +/* background colors */ +$scheme-main: $white; +$scheme-main: $white-bis; +$background-body: $white; +$background-secondary: $white-ter; +$background-tertiary: $white-bis; + +/* highlight colors */ +$primary-highlight: $primary-light; +$info-highlight: $info-light; +$success-highlight: $success-light; + +/* borders */ +$border: $grey-lighter; +$border-hover: $grey-light; +$border-light: $grey-lightest; +$border-light-hover: $grey-light; + +/* text */ +$text: $grey-dark; +$text-light: $grey; +$text-strong: $grey-darker; + +/* links */ +$link: #3273dc; +$link-background: $link; +$link-hover: $grey-darker; +$link-focus: $grey-darker; +$link-active: $grey-darker; + +/* bulma overrides */ +$background: $background-secondary; +$menu-item-active-background-color: $link-background; + +/* Fonts + ******************************************************************************/ +$family-primary: $family-sans-serif; +$family-secondary: $family-sans-serif; diff --git a/bookwyrm/templates/about/about.html b/bookwyrm/templates/about/about.html index 6f16aa675..553bfee11 100644 --- a/bookwyrm/templates/about/about.html +++ b/bookwyrm/templates/about/about.html @@ -19,7 +19,7 @@ {% blocktrans with site_name=site.name %}Welcome to {{ site_name }}!{% endblocktrans %} -

+

{% blocktrans trimmed with site_name=site.name %} {{ site_name }} is part of BookWyrm, a network of independent, self-directed communities for readers. While you can interact seamlessly with users anywhere in the BookWyrm network, this community is unique. @@ -107,7 +107,7 @@

{% with role=user.groups.first.name %} -
+
{% if role == "moderator" %} {% trans "Moderator" %} @@ -123,7 +123,7 @@
{% if request.user.is_authenticated and user.id != request.user.id %} -