This commit is contained in:
84
app/assets/stylesheets/_reset.css
Normal file
84
app/assets/stylesheets/_reset.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Modern CSS Reset
|
||||
* @link https://github.com/hankchizljaw/modern-css-reset
|
||||
*/
|
||||
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Remove default margin */
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p,
|
||||
li,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
/* Help prevent overflow of long words/names/URLs */
|
||||
word-break: break-word;
|
||||
|
||||
/* Optional, not supported for all languages */
|
||||
/* hyphens: auto; */
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Set core body defaults */
|
||||
body {
|
||||
min-height: 100dvh;
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 1.5;
|
||||
text-rendering: optimizeSpeed;
|
||||
}
|
||||
|
||||
/* Make images easier to work with */
|
||||
img {
|
||||
display: block;
|
||||
max-inline-size: 100%;
|
||||
}
|
||||
|
||||
/* Inherit fonts for inputs and buttons */
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/* Remove all animations and transitions for people that prefer not to see them */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: initial;
|
||||
}
|
||||
}
|
||||
69
app/assets/stylesheets/animation.css
Normal file
69
app/assets/stylesheets/animation.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Animation classes */
|
||||
.shake {
|
||||
animation: shake 400ms both;
|
||||
}
|
||||
|
||||
.wiggle {
|
||||
animation: wiggle 400ms both;
|
||||
}
|
||||
|
||||
/* Keyframes */
|
||||
@keyframes fade-out {
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% { transform: translateX(-2rem); }
|
||||
25% { transform: translateX(2rem); }
|
||||
50% { transform: translateX(-1rem); }
|
||||
75% { transform: translateX(1rem); }
|
||||
}
|
||||
|
||||
@keyframes submitting {
|
||||
0% { -webkit-mask-position: 0% 0%, 50% 0%, 100% 0% }
|
||||
12.5% { -webkit-mask-position: 0% 50%, 50% 0%, 100% 0% }
|
||||
25% { -webkit-mask-position: 0% 100%, 50% 50%, 100% 0% }
|
||||
37.5% { -webkit-mask-position: 0% 100%, 50% 100%, 100% 50% }
|
||||
50% { -webkit-mask-position: 0% 100%, 50% 100%, 100% 100% }
|
||||
62.5% { -webkit-mask-position: 0% 50%, 50% 100%, 100% 100% }
|
||||
75% { -webkit-mask-position: 0% 0%, 50% 50%, 100% 100% }
|
||||
87.5% { -webkit-mask-position: 0% 0%, 50% 0%, 100% 50% }
|
||||
100% { -webkit-mask-position: 0% 0%, 50% 0%, 100% 0% }
|
||||
}
|
||||
|
||||
@keyframes success {
|
||||
0% { background-color: var(--color-border-darker); scale: 0.8; }
|
||||
20% { background-color: var(--color-border-darker); scale: 1; }
|
||||
}
|
||||
|
||||
@keyframes wiggle {
|
||||
0% { transform: rotate(0deg); }
|
||||
20% { transform: rotate(3deg); }
|
||||
40% { transform: rotate(-3deg); }
|
||||
60% { transform: rotate(3deg); }
|
||||
80% { transform: rotate(-3deg); }
|
||||
100% { transform: rotate(0deg); }
|
||||
}
|
||||
|
||||
@keyframes zoom-fade {
|
||||
100% { transform: translateY(-2em); opacity: 0; }
|
||||
}
|
||||
|
||||
/* View Transitions */
|
||||
::view-transition-old(root) {
|
||||
animation:
|
||||
100ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
|
||||
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
animation:
|
||||
200ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
|
||||
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
|
||||
}
|
||||
85
app/assets/stylesheets/arrangement.css
Normal file
85
app/assets/stylesheets/arrangement.css
Normal file
@@ -0,0 +1,85 @@
|
||||
.arrangement {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
:has(#arrange-mode:checked) .disable-when-arranging {
|
||||
cursor: not-allowed;
|
||||
filter: grayscale(100%) contrast(0.5);
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.arrangement__container {
|
||||
&:where(:has(#arrange-mode:checked)) {
|
||||
.hide-when-arranging {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.arrangement__item {
|
||||
cursor: move;
|
||||
|
||||
* {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.btn:not(.arrangement__handle) {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(:has(#toc-list:checked)) {
|
||||
.btn:is(.arrangement__handle) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(:has(#toc-grid:checked)) {
|
||||
.toc__thumbnail {
|
||||
border-color: var(--color-link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.arrangement--adding {
|
||||
.arrangement__item {
|
||||
* {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.arrangement-cursor {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.arrangement-drag-image {
|
||||
background-color: var(--color-link);
|
||||
border-radius: 1rem;
|
||||
color: var(--color-ink-reversed);
|
||||
inset: auto 100% 100% auto;
|
||||
line-height: 2rem;
|
||||
padding: 0 1rem;
|
||||
position: fixed;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.btn:is(.arrangement__handle) {
|
||||
display: none;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.arrangement-placeholder {
|
||||
background-color: var(--color-subtle-light);
|
||||
border: 1px dashed var(--color-subtle-dark);
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
|
||||
.arrangement-selected {
|
||||
background-color: var(--color-selected);
|
||||
border-radius: 0.2em;
|
||||
|
||||
.arrangement-move-mode & {
|
||||
animation: pulse 1000ms infinite;
|
||||
}
|
||||
}
|
||||
102
app/assets/stylesheets/base.css
Normal file
102
app/assets/stylesheets/base.css
Normal file
@@ -0,0 +1,102 @@
|
||||
html, body {
|
||||
--font-sans: system-ui;
|
||||
--font-serif: ui-serif, serif;
|
||||
--font-mono: ui-monospace, monospace;
|
||||
--hover-color: var(--color-subtle-dark);
|
||||
--hover-size: 0.15rem;
|
||||
--hover-filter: brightness(1);
|
||||
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: none;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-ink);
|
||||
font-family: var(--font-sans);
|
||||
line-height: 1.4;
|
||||
overflow: unset;
|
||||
scroll-behavior: auto;
|
||||
text-rendering: optimizeLegibility;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
a:not([class]) {
|
||||
--hover-size: 0;
|
||||
|
||||
color: var(--color-link);
|
||||
text-decoration: underline;
|
||||
text-decoration-skip-ink: auto;
|
||||
}
|
||||
|
||||
:is(a, button, input, textarea, .switch, .toc, .toc__title) {
|
||||
--outline-size: max(2px, 0.08em);
|
||||
|
||||
caret-color: var(--color-link);
|
||||
text-decoration: none;
|
||||
touch-action: manipulation;
|
||||
transition: box-shadow 150ms ease, outline-offset 150ms ease, background-color 150ms ease, opacity 150ms ease, filter 150ms ease;
|
||||
|
||||
/* Hover */
|
||||
@media (any-hover: hover) {
|
||||
&:where(:not(:active):hover) {
|
||||
box-shadow: 0 0 0 var(--hover-size) var(--hover-color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keyboard navigation */
|
||||
&:where(:not(:active)):focus-visible {
|
||||
outline-width: var(--outline-size);
|
||||
outline-color: var(--outline-color, currentColor);
|
||||
outline-offset: var(--outline-offset, calc(var(--outline-size) * 2));
|
||||
}
|
||||
|
||||
&:where(:focus-visible):active {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* Pressing */
|
||||
&:focus:not(:focus-visible) {
|
||||
--outline-offset: 0;
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
&:where([disabled]):not(:hover):not(:active) {
|
||||
cursor: not-allowed;
|
||||
filter: brightness(0.75);
|
||||
}
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: var(--color-selected);
|
||||
}
|
||||
|
||||
:where(ul, ol):where([role="list"]) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
@page {
|
||||
margin: 1in;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.no-print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Turbo */
|
||||
turbo-frame {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/* Nicer scrollbars on Chrome 29+. This is intended for Windows machines, but */
|
||||
/* there's not a way to target Windows using CSS, so Chrome on Mac will have */
|
||||
/* slightly thinner scrollbars than normal. #C1C1C1 is the default color on Macs. */
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) and (min-resolution:.001dpcm) {
|
||||
* {
|
||||
scrollbar-color: #C1C1C1 transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
}
|
||||
235
app/assets/stylesheets/books.css
Normal file
235
app/assets/stylesheets/books.css
Normal file
@@ -0,0 +1,235 @@
|
||||
:root {
|
||||
--theme-color--blue: oklch(69.14% 0.174 245.01);
|
||||
--theme-color--orange: oklch(70.22% 0.2 45.1);
|
||||
--theme-color--magenta: oklch(61.8% 0.19 354.64);
|
||||
--theme-color--green: oklch(71.53% 0.175 155.352);
|
||||
--theme-color--violet: oklch(56.13% 0.244 297.99);
|
||||
--theme-color--white: oklch(100% 0 0);
|
||||
--theme-color--black: oklch(0 0 0);
|
||||
}
|
||||
|
||||
.books {
|
||||
inline-size: 100%;
|
||||
}
|
||||
|
||||
.book {
|
||||
--cover-height: auto;
|
||||
--space: clamp(2ch, 10%, 6ch);
|
||||
|
||||
container-type: unset;
|
||||
column-gap: calc(var(--space) / 2);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(25%, 20dvw) 1fr;
|
||||
inline-size: 100%;
|
||||
padding-inline: var(--space);
|
||||
|
||||
@media (max-width: 70ch) {
|
||||
grid-template-columns: 1fr;
|
||||
padding-inline: var(--inline-space);
|
||||
}
|
||||
}
|
||||
|
||||
.book-access {
|
||||
&:has(.book-access__switch:checked) {
|
||||
.book-access__reader {
|
||||
background-color: var(--color-link);
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.book__cover {
|
||||
background-color: var(--color-bg);
|
||||
border-radius: 0.3em;
|
||||
box-shadow: 0 0 0 1px var(--color-subtle-dark);
|
||||
margin: auto;
|
||||
transition: background 300ms ease;
|
||||
|
||||
@media (min-width: 70ch) {
|
||||
max-block-size: var(--cover-height, 75vh);
|
||||
}
|
||||
|
||||
.theme--black &,
|
||||
:has(#book_theme_black:checked) & {
|
||||
background: url(covers/cover-black.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--blue &,
|
||||
:has(#book_theme_blue:checked) & {
|
||||
background: url(covers/cover-blue.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--green &,
|
||||
:has(#book_theme_green:checked) & {
|
||||
background: url(covers/cover-green.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--orange &,
|
||||
:has(#book_theme_orange:checked) & {
|
||||
background: url(covers/cover-orange.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--magenta &,
|
||||
:has(#book_theme_magenta:checked) & {
|
||||
background: url(covers/cover-magenta.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--violet &,
|
||||
:has(#book_theme_violet:checked) &{
|
||||
background: url(covers/cover-violet.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.theme--white &,
|
||||
:has(#book_theme_white:checked) & {
|
||||
background: url(covers/cover-white.png) no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--circle:has(#book_theme_white:checked) {
|
||||
img.checked {
|
||||
filter: invert(0);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
img.checked {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.book__cover--add {
|
||||
inset: auto 50% calc(var(--block-space) * -1) auto;
|
||||
margin-inline-end: calc(var(--btn-size) * -0.5);
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.book__cover-wrapper {
|
||||
color: var(--color-always-white);
|
||||
display: inline-grid;
|
||||
margin: auto;
|
||||
place-items: start;
|
||||
|
||||
> * {
|
||||
grid-area: 1 / 1;
|
||||
}
|
||||
|
||||
@media (max-width: 70ch) {
|
||||
.book & {
|
||||
font-size: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 150ch) {
|
||||
.book & {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.theme--white & .book__title {
|
||||
color: var(--color-always-black);
|
||||
}
|
||||
}
|
||||
|
||||
.book__cover--remove {
|
||||
margin-block-start: calc(var(--block-space) * -1);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.book__form {
|
||||
@media (max-width: 70ch) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.book__nav {
|
||||
font-size: var(--font-medium-responsive);
|
||||
margin: var(--block-space-double) auto var(--block-space);
|
||||
|
||||
.btn {
|
||||
max-inline-size: 50ch;
|
||||
}
|
||||
}
|
||||
|
||||
.book__navbar {
|
||||
.btn--placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:has(.btn.fullscreen):has(.btn.settings) {
|
||||
.placeholder-start {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:has(.btn.fullscreen)):not(:has(.btn.settings)) {
|
||||
.placeholder-end {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.book__sidebar {
|
||||
inset-block-start: var(--block-space);
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.book__title {
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.book__toolbar {
|
||||
inset-block-start: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Bookmarks */
|
||||
.bookmark {
|
||||
--icon-size: 1.5em;
|
||||
|
||||
display: block;
|
||||
inset: var(--progress, 0) calc(var(--icon-size) / 4) auto calc(var(--icon-size) * -0.5);
|
||||
margin-block-start: calc(var(--icon-size) * -0.5);
|
||||
position: absolute;
|
||||
|
||||
.bookmark__icon {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
|
||||
svg {
|
||||
block-size: var(--icon-size);
|
||||
flex-shrink: 0;
|
||||
inline-size: var(--icon-size);
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-block-end: 0.07em dashed var(--color-marker);
|
||||
content: "";
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bookmark__link {
|
||||
border-radius: 0.3em;
|
||||
color: var(--color-link);
|
||||
content: "";
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
20
app/assets/stylesheets/breadcrumbs.css
Normal file
20
app/assets/stylesheets/breadcrumbs.css
Normal file
@@ -0,0 +1,20 @@
|
||||
.breadcrumbs {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: var(--inline-space-half);
|
||||
margin-inline: auto;
|
||||
min-width: 0;
|
||||
|
||||
> * {
|
||||
flex-shrink: 1;
|
||||
max-inline-size: 40ch;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
input {
|
||||
field-sizing: content;
|
||||
min-inline-size: 8ch;
|
||||
}
|
||||
}
|
||||
182
app/assets/stylesheets/buttons.css
Normal file
182
app/assets/stylesheets/buttons.css
Normal file
@@ -0,0 +1,182 @@
|
||||
:root {
|
||||
--btn-size: 2.65em;
|
||||
}
|
||||
|
||||
.btn {
|
||||
--transition: 300ms ease;
|
||||
|
||||
align-items: center;
|
||||
background-color: var(--btn-background, transparent);
|
||||
border-radius: var(--btn-border-radius, 2em);
|
||||
border: var(--btn-border-size, 1px) solid var(--btn-border-color, var(--color-subtle-dark));
|
||||
color: var(--btn-color, var(--color-ink));
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
gap: var(--btn-gap, 0.5em);
|
||||
justify-content: center;
|
||||
padding: var(--btn-padding, 0.5em 1.1em);
|
||||
pointer-events: auto;
|
||||
transition:
|
||||
background-color var( --transition),
|
||||
border var( --transition),
|
||||
color var( --transition),
|
||||
filter var( --transition),
|
||||
opacity var( --transition);
|
||||
|
||||
img {
|
||||
-webkit-touch-callout: none;
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Default icon styles */
|
||||
&:where(:has(img, svg)) {
|
||||
text-align: start;
|
||||
|
||||
img, svg {
|
||||
block-size: var(--btn-icon-size, 1.3em);
|
||||
inline-size: var(--btn-icon-size, 1.3em);
|
||||
max-inline-size: unset;
|
||||
}
|
||||
|
||||
img:not([class]) {
|
||||
filter: invert(0);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Circle buttons */
|
||||
&.btn--circle,
|
||||
&:where(:has(.for-screen-reader):has(img, svg)) {
|
||||
--btn-border-radius: 50%;
|
||||
--btn-padding: 0;
|
||||
|
||||
aspect-ratio: 1;
|
||||
block-size: var(--btn-size);
|
||||
display: grid;
|
||||
inline-size: var(--btn-size);
|
||||
place-items: center;
|
||||
|
||||
> * {
|
||||
grid-area: 1/1;
|
||||
}
|
||||
}
|
||||
|
||||
/* With radios and checkboxes */
|
||||
&:has(input[type=radio], input[type=checkbox]) {
|
||||
:is(input[type=radio], input[type=checkbox]) {
|
||||
appearance: none;
|
||||
block-size: calc(var(--btn-size) - var(--outline-size));
|
||||
border-radius: var(--btn-border-radius);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
inline-size: calc(var(--btn-size) - var(--outline-size));
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
img.checked {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input:checked) {
|
||||
--btn-background: var(--color-ink);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-ink);
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
img {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
|
||||
img.checked {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled],
|
||||
&:has([disabled]),
|
||||
[disabled] &[type=submit],
|
||||
&[type=submit]:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Variants */
|
||||
.btn--link {
|
||||
--btn-background: var(--color-link);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-link);
|
||||
}
|
||||
|
||||
.btn--negative {
|
||||
--btn-background: var(--color-negative);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-negative);
|
||||
}
|
||||
|
||||
.btn--placeholder {
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.btn--plain {
|
||||
--btn-border-radius: 0.5em;
|
||||
--btn-border-size: 0;
|
||||
--btn-icon-size: 100%;
|
||||
--btn-padding: 0;
|
||||
--hover-size: 0;
|
||||
}
|
||||
|
||||
.btn--positive {
|
||||
--btn-background: var(--color-positive);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-positive);
|
||||
}
|
||||
|
||||
.btn--reversed {
|
||||
--btn-background: var(--color-ink);
|
||||
--btn-color: var(--color-bg);
|
||||
--outline-color: var(--color-ink);
|
||||
}
|
||||
|
||||
:is(.btn--link, .btn--negative, .btn--positive, .btn--reversed) {
|
||||
--btn-border-color: var(--color-bg);
|
||||
|
||||
img:not([class]) {
|
||||
filter: invert(1);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn--small {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.btn--success {
|
||||
animation: success 1s ease-out;
|
||||
|
||||
img {
|
||||
animation: zoom-fade 300ms ease-out;
|
||||
}
|
||||
}
|
||||
65
app/assets/stylesheets/colors.css
Normal file
65
app/assets/stylesheets/colors.css
Normal file
@@ -0,0 +1,65 @@
|
||||
:root {
|
||||
/* Named color values */
|
||||
--lch-black: 0% 0 0;
|
||||
--lch-white: 100% 0 0;
|
||||
--lch-gray-light: 96% 0.005 96;
|
||||
--lch-gray: 92% 0.005 96;
|
||||
--lch-gray-dark: 75% 0.005 96;
|
||||
--lch-blue: 54% 0.15 255;
|
||||
--lch-blue-light: 95% 0.03 255;
|
||||
--lch-blue-dark: 80% 0.08 255;
|
||||
--lch-orange: 70% 0.2 44;
|
||||
--lch-red: 51% 0.2 31;
|
||||
--lch-green: 65.59% 0.234 142.49;
|
||||
--lch-green-light: 95% 0.03 142.49;
|
||||
--lch-always-black: 0% 0 0;
|
||||
--lch-always-white: 100% 0 0;
|
||||
|
||||
/* Abstractions */
|
||||
--color-negative: oklch(var(--lch-red));
|
||||
--color-positive: oklch(var(--lch-green));
|
||||
--color-positive-light: oklch(var(--lch-green-light));
|
||||
--color-bg: oklch(var(--lch-white));
|
||||
--color-ink: oklch(var(--lch-black));
|
||||
--color-ink-reversed: oklch(var(--lch-white));
|
||||
--color-link: oklch(var(--lch-blue));
|
||||
--color-subtle-light: oklch(var(--lch-gray-light));
|
||||
--color-subtle: oklch(var(--lch-gray));
|
||||
--color-subtle-dark: oklch(var(--lch-gray-dark));
|
||||
--color-selected: oklch(var(--lch-blue-light));
|
||||
--color-selected-dark: oklch(var(--lch-blue-dark));
|
||||
--color-marker: oklch(var(--lch-orange));
|
||||
--color-always-black: oklch(var(--lch-always-black));
|
||||
--color-always-white: oklch(var(--lch-always-white));
|
||||
|
||||
/* Redefine named color values for dark mode */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--lch-black: 100% 0 0;
|
||||
--lch-white: 0% 0 0;
|
||||
--lch-gray-light: 25.2% 0 0;
|
||||
--lch-gray: 30.12% 0 0;
|
||||
--lch-gray-dark: 44.95% 0 0;
|
||||
--lch-blue: 72.25% 0.16 248;
|
||||
--lch-blue-light: 28.11% 0.053 248;
|
||||
--lch-blue-dark: 42.25% 0.07 248;
|
||||
--lch-red: 73.8% 0.184 29.18;
|
||||
--lch-green: 75% 0.21 141.89;
|
||||
--lch-green-light: 28.11% 0.02 142.49;
|
||||
}
|
||||
}
|
||||
|
||||
.colorize--white {
|
||||
filter: invert(1);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
|
||||
.colorize--black {
|
||||
filter: invert(0);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
45
app/assets/stylesheets/dialog.css
Normal file
45
app/assets/stylesheets/dialog.css
Normal file
@@ -0,0 +1,45 @@
|
||||
:is(.dialog) {
|
||||
--backdrop-speed: 150ms;
|
||||
--panel-size: max-content;
|
||||
--speed: 150ms;
|
||||
|
||||
border: 0;
|
||||
opacity: 0;
|
||||
transform: translateY(50%);
|
||||
transform-origin: bottom center;
|
||||
transition:
|
||||
display var(--speed) allow-discrete,
|
||||
opacity var(--speed),
|
||||
overlay var(--speed) allow-discrete,
|
||||
transform var(--speed);
|
||||
|
||||
&::backdrop {
|
||||
background-color: var(--color-ink);
|
||||
opacity: 0;
|
||||
transform: translateY(0);
|
||||
transition:
|
||||
display var(--backdrop-speed) allow-discrete,
|
||||
opacity var(--backdrop-speed),
|
||||
overlay var(--backdrop-speed) allow-discrete;
|
||||
}
|
||||
|
||||
&[open] {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
|
||||
&::backdrop {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
&[open] {
|
||||
opacity: 0;
|
||||
transform: translateY(50%);
|
||||
}
|
||||
|
||||
&[open]::backdrop {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
161
app/assets/stylesheets/house.css
Normal file
161
app/assets/stylesheets/house.css
Normal file
@@ -0,0 +1,161 @@
|
||||
:root {
|
||||
--house-border-radius: 0.5em;
|
||||
}
|
||||
|
||||
:where(house-md) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
&:invalid {
|
||||
border: var(--color-negative) 2px solid;
|
||||
}
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
:where(house-md-toolbar) {
|
||||
--hover-size: 0;
|
||||
|
||||
border-radius: var(--house-border-radius);
|
||||
display: inline-flex;
|
||||
gap: 0.1em;
|
||||
|
||||
:is(button, label) {
|
||||
aspect-ratio: 6/5;
|
||||
align-items: center;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: var(--house-border-radius);
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
inline-size: auto;
|
||||
justify-content: center;
|
||||
min-block-size: 2em;
|
||||
transition: background-color 300ms ease;
|
||||
|
||||
:is(img, svg) {
|
||||
-webkit-touch-callout: none;
|
||||
block-size: 1em;
|
||||
fill: currentColor;
|
||||
inline-size: auto;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&:where(:focus-visible) {
|
||||
background-color: var(--color-bg);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
background-color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&:where(:active) {
|
||||
background-color: var(--color-selected-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Markdown Content */
|
||||
:where(.house-md-content) {
|
||||
caret-color: var(--color-link);
|
||||
flex-grow: 1;
|
||||
min-block-size: 50dvh;
|
||||
text-align: start;
|
||||
white-space: break-spaces;
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Uploads */
|
||||
:where(house-md-upload) {
|
||||
border-radius: var(--house-border-radius);
|
||||
margin-block: 0.5ex;
|
||||
position: relative;
|
||||
|
||||
&[status="failed"] {
|
||||
background-color: var(--color-negative);
|
||||
color: var(--color-ink-reversed);
|
||||
font-weight: bold;
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
:where(.md-close) {
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
block-size: 1em;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
inset: 0.5em 0.5em auto auto;
|
||||
inline-size: 1em;
|
||||
outline: none;
|
||||
position: absolute;
|
||||
|
||||
house-md-upload[status="failed"] & {
|
||||
color: var(--color-ink-reversed);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&::before {
|
||||
color: var(--color-ink-reversed);
|
||||
content: '×';
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
inset: 50% auto auto 50%;
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
:where(.md-file) {
|
||||
font-weight: normal;
|
||||
|
||||
house-md-upload[status="complete"] & {
|
||||
color: var(--color-positive);
|
||||
}
|
||||
}
|
||||
|
||||
:where(.md-progress-bar) {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--color-subtle);
|
||||
block-size: 1ex;
|
||||
border-radius: var(--house-border-radius);
|
||||
display: block;
|
||||
inline-size: 100%;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
|
||||
house-md-upload[status="failed"] & ,
|
||||
house-md-upload[status="complete"] & {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
background-color: var(--color-subtle);
|
||||
border-radius: var(--house-border-radius);
|
||||
}
|
||||
|
||||
&::-webkit-progress-inner-element {
|
||||
border-radius: var(--house-border-radius);
|
||||
}
|
||||
|
||||
&::-webkit-progress-value {
|
||||
background-color: var(--color-positive);
|
||||
border-radius: var(--house-border-radius);
|
||||
}
|
||||
|
||||
&::-moz-progress-bar {
|
||||
background-color: var(--color-positive);
|
||||
border-radius: var(--house-border-radius);
|
||||
}
|
||||
}
|
||||
181
app/assets/stylesheets/inputs.css
Normal file
181
app/assets/stylesheets/inputs.css
Normal file
@@ -0,0 +1,181 @@
|
||||
/* Text inputs */
|
||||
.input {
|
||||
accent-color: var(--input-accent-color, var(--color-ink));
|
||||
background-color: var(--input-background, transparent);
|
||||
border-radius: var(--input-border-radius, 0.5em);
|
||||
border: var(--input-border-size, 1px) solid var(--input-border-color, var(--color-subtle-dark));
|
||||
color: var(--input-color, var(--color-ink));
|
||||
font-size: max(16px, 1em);
|
||||
inline-size: 100%;
|
||||
line-height: 1.2;
|
||||
max-inline-size: 100%;
|
||||
padding: var(--input-padding, 0.5em 0.8em);
|
||||
resize: none;
|
||||
|
||||
&:autofill,
|
||||
&:-webkit-autofill,
|
||||
&:-webkit-autofill:hover,
|
||||
&:-webkit-autofill:focus {
|
||||
-webkit-text-fill-color: var(--color-ink);
|
||||
-webkit-box-shadow: 0 0 0px 1000px var(--color-selected) inset;
|
||||
}
|
||||
|
||||
&:where(:not(:active)):focus {
|
||||
--input-border-color: var(--color-selected-dark);
|
||||
--hover-color: var(--color-selected-dark);
|
||||
--outline-size: 0;
|
||||
--outline-color: transparent;
|
||||
|
||||
filter: var(--hover-filter);
|
||||
box-shadow: 0 0 0 var(--hover-size) var(--hover-color);
|
||||
}
|
||||
}
|
||||
|
||||
.input--file {
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
inline-size: auto;
|
||||
place-items: center;
|
||||
|
||||
> * {
|
||||
grid-area: 1 / 1;
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
--input-border-color: transparent;
|
||||
--input-border-radius: 8px;
|
||||
|
||||
block-size: 100%;
|
||||
cursor: pointer;
|
||||
font-size: 0;
|
||||
inline-size: 100%;
|
||||
overflow: clip;
|
||||
|
||||
&::file-selector-button {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
--input-border-color: var(--color-selected-dark);
|
||||
--input-border-radius: 8px;
|
||||
--input-border-size: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input--textara {
|
||||
--input-padding: 0.5em;
|
||||
|
||||
line-height: 1.1;
|
||||
min-block-size: calc(4lh + (2 * var(--input-padding)));
|
||||
min-inline-size: 100%;
|
||||
padding-block: var(--input-padding);
|
||||
padding-inline: calc(var(--input-padding) + calc((1lh - 1ex) / 2));
|
||||
|
||||
@supports (field-sizing: content) {
|
||||
field-sizing: content;
|
||||
max-block-size: calc(10lh + (2 * var(--input-padding)));
|
||||
min-block-size: calc(1lh + (2 * var(--input-padding)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Switches */
|
||||
.switch {
|
||||
block-size: 1.75em;
|
||||
border-radius: 2em;
|
||||
display: inline-flex;
|
||||
inline-size: 3em;
|
||||
position: relative;
|
||||
|
||||
&:has(:focus-visible) {
|
||||
.switch__btn {
|
||||
box-shadow:
|
||||
0 0 0 var(--outline-size) var(--color-bg),
|
||||
0 0 0 calc(var(--outline-size) * 2) var(--color-ink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.switch__input {
|
||||
block-size: 0;
|
||||
inline-size: 0;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.switch__btn {
|
||||
background-color: var(--color-subtle-dark);
|
||||
border-radius: 2em;
|
||||
cursor: pointer;
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
transition: 150ms ease;
|
||||
|
||||
&::before {
|
||||
background-color: var(--color-ink-reversed);
|
||||
block-size: 1.35em;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
inline-size: 1.35em;
|
||||
inset-block-end: 0.2em;
|
||||
inset-inline-start: 0.2em;
|
||||
position: absolute;
|
||||
transition: 150ms ease;
|
||||
}
|
||||
|
||||
.switch__input:disabled + & {
|
||||
background-color: var(--color-subtle-dark) !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.switch__input:checked + & {
|
||||
background-color: var(--color-link);
|
||||
|
||||
&::before {
|
||||
transform: translateX(1.2em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Containers that act like (and contain) inputs */
|
||||
.input--actor {
|
||||
transition: box-shadow 150ms ease, outline-offset 150ms ease;
|
||||
|
||||
&:focus-within {
|
||||
--input-border-color: var(--color-selected-dark);
|
||||
--hover-color: var(--color-selected-dark);
|
||||
--outline-size: 0;
|
||||
|
||||
filter: var(--hover-filter);
|
||||
box-shadow: 0 0 0 var(--hover-size) var(--hover-color);
|
||||
}
|
||||
|
||||
.input {
|
||||
--input-padding: 0;
|
||||
--input-border-radius: 0;
|
||||
--input-background: transparent;
|
||||
--input-border-size: 0;
|
||||
--hover-size: 0;
|
||||
--outline-size: 0;
|
||||
--outline-color: transparent;
|
||||
|
||||
inline-size: 100%;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&:has(.input:is(
|
||||
:autofill,
|
||||
:-webkit-autofill,
|
||||
:-webkit-autofill:hover,
|
||||
:-webkit-autofill:focus)) {
|
||||
-webkit-text-fill-color: var(--color-text);
|
||||
-webkit-box-shadow: 0 0 0px 1000px var(--color-selected) inset;
|
||||
}
|
||||
}
|
||||
86
app/assets/stylesheets/layout.css
Normal file
86
app/assets/stylesheets/layout.css
Normal file
@@ -0,0 +1,86 @@
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto 1fr auto var(--block-space);
|
||||
}
|
||||
|
||||
:where(#main) {
|
||||
container-type: inline-size;
|
||||
font-size: var(--font-medium-responsive);
|
||||
inline-size: 67ch;
|
||||
margin-inline: auto;
|
||||
max-inline-size: 100vw;
|
||||
padding-block-end: clamp(var(--block-space), 5%, calc(var(--block-space) * 3));
|
||||
padding-inline: clamp(var(--inline-space), 5%, calc(var(--inline-space) * 3));
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: 70ch) {
|
||||
padding-inline: var(--inline-space);
|
||||
}
|
||||
|
||||
@media print {
|
||||
font-size: 11pt;
|
||||
inline-size: unset;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
orphans: 3;
|
||||
padding: 0;
|
||||
text-align: justify;
|
||||
text-justify: distribute;
|
||||
widows: 2;
|
||||
}
|
||||
}
|
||||
|
||||
:where(#footer) {
|
||||
max-inline-size: 100vw;
|
||||
view-transition-name: footer;
|
||||
|
||||
> nav {
|
||||
padding-inline: var(--inline-space);
|
||||
view-transition-name: footer-nav;
|
||||
}
|
||||
|
||||
&:has(.new-book-btn) {
|
||||
inset-block-end: 0;
|
||||
pointer-events: none;
|
||||
position: sticky;
|
||||
}
|
||||
}
|
||||
|
||||
:where(#header) {
|
||||
max-inline-size: 100vw;
|
||||
view-transition-name: header;
|
||||
|
||||
> nav {
|
||||
view-transition-name: nav;
|
||||
}
|
||||
|
||||
> * {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 1ch;
|
||||
justify-content: center;
|
||||
padding: var(--block-space-half) var(--inline-space);
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:where(#toolbar) {
|
||||
display: flex;
|
||||
inset: 0 0 auto;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
padding-inline: var(--inline-space);
|
||||
position: sticky;
|
||||
view-transition-name: toolbar;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:is(#header, #footer, #toolbar) {
|
||||
@media print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
28
app/assets/stylesheets/library.css
Normal file
28
app/assets/stylesheets/library.css
Normal file
@@ -0,0 +1,28 @@
|
||||
.library {
|
||||
--gap: clamp(var(--inline-space), 2cqi, calc(var(--inline-space) * 3));
|
||||
--hover-size: 0;
|
||||
|
||||
display: grid;
|
||||
gap: var(--block-space) var(--gap);
|
||||
grid-template-columns: repeat(auto-fit, minmax(max(150px, 14cqi), 1fr));
|
||||
padding: var(--gap);
|
||||
}
|
||||
|
||||
.library__book {
|
||||
--row-gap: calc(var(--block-space) * 0.2);
|
||||
|
||||
container-type: inline-size;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.library__book--empty {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
|
||||
* {
|
||||
grid-area: 1 / 1;
|
||||
}
|
||||
}
|
||||
57
app/assets/stylesheets/lightbox.css
Normal file
57
app/assets/stylesheets/lightbox.css
Normal file
@@ -0,0 +1,57 @@
|
||||
.lightbox {
|
||||
--speed: 150ms;
|
||||
|
||||
background-color: oklch(var(--lch-white) / 0.66);
|
||||
block-size: 100dvh;
|
||||
border: 0;
|
||||
inline-size: 100dvw;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
max-height: unset;
|
||||
max-width: unset;
|
||||
overflow: hidden;
|
||||
padding: var(--block-space-half) var(--inline-space);
|
||||
|
||||
&::backdrop {
|
||||
-webkit-backdrop-filter: blur(66px);
|
||||
backdrop-filter: blur(66px);
|
||||
background-color: var(--color-ink);
|
||||
opacity: 0;
|
||||
transition:
|
||||
display var(--backdrop-speed) allow-discrete,
|
||||
opacity var(--backdrop-speed),
|
||||
overlay var(--backdrop-speed) allow-discrete;
|
||||
}
|
||||
|
||||
&[open] {
|
||||
display: grid;
|
||||
opacity: 1;
|
||||
place-items: center;
|
||||
|
||||
&::backdrop {
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
&[open] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&[open]::backdrop {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightbox__btn {
|
||||
align-self: start;
|
||||
grid-area: 1/1;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.lightbox__image {
|
||||
grid-area: 1/1;
|
||||
max-inline-size: calc(100dvw - (var(--inline-space) * 2));
|
||||
max-block-size: calc(100dvh - (var(--block-space) * 2));
|
||||
}
|
||||
182
app/assets/stylesheets/pages.css
Normal file
182
app/assets/stylesheets/pages.css
Normal file
@@ -0,0 +1,182 @@
|
||||
#main:has(.page--section, .page--picture) {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
#main:has(.page--picture:not(.picture-form)) {
|
||||
inline-size: 100%;
|
||||
padding: 0;
|
||||
|
||||
figcaption {
|
||||
inline-size: 67ch;
|
||||
margin-inline: auto;
|
||||
max-inline-size: 100dvw;
|
||||
padding-inline: clamp(var(--inline-space), 5%, calc(var(--inline-space) * 3));
|
||||
}
|
||||
}
|
||||
|
||||
:has(#section_theme[value=dark]:checked),
|
||||
:not(:has(#section_theme[value=dark])):has(.page--section.theme--dark) {
|
||||
--lch-black: 100% 0 0;
|
||||
--lch-white: 0% 0 0;
|
||||
--lch-gray-light: 25.2% 0 0;
|
||||
--lch-gray: 30.12% 0 0;
|
||||
--lch-gray-dark: 44.95% 0 0;
|
||||
--lch-blue: 72.25% 0.16 248;
|
||||
--lch-blue-light: 28.11% 0.053 248;
|
||||
--lch-blue-dark: 42.25% 0.07 248;
|
||||
--lch-red: 73.8% 0.184 29.18;
|
||||
--lch-green: 75% 0.21 141.89;
|
||||
--lch-green-light: 28.11% 0.02 142.49;
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--lch-black: 0% 0 0;
|
||||
--lch-white: 100% 0 0;
|
||||
--lch-gray-light: 96% 0.005 96;
|
||||
--lch-gray: 92% 0.005 96;
|
||||
--lch-gray-dark: 75% 0.005 96;
|
||||
--lch-blue: 54% 0.15 255;
|
||||
--lch-blue-light: 95% 0.03 255;
|
||||
--lch-blue-dark: 80% 0.08 255;
|
||||
--lch-orange: 70% 0.2 44;
|
||||
--lch-red: 51% 0.2 31;
|
||||
--lch-green: 65.59% 0.234 142.49;
|
||||
--lch-green-light: 95% 0.03 142.49;
|
||||
--lch-always-black: 0% 0 0;
|
||||
}
|
||||
|
||||
img,
|
||||
.btn img {
|
||||
filter: invert(1);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
|
||||
.btn:has(input:checked) {
|
||||
& img {
|
||||
filter: invert(0);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
& img {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.page-toolbar {
|
||||
--padding-block: 0.5em;
|
||||
--padding-inline: 1.1em;
|
||||
|
||||
border-radius: 5em;
|
||||
display: inline-flex;
|
||||
margin: var(--block-space-half) auto;
|
||||
min-width: 0;
|
||||
padding: var(--padding-block) var(--padding-inline);
|
||||
transition: background-color 300ms ease;
|
||||
|
||||
.separator {
|
||||
block-size: 100%;
|
||||
border-color: var(--color-bg);
|
||||
border-width: 3px;
|
||||
margin-block: calc(-1 * var(--padding-block));
|
||||
}
|
||||
|
||||
.btn {
|
||||
--btn-border-color: transparent;
|
||||
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:is(.page__body, .page--page) {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
:is(.page--section, .page--picture) {
|
||||
place-self: center;
|
||||
}
|
||||
|
||||
body:has(#leafable-editor.clean) {
|
||||
& .page-toolbar__save {
|
||||
--btn-background: var(--color-positive);
|
||||
--btn-border-color: var(--color-bg);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-positive);
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:has(#leafable-editor.dirty) {
|
||||
& .page-toolbar__save {
|
||||
--btn-background: var(--color-link);
|
||||
--btn-border-color: var(--color-bg);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--outline-color: var(--color-link);
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:has(#leafable-editor.saving) .page-toolbar__save {
|
||||
position: relative;
|
||||
|
||||
> * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&::after {
|
||||
--mask: no-repeat radial-gradient(#000 68%,#0000 71%);
|
||||
--size: 1.25em;
|
||||
|
||||
-webkit-mask: var(--mask), var(--mask), var(--mask);
|
||||
-webkit-mask-size: 28% 45%;
|
||||
animation: submitting 1s infinite linear;
|
||||
aspect-ratio: 8/5;
|
||||
background: currentColor;
|
||||
content: "";
|
||||
inline-size: var(--size);
|
||||
inset: 50%;
|
||||
margin-block: calc((var(--size) / 3) * -1);
|
||||
margin-inline: calc((var(--size) / 2) * -1);
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
body.edit-mode .hide_from_edit_mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:not(.edit-mode) .hide_from_reading_mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.being-edited-by {
|
||||
animation: fade-out 300ms ease-out 20s;
|
||||
background-color: var(--color-ink);
|
||||
border-radius: 2em;
|
||||
color: var(--color-ink-reversed);
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
.page-edit__current {
|
||||
@media (max-width: 70ch) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
13
app/assets/stylesheets/panels.css
Normal file
13
app/assets/stylesheets/panels.css
Normal file
@@ -0,0 +1,13 @@
|
||||
.panel {
|
||||
background-color: var(--color-bg);
|
||||
border: 1px solid var(--panel-border-color, var(--color-subtle));
|
||||
color: var(--color-ink);
|
||||
border-radius: var(--panel-border-radius, 1em);
|
||||
inline-size: var(--panel-size, 40ch);
|
||||
max-inline-size: 100%;
|
||||
padding: calc(var(--block-space) * 2);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--panel-border-color: var(--color-subtle-dark);
|
||||
}
|
||||
}
|
||||
19
app/assets/stylesheets/popover.css
Normal file
19
app/assets/stylesheets/popover.css
Normal file
@@ -0,0 +1,19 @@
|
||||
:is(.popover) {
|
||||
--speed: 150ms;
|
||||
|
||||
opacity: 0;
|
||||
transition:
|
||||
display var(--speed) allow-discrete,
|
||||
opacity var(--speed),
|
||||
overlay var(--speed) allow-discrete,;
|
||||
|
||||
&[open] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
&[open] {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/assets/stylesheets/product.css
Normal file
17
app/assets/stylesheets/product.css
Normal file
@@ -0,0 +1,17 @@
|
||||
.product__logo {
|
||||
block-size: 6.5em;
|
||||
flex-shrink: 0;
|
||||
inline-size: 6.5em;
|
||||
}
|
||||
|
||||
.product__wordmark {
|
||||
--btn-gap: 0.2em;
|
||||
--btn-icon-size: 1.8em;
|
||||
}
|
||||
|
||||
.product__version-badge {
|
||||
border: 1px solid var(--color-subtle-dark);
|
||||
border-radius: 0.3em;
|
||||
color: var(--color-subtle-dark);
|
||||
padding: 0.1em var(--inline-space-half);
|
||||
}
|
||||
4
app/assets/stylesheets/qr-code.css
Normal file
4
app/assets/stylesheets/qr-code.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.qr-code {
|
||||
aspect-ratio: 1;
|
||||
block-size: 50dvh;
|
||||
}
|
||||
106
app/assets/stylesheets/syntax.css
Normal file
106
app/assets/stylesheets/syntax.css
Normal file
@@ -0,0 +1,106 @@
|
||||
.highlight {
|
||||
/* Named color values */
|
||||
--keyword: lch(50.16 68.78 25.97);
|
||||
--entity: lch(39.03 73.26 304.21);
|
||||
--constant: lch(39.68 63.13 279.47);
|
||||
--string: lch(19.22 34.92 275.47);
|
||||
--variable: lch(57.9 81.69 53.33);
|
||||
--comment: lch(47.93 7 254.8);
|
||||
--entity-tag: lch(39.64 68.17 142.85);
|
||||
--markup-heading: lch(39.68 63.13 279.47);
|
||||
--markup-list: lch(40.44 43.36 84.69);
|
||||
--markup-inserted: lch(39.64 68.17 142.85);
|
||||
--markup-deleted: lch(39.64 68.17 31.45);
|
||||
|
||||
/* Redefine named color values for dark mode */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--keyword: lch(67.63 58.99 30.64);
|
||||
--entity: lch(75.13 46.73 306.74);
|
||||
--constant: lch(74.9 39.71 255.53);
|
||||
--string: lch(74.9 39.71 255.53);
|
||||
--variable: lch(76.17 61.1 61.97);
|
||||
--comment: lch(60.83 6.66 254.46);
|
||||
--entity-tag: lch(83.65 59.31 141.61);
|
||||
--markup-heading: lch(47.93 71.67 280.72);
|
||||
--markup-list: lch(83.84 57.9 85.03);
|
||||
--markup-inserted: lch(83.65 59.31 141.61);
|
||||
--markup-deleted: lch(73.8% 65 29.18);
|
||||
}
|
||||
|
||||
color: var(--color-ink);
|
||||
|
||||
.w {
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.k, .kd, .kn, .kp, .kr, .kt, .kv {
|
||||
color: var(--keyword);
|
||||
}
|
||||
|
||||
.gr {
|
||||
color: var(--color-subtle-light);
|
||||
}
|
||||
|
||||
.gd {
|
||||
color: var(--markup-deleted);
|
||||
background-color: light-dark(lch(39.64 68.17 31.45 / 0.15), lch(39.64 68.17 31.45 / 0.2));
|
||||
}
|
||||
|
||||
.nb, .nc, .no, .nn {
|
||||
color: var(--variable);
|
||||
}
|
||||
|
||||
.sr, .na, .nt {
|
||||
color: var(--entity-tag);
|
||||
}
|
||||
|
||||
.gi {
|
||||
color: var(--markup-inserted);
|
||||
background-color: light-dark(lch(49.14 52.75 142.85 / 0.15), lch(83.65 59.31 141.61 / 0.15));
|
||||
}
|
||||
|
||||
.kc, .l, .ld, .m, .mb, .mf, .mh, .mi, .il, .mo, .mx, .sb, .bp, .ne, .nl, .py, .nv, .vc, .vg, .vi, .vm, .o, .ow {
|
||||
color: var(--constant);
|
||||
}
|
||||
|
||||
.gh {
|
||||
color: var(--constant);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gu {
|
||||
color: var(--constant);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.s, .sa, .sc, .dl, .sd, .s2, .se, .sh, .sx, .s1, .ss {
|
||||
color: var(--string);
|
||||
}
|
||||
|
||||
.nd, .nf, .fm {
|
||||
color: var(--entity);
|
||||
}
|
||||
|
||||
.err {
|
||||
color: var(--color-ink-reversed);
|
||||
background-color: var(--markup-deleted);
|
||||
}
|
||||
|
||||
.c, .ch, .cd, .cm, .cp, .cpf, .c1, .cs, .gl, .gt {
|
||||
color: var(--comment);
|
||||
}
|
||||
|
||||
.ni, .si {
|
||||
color: var(--storage-modifier-import);
|
||||
}
|
||||
|
||||
.ge {
|
||||
color: var(--storage-modifier-import);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.gs {
|
||||
color: var(--storage-modifier-import);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
161
app/assets/stylesheets/text.css
Normal file
161
app/assets/stylesheets/text.css
Normal file
@@ -0,0 +1,161 @@
|
||||
:where(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6) {
|
||||
font-weight: 800;
|
||||
hyphens: auto;
|
||||
letter-spacing: -0.02ch;
|
||||
line-height: 1.1;
|
||||
margin-block: 0;
|
||||
overflow-wrap: break-word;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
:where(h1, h2, h3, h4, h5, h6) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6) {
|
||||
margin-block: 0.65em;
|
||||
}
|
||||
|
||||
:is(h1, .h1) {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
:is(h2, .h2) {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
:is(h3, .h3) {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
:is(h4, .h4) {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
:is(h5, .h5) {
|
||||
font-size: 0.83em;
|
||||
}
|
||||
|
||||
:is(h6, .h6) {
|
||||
font-size: 0.67em;
|
||||
}
|
||||
|
||||
:is(p, ul, ol, dl, blockquote, pre, figure, table, hr) {
|
||||
margin-block: 0.65lh;
|
||||
overflow-wrap: break-word;
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
.heading {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.heading__link {
|
||||
--hover-size: 0;
|
||||
--opacity: 0.5;
|
||||
--size: 0.8em;
|
||||
|
||||
background: url(link.svg) no-repeat center bottom 0.2em;
|
||||
background-size: var(--size);
|
||||
block-size: 1em;
|
||||
color: var(--color-link);
|
||||
display: inline-flex;
|
||||
font-size: var(--size);
|
||||
inline-size: var(--size);
|
||||
padding: 1em 0 0;
|
||||
opacity: var(--opacity);
|
||||
overflow: hidden;
|
||||
transition: opacity 300ms ease;
|
||||
vertical-align: middle;
|
||||
|
||||
@media (hover: hover) {
|
||||
--opacity: 0;
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6):hover & {
|
||||
--opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
border-color: var(--color-subtle-dark);
|
||||
border-style: var(--border-style, solid) none none;
|
||||
margin: 2lh auto;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
:is(pre, code, .pre, .code) {
|
||||
background-color: var(--color-subtle-light);
|
||||
border: 1px solid var(--color-subtle);
|
||||
border-radius: 0.3em;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0.1em 0.3em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
:is(pre, .pre) {
|
||||
border-radius: 0.5em;
|
||||
padding: 0.5lh 2ch;
|
||||
|
||||
:is(code, .code) {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
font-size: 1em;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
hyphens: auto;
|
||||
letter-spacing: -0.005ch;
|
||||
}
|
||||
|
||||
:is(blockquote, .quote) {
|
||||
font-style: italic;
|
||||
margin: 0 3ch;
|
||||
|
||||
p {
|
||||
hyphens: none;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid var(--color-subtle-dark);
|
||||
border-collapse: collapse;
|
||||
margin: 1lh 0;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
:where(th, td) {
|
||||
border: 1px solid var(--color-subtle-dark);
|
||||
padding: 0.2lh 1ch;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
:where(th) {
|
||||
border-block-end-width: 3px;
|
||||
}
|
||||
|
||||
del {
|
||||
background-color: oklch(var(--lch-red) / 0.1);
|
||||
color: var(--color-negative);
|
||||
}
|
||||
|
||||
ins {
|
||||
background-color: oklch(var(--lch-green) / 0.1);
|
||||
color: var(--color-positive);
|
||||
}
|
||||
256
app/assets/stylesheets/toc.css
Normal file
256
app/assets/stylesheets/toc.css
Normal file
@@ -0,0 +1,256 @@
|
||||
.toc {
|
||||
--hover-size: 0;
|
||||
|
||||
display: grid;
|
||||
inline-size: auto;
|
||||
gap: var(--block-space) var(--inline-space);
|
||||
grid-template-columns: repeat(auto-fit, minmax(max(130px, 12cqi), 1fr));
|
||||
letter-spacing: -0.01ch;
|
||||
list-style: none;
|
||||
outline-offset: var(--inline-space-half);
|
||||
padding: 0;
|
||||
|
||||
&:has(turbo-frame > :last-child:nth-child(-n + 2)) {
|
||||
@media (min-width: 70ch) {
|
||||
grid-template-columns: repeat(auto-fit, minmax(max(130px, 12cqi), 24cqi));
|
||||
}
|
||||
}
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.toc__container:where(:has(#toc-list:checked)) & {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: calc(var(--block-space) * 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.toc__blank-slate {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
margin-inline: auto;
|
||||
|
||||
img {
|
||||
inline-size: 6.5em;
|
||||
}
|
||||
|
||||
:has(.toc__leaf) & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.toc__bookmark {
|
||||
--icon-size: 1.4em;
|
||||
|
||||
display: none;
|
||||
|
||||
.toc__leaf--last-read & {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.toc__container:where(:has(#toc-grid:checked)) & {
|
||||
inset: calc(var(--icon-size) * -0.33) 0 auto calc(var(--icon-size) * -0.5);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
svg {
|
||||
block-size: var(--icon-size);
|
||||
flex-shrink: 0;
|
||||
inline-size: var(--icon-size);
|
||||
}
|
||||
}
|
||||
|
||||
.toc__container {
|
||||
max-inline-size: 70ch;
|
||||
|
||||
&:where(:has(#delete-mode:checked)) {
|
||||
.disable-when-deleting {
|
||||
cursor: not-allowed;
|
||||
filter: grayscale(100%) contrast(0.5);
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toc__leaf {
|
||||
border: solid 2px transparent;
|
||||
color: var(--color-ink);
|
||||
container-type: inline-size;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
scroll-margin-top: 8em;
|
||||
text-align: center;
|
||||
|
||||
.toc__container:where(:has(#toc-list:checked)) & {
|
||||
align-items: center;
|
||||
column-gap: 1ch;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
row-gap: calc(var(--block-space) * 0.3);
|
||||
text-align: start;
|
||||
}
|
||||
}
|
||||
|
||||
.toc__title {
|
||||
--title-border-color: var(--color-subtle-dark);
|
||||
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: var(--font-medium-responsive);
|
||||
gap: var(--inline-space);
|
||||
line-height: 1.2;
|
||||
text-decoration: none;
|
||||
|
||||
.toc__container:where(:has(#toc-grid:checked)) & {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.toc__container:where(:has(#toc-list:checked)) & {
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
font-size: inherit;
|
||||
white-space: nowrap;
|
||||
|
||||
&:is(a) {
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
text-decoration-line: underline;
|
||||
text-decoration-thickness: 0.075em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:is(.input) {
|
||||
field-sizing: content;
|
||||
min-inline-size: 20ch;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-block-end: 1px dotted var(--title-border-color);
|
||||
content: "";
|
||||
flex-grow: 1;
|
||||
margin-block-end: 0.25em;
|
||||
}
|
||||
|
||||
.toc__leaf--section & {
|
||||
font-weight: 750;
|
||||
}
|
||||
}
|
||||
|
||||
.toc__leaf--last-read & {
|
||||
--title-border-color: var(--color-marker);
|
||||
}
|
||||
}
|
||||
|
||||
.toc__thumbnail {
|
||||
aspect-ratio: 6 / 9;
|
||||
border-radius: 0.3em;
|
||||
border: 1px solid var(--color-subtle-dark);
|
||||
color: inherit;
|
||||
display: block;
|
||||
font-size: clamp(0.5rem, 5cqi, 0.8rem);
|
||||
line-height: 1.4;
|
||||
margin-block-end: var(--block-space-half);
|
||||
overflow: hidden;
|
||||
padding: 10cqi;
|
||||
position: relative;
|
||||
text-align: start;
|
||||
text-decoration: none;
|
||||
|
||||
.toc__link {
|
||||
background-color: transparent;
|
||||
content: "";
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
.toc__container:where(:has(#delete-mode:checked)) & {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.toc__leaf--section & {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: var(--font-medium-responsive);
|
||||
font-weight: 900;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.toc__leaf--picture & {
|
||||
padding: 0;
|
||||
|
||||
img {
|
||||
block-size: 100%;
|
||||
inline-size: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.toc__container:where(:has(#toc-list:checked)) & {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.heading__link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.toc__thumbnail--dark {
|
||||
background-color: var(--color-ink);
|
||||
color: var(--color-ink-reversed);
|
||||
}
|
||||
}
|
||||
|
||||
.toc__wordcount {
|
||||
white-space: nowrap;
|
||||
|
||||
.toc__container:where(:has(#toc-list:checked)) & {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete mode */
|
||||
.leaf__delete {
|
||||
--hover-color: var(--color-negative);
|
||||
--hover-size: max(2px, 0.08em);
|
||||
|
||||
display: none;
|
||||
|
||||
#footer &,
|
||||
.toc__container:where(:has(#delete-mode:checked)) & {
|
||||
display: flex;
|
||||
|
||||
:is(.delete-mode__button:has(input:checked)) {
|
||||
--btn-background: var(--color-negative);
|
||||
}
|
||||
}
|
||||
|
||||
.toc__container:where(:has(#toc-grid:checked)) & .btn {
|
||||
margin-block-end: calc(-0.5 * var(--btn-size));
|
||||
margin-inline: auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-mode__button:has(input:checked) {
|
||||
--btn-background: var(--color-negative);
|
||||
}
|
||||
|
||||
.arrange-mode__button:has(input:checked) {
|
||||
--btn-background: var(--color-link);
|
||||
}
|
||||
|
||||
body:not(:has(.toc__leaf)) {
|
||||
.disable-when-empty {
|
||||
cursor: not-allowed;
|
||||
filter: grayscale(100%) contrast(0.5);
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
33
app/assets/stylesheets/translations.css
Normal file
33
app/assets/stylesheets/translations.css
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Language translations */
|
||||
.lanuage-list-menu {
|
||||
--max-width: 40ch;
|
||||
|
||||
background-color: var(--color-subtle);
|
||||
border: 1px solid var(--color-subtle-dark);
|
||||
border-radius: 0.5em;
|
||||
inset: auto;
|
||||
inline-size: max-content;
|
||||
margin-inline: var(--inline-space);
|
||||
max-inline-size: 40ch;
|
||||
overflow: clip;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
@media (max-width: 70ch) {
|
||||
max-inline-size: calc(var(--max-width) - var(--inline-space));
|
||||
}
|
||||
|
||||
.popover-orientation-top & {
|
||||
inset-block-end: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.language-list {
|
||||
display: grid;
|
||||
gap: var(--block-space-half) var(--inline-space);
|
||||
grid-template-rows: min-content;
|
||||
grid-template-columns: min-content 1fr;
|
||||
justify-content: start;
|
||||
margin: 0;
|
||||
text-align: start;
|
||||
}
|
||||
240
app/assets/stylesheets/utilities.css
Normal file
240
app/assets/stylesheets/utilities.css
Normal file
@@ -0,0 +1,240 @@
|
||||
:root {
|
||||
--inline-space: 1ch;
|
||||
--inline-space-half: calc(var(--inline-space) / 2);
|
||||
--inline-space-double: calc(var(--inline-space) * 2);
|
||||
|
||||
--block-space: 1rem;
|
||||
--block-space-half: calc(var(--block-space) / 2);
|
||||
--block-space-double: calc(var(--block-space) * 2);
|
||||
|
||||
--font-small-responsive: clamp(0.8rem, 2cqi, 1rem);
|
||||
--font-medium-responsive: clamp(1rem, 2.5cqi, 1.4rem);
|
||||
--font-large-responsive: clamp(1.3rem, 4cqi, 1.8rem);
|
||||
--font-x-large-responsive: clamp(1.8rem, 5cqi, 3.2rem);
|
||||
}
|
||||
|
||||
/* Text */
|
||||
.txt-small { font-size: 0.8rem; }
|
||||
.txt-medium { font-size: 1rem; }
|
||||
.txt-large { font-size: 1.4rem; }
|
||||
.txt-x-large { font-size: 1.8rem; }
|
||||
.txt-xx-large { font-size: 2.4rem; }
|
||||
|
||||
.txt-small--responsive { font-size: var(--font-small-responsive); }
|
||||
.txt-medium--responsive { font-size: var(--font-medium-responsive); }
|
||||
.txt-large--responsive { font-size: var(--font-large-responsive); }
|
||||
.txt-x-large--responsive { font-size: var(--font-x-large-responsive); }
|
||||
|
||||
.txt-align-center { text-align: center; }
|
||||
.txt-align-start { text-align: start; }
|
||||
.txt-align-end { text-align: end; }
|
||||
|
||||
.txt-ink { color: var(--color-ink); }
|
||||
.txt-reversed { color: var(--color-ink-reversed); }
|
||||
.txt-negative { color: var(--color-negative); }
|
||||
.txt-subtle { color: var(--color-subtle-dark); }
|
||||
.txt-undecorated { text-decoration: none; }
|
||||
.txt-tight-lines { line-height: 1.2; }
|
||||
.txt-normal { font-weight: 400; font-style: normal; }
|
||||
.txt-nowrap { white-space: nowrap; }
|
||||
.txt-uppercase { text-transform: uppercase; }
|
||||
|
||||
/* Flexbox and Grid */
|
||||
.justify-end { justify-content: end; }
|
||||
.justify-start { justify-content: start; }
|
||||
.justify-center { justify-content: center; }
|
||||
.justify-space-between { justify-content: space-between; }
|
||||
|
||||
.align-center { align-items: center; }
|
||||
.align-start { align-items: start; }
|
||||
.align-end { align-items: end; }
|
||||
|
||||
.align-self-start { align-self: start; }
|
||||
|
||||
.contain { contain: inline-size; }
|
||||
|
||||
.flex { display: flex; }
|
||||
.flex-inline { display: inline-flex; }
|
||||
.flex-column { flex-direction: column; }
|
||||
.flex-wrap { flex-wrap: wrap; }
|
||||
|
||||
.flex-item-grow { flex-grow: 1; }
|
||||
.flex-item-shrink { flex-shrink: 1; }
|
||||
.flex-item-no-shrink { flex-shrink: 0; }
|
||||
.flex-item-justify-start { margin-inline-end: auto; }
|
||||
.flex-item-justify-end { margin-inline-start: auto; }
|
||||
|
||||
.gap {
|
||||
column-gap: var(--column-gap, var(--inline-space));
|
||||
row-gap: var(--row-gap, var(--block-space));
|
||||
}
|
||||
|
||||
.gap-half {
|
||||
column-gap: var(--inline-space-half);
|
||||
row-gap: var(--block-space-half);
|
||||
}
|
||||
|
||||
/* Sizing */
|
||||
.full-width { inline-size: 100%; }
|
||||
.min-width { min-inline-size: 0; }
|
||||
.half-width { inline-size: 50%; }
|
||||
.max-width { max-inline-size: 100%; }
|
||||
.min-content { inline-size: min-content; }
|
||||
.max-inline-size { max-inline-size: 100%; }
|
||||
|
||||
/* Overflow */
|
||||
.overflow-x { overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; }
|
||||
.overflow-y { overflow-y: auto; scroll-snap-type: y mandatory; scroll-behavior: smooth; }
|
||||
.overflow-clip { text-overflow: clip; white-space: nowrap; overflow: hidden; }
|
||||
.overflow-ellipsis { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
|
||||
|
||||
.overflow-hide-scrollbar::-webkit-scrollbar {
|
||||
@media (pointer: course) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.overflow-line-clamp {
|
||||
-webkit-line-clamp: var(--lines, 2);
|
||||
-webkit-box-orient: vertical;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Padding */
|
||||
.pad { padding: var(--block-space) var(--inline-space); }
|
||||
.pad-double { padding: var(--block-space-double) var(--inline-space-double); }
|
||||
|
||||
.pad-block { padding-block: var(--block-space); }
|
||||
.pad-block-start { padding-block-start: var(--block-space); }
|
||||
.pad-block-end { padding-block-end: var(--block-space); }
|
||||
.pad-block-half { padding-block: var(--block-space-half); }
|
||||
.pad-block-start-half { padding-block-start: var(--block-space-half); }
|
||||
|
||||
.pad-inline { padding-inline: var(--inline-space); }
|
||||
.pad-inline-start { padding-inline-start: var(--inline-space); }
|
||||
.pad-inline-end { padding-inline-end: var(--inline-space); }
|
||||
.pad-inline-half { padding-inline: var(--inline-space-half); }
|
||||
.pad-inline-double { padding-inline: var(--inline-space-double); }
|
||||
|
||||
.unpad { padding: 0; }
|
||||
|
||||
/* Margins */
|
||||
.margin { margin: var(--block-space) var(--inline-space); }
|
||||
.margin-block { margin-block: var(--block-space); }
|
||||
.margin-block-half { margin-block: var(--block-space-half); }
|
||||
.margin-block-start { margin-block-start: var(--block-space); }
|
||||
.margin-block-start-half { margin-block-start: var(--block-space-half); }
|
||||
.margin-block-end { margin-block-end: var(--block-space); }
|
||||
.margin-block-end-half { margin-block-end: var(--block-space-half); }
|
||||
.margin-block-double { margin-block: var(--block-space-double); }
|
||||
.margin-block-end-double { margin-block-end: var(--block-space-double); }
|
||||
.margin-block-start-double { margin-block-start: var(--block-space-double); }
|
||||
|
||||
.margin-inline { margin-inline: var(--inline-space); }
|
||||
.margin-inline-start { margin-inline-start: var(--inline-space); }
|
||||
.margin-inline-start-half { margin-inline-start: var(--inline-space-half); }
|
||||
.margin-inline-end { margin-inline-end: var(--inline-space); }
|
||||
.margin-inline-end-half { margin-inline-end: var(--inline-space-half); }
|
||||
.margin-inline-half { margin-inline: var(--inline-space-half); }
|
||||
.margin-inline-double { margin-inline: var(--inline-space-double); }
|
||||
|
||||
.margin-none { margin: 0; }
|
||||
.margin-none-block { margin-block: 0; }
|
||||
.margin-none-block-start { margin-block-start: 0; }
|
||||
.margin-none-block-end { margin-block-end: 0; }
|
||||
|
||||
.margin-none-inline { margin-inline: 0; }
|
||||
.margin-none-inline-start { margin-inline-start: 0; }
|
||||
.margin-none-inline-end { margin-inline-end: 0; }
|
||||
|
||||
.center { margin-inline: auto; }
|
||||
.center-block { margin-block: auto; }
|
||||
|
||||
/* Position */
|
||||
.position-relative { position: relative; }
|
||||
.position-sticky { position: sticky; }
|
||||
|
||||
/* Fills */
|
||||
.fill { background-color: var(--color-bg); }
|
||||
.fill-black { background-color: var(--color-ink); }
|
||||
.fill-white { background-color: var(--color-ink-reversed); }
|
||||
.fill-shade { background-color: var(--color-subtle-light); }
|
||||
.fill-selected { background-color: var(--color-selected); }
|
||||
.fill-transparent { background-color: transparent; }
|
||||
|
||||
.translucent { opacity: var(--opacity, 0.5); }
|
||||
|
||||
/* Borders */
|
||||
.border { border: var(--border-size, 1px) solid var(--border-color, var(--color-subtle)); }
|
||||
.border-top { border-top: var(--border-size, 1px) solid var(--border-color, var(--color-subtle)); }
|
||||
.borderless { border: 0; }
|
||||
|
||||
/* Border radius */
|
||||
.border-radius { border-radius: var(--border-radius, 1em); }
|
||||
|
||||
/* Shadows */
|
||||
.shadow {
|
||||
box-shadow:
|
||||
0 0 0 1px oklch(var(--lch-always-black) / 0.02),
|
||||
0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.2),
|
||||
0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.3),
|
||||
0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.4),
|
||||
0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.5),
|
||||
0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 0.6);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
box-shadow:
|
||||
0 0 0 1px oklch(var(--lch-always-black) / 0.42),
|
||||
0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.6),
|
||||
0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.7),
|
||||
0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.8),
|
||||
0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.9),
|
||||
0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Seperators */
|
||||
.separator {
|
||||
border-inline-start: 1px solid var(--color-subtle-dark);
|
||||
display: inline-flex;
|
||||
inline-size: 0;
|
||||
}
|
||||
|
||||
/* Spinners */
|
||||
.spinner {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
--mask: no-repeat radial-gradient(#000 68%, #0000 71%);
|
||||
--dot-size: 1.25em;
|
||||
|
||||
-webkit-mask: var(--mask), var(--mask), var(--mask);
|
||||
-webkit-mask-size: 28% 45%;
|
||||
animation: submitting 1.3s infinite linear;
|
||||
aspect-ratio: 8/5;
|
||||
background: currentColor;
|
||||
content: "";
|
||||
inline-size: var(--dot-size);
|
||||
inset: 50% 0.25em;
|
||||
margin-block: calc((var(--dot-size) / 3) * -1);
|
||||
margin-inline: calc((var(--dot-size) / 2) * -1);
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessibility */
|
||||
.for-screen-reader {
|
||||
block-size: 1px;
|
||||
clip-path: inset(50%);
|
||||
inline-size: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Visibility */
|
||||
[hidden] { display: none; }
|
||||
[contents] { display: contents; }
|
||||
Reference in New Issue
Block a user