diff --git a/src/routes/viewer.ts b/src/routes/viewer.ts index 5464b7d7..2085421d 100644 --- a/src/routes/viewer.ts +++ b/src/routes/viewer.ts @@ -69,7 +69,9 @@ router.get(/.*/, async (req: Request, res: Response) => { ${title} + + diff --git a/static/colors.css b/static/colors.css new file mode 100644 index 00000000..ef7ea1d3 --- /dev/null +++ b/static/colors.css @@ -0,0 +1,94 @@ +/* -------------------------------------------------------------------------- + * DARK MODE ---------------------------------------------------------------- */ + +:root { + --bg-primary: black; + --bg-secondary: #161616; + --bg-code: #333; + --bg-mark: rgba(255, 255, 175, 0.8); + + --text-primary: #aaa; + --text-secondary: #6a6a6a; /* #7d7d7d from foot notes */ + --text-link: #859abc; + --text-mark: #222; + + --border-regular: #353535; + --border-muted: #303030; + + --syntax-text: var(--text-primary); + --syntax-keyword: #aed7ff; + --syntax-entity: #aeafff; + --syntax-constant: #d1b0fa; + --syntax-string: #d787af; + --syntax-symbol: var(--syntax-constant); + --syntax-comment: #949494; + --syntax-entity-tag: #d7afd7; + --syntax-storage-modifier-import: var(--syntax-text); + + --syntax-markup-heading: var(--syntax-text); + --syntax-markup-list: var(--syntax-text); + --syntax-markup-italic: var(--syntax-text); + --syntax-markup-bold: var(--syntax-text); + --syntax-markup-inserted-fg: #aff5b4; + --syntax-markup-inserted-bg: #033a16; + --syntax-markup-deleted-fg: #ffdcd7; + --syntax-markup-deleted-bg: #67060c; + + --alert-note: #a5d5fe; + --alert-tip: #b4fa72; + --alert-important: #ff8ffd; + --alert-warning: #ffaf00; + --alert-caution: #ff5f5f; + + --ipynb-bg-error: rgba(255, 0, 0, 0.1); +} + +/* -------------------------------------------------------------------------- + * LIGHT MODE --------------------------------------------------------------- */ + +@media (prefers-color-scheme: light) { + :root { + --bg-primary: white; + --bg-secondary: #f6f8fa; + --bg-code: #eff1f3; + --bg-mark: rgba(255, 255, 175, 1); + + --text-primary: #1f2328; + --text-secondary: #656d76; + --text-link: #0969da; + --text-mark: var(--text-primary); + + --border-regular: #d0d7de; + --border-muted: #d8dee4; + + /* source for light mode syntax theme: + * https://github.com/highlightjs/highlight.js/blob/main/src/styles/github.css + * */ + --syntax-text: #24292e; + --syntax-keyword: #d73a49; + --syntax-entity: #6f42c1; + --syntax-constant: #005cc5; + --syntax-string: #032f62; + --syntax-symbol: #e36209; + --syntax-comment: #6a737d; + --syntax-entity-tag: #22863a; + --syntax-storage-modifier-import: var(--syntax-text); + + --syntax-markup-heading: var(--syntax-constant); + --syntax-markup-list: #735c0f; + --syntax-markup-italic: var(--syntax-text); + --syntax-markup-bold: var(--syntax-text); + --syntax-markup-inserted-fg: var(--syntax-entity-tag); + --syntax-markup-inserted-bg: #f0fff4; + --syntax-markup-deleted-fg: #b31d28; + --syntax-markup-deleted-bg: #ffeef0; + + --alert-note: var(--text-link); + --alert-tip: #1a7f37; + --alert-important: #8250df; + --alert-warning: #bf8700; + --alert-caution: #cf222e; + + --ipynb-bg-error: rgba(255, 0, 0, 0.1); + } +} diff --git a/static/highlight.css b/static/highlight.css index 43bd1d48..704eb716 100644 --- a/static/highlight.css +++ b/static/highlight.css @@ -1,163 +1,102 @@ -/* translucent dark */ -.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{ - color: #aed7ff; +.hljs { + color: var(--syntax-text); } -.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{ - color: #aeafff; +.hljs-doctag, +.hljs-keyword, +.hljs-meta .hljs-keyword, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-variable.language_ { + color: var(--syntax-keyword); } -.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{ - color: #d1b0fa; +.hljs-title, +.hljs-title.class_, +.hljs-title.class_.inherited__, +.hljs-title.function_ { + color: var(--syntax-entity); } -.hljs-meta .hljs-string,.hljs-regexp,.hljs-string,.hljs-subst{ - color: #d787af; +.hljs-attr, +.hljs-attribute, +.hljs-literal, +.hljs-meta, +.hljs-number, +.hljs-operator, +.hljs-variable, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-id { + color: var(--syntax-constant); } -.hljs-built_in,.hljs-symbol{ - color: #d1b0fa; - font-weight: bold; +.hljs-regexp, +.hljs-string, +.hljs-meta .hljs-string { + color: var(--syntax-string); } -.hljs-code,.hljs-comment,.hljs-formula{ - color: #949494; - font-style: italic; +.hljs-built_in, +.hljs-symbol { + color: var(--syntax-symbol); + font-style: bold; } -.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{ - color: #d7afd7; +.hljs-comment, +.hljs-code, +.hljs-formula { + color: var(--syntax-comment); + font-style: italic; } -.hljs-strong,.hljs-emphasis{ - font-weight: bold; +.hljs-name, +.hljs-quote, +.hljs-selector-tag, +.hljs-selector-pseudo { + color: var(--syntax-entity-tag); } -.hljs-addition{ - color: #aff5b4; - background-color: #033a16; +.hljs-subst { + color: var(--syntax-storage-modifier-import); } -.hljs-deletion{ - color: #ffdcd7; - background-color: #67060c; +.hljs-section { + color: var(--syntax-markup-heading); + font-weight: bold; } -/* light mode */ -/* source: https://github.com/highlightjs/highlight.js/blob/main/src/styles/github.css */ -@media (prefers-color-scheme: light) { - .hljs { - color: #24292e; - background: #ffffff; - } - - .hljs-doctag, - .hljs-keyword, - .hljs-meta .hljs-keyword, - .hljs-template-tag, - .hljs-template-variable, - .hljs-type, - .hljs-variable.language_ { - /* prettylights-syntax-keyword */ - color: #d73a49; - } - - .hljs-title, - .hljs-title.class_, - .hljs-title.class_.inherited__, - .hljs-title.function_ { - /* prettylights-syntax-entity */ - color: #6f42c1; - } - - .hljs-attr, - .hljs-attribute, - .hljs-literal, - .hljs-meta, - .hljs-number, - .hljs-operator, - .hljs-variable, - .hljs-selector-attr, - .hljs-selector-class, - .hljs-selector-id { - /* prettylights-syntax-constant */ - color: #005cc5; - } - - .hljs-regexp, - .hljs-string, - .hljs-meta .hljs-string { - /* prettylights-syntax-string */ - color: #032f62; - } - - .hljs-built_in, - .hljs-symbol { - /* prettylights-syntax-variable */ - color: #e36209; - } - - .hljs-comment, - .hljs-code, - .hljs-formula { - /* prettylights-syntax-comment */ - color: #6a737d; - } - - .hljs-name, - .hljs-quote, - .hljs-selector-tag, - .hljs-selector-pseudo { - /* prettylights-syntax-entity-tag */ - color: #22863a; - } - - .hljs-subst { - /* prettylights-syntax-storage-modifier-import */ - color: #24292e; - } - - .hljs-section { - /* prettylights-syntax-markup-heading */ - color: #005cc5; - font-weight: bold; - } - - .hljs-bullet { - /* prettylights-syntax-markup-list */ - color: #735c0f; - } +.hljs-bullet { + color: var(--syntax-markup-bullet); +} - .hljs-emphasis { - /* prettylights-syntax-markup-italic */ - color: #24292e; - font-style: italic; - } +.hljs-emphasis { + color: var(--syntax-markup-italic); + font-style: italic; +} - .hljs-strong { - /* prettylights-syntax-markup-bold */ - color: #24292e; - font-weight: bold; - } +.hljs-strong { + color: var(--syntax-markup-bold); + font-weight: bold; +} - .hljs-addition { - /* prettylights-syntax-markup-inserted */ - color: #22863a; - background-color: #f0fff4; - } +.hljs-addition { + color: var(--syntax-markup-inserted-fg); + background-color: var(--syntax-markup-inserted-bg); +} - .hljs-deletion { - /* prettylights-syntax-markup-deleted */ - color: #b31d28; - background-color: #ffeef0; - } +.hljs-deletion { + color: var(--syntax-markup-deleted-fg); + background-color: var(--syntax-markup-deleted-bg); +} - .hljs-char.escape_, - .hljs-link, - .hljs-params, - .hljs-property, - .hljs-punctuation, - .hljs-tag { - /* purposely ignored */ - } +.hljs-char.escape_, +.hljs-link, +.hljs-params, +.hljs-property, +.hljs-punctuation, +.hljs-tag { + /* purposely ignored */ + color: inherit; } diff --git a/static/ipynb.css b/static/ipynb.css index 57911b9b..e68d9702 100644 --- a/static/ipynb.css +++ b/static/ipynb.css @@ -19,9 +19,9 @@ padding: unset; background-color: unset; } -.ipynb-output-stream-stderr { background-color: rgba(255, 0, 0, 0.1); } +.ipynb-output-stream-stderr { background-color: var(--ipynb-bg-error); } -.ipynb-output-error { background-color: rgba(255, 0, 0, 0.1); } +.ipynb-output-error { background-color: var(--ipynb-bg-error); } .ipynb-output-plain { padding: unset; diff --git a/static/markdown.css b/static/markdown.css new file mode 100644 index 00000000..742867e3 --- /dev/null +++ b/static/markdown.css @@ -0,0 +1,215 @@ +/* -------------------------------------------------------------------------- + * CODE --------------------------------------------------------------------- */ + +pre { + background-color: var(--bg-secondary); + padding: 1rem; + overflow: auto; +} +code { + background-color: var(--bg-code); + padding: 0.2rem; + border-radius: 0.25rem; +} +pre > code { + background-color: unset; + padding: unset; +} + +/* -------------------------------------------------------------------------- + * LINKS -------------------------------------------------------------------- */ + +a { + color: var(--text-link); + text-decoration: none; +} +a:hover { text-decoration: underline; } +a.header-anchor { + opacity: 0; + position: absolute; + transform: translateX(-2rem); + width: 2rem; +} +a.header-anchor:hover, +h1:hover a.header-anchor, h2:hover a.header-anchor, +h3:hover a.header-anchor, h4:hover a.header-anchor, +h5:hover a.header-anchor, h6:hover a.header-anchor { + opacity: 1; +} +a#top-nav-up:before { content: '◂'} + +/* -------------------------------------------------------------------------- + * TABLES ------------------------------------------------------------------- */ + +table { + border-spacing: 0; + border-collapse: collapse; + margin-top: 0; + margin-bottom: 16px; +} + +th, td { + padding: 6px 13px; + border: 1px solid var(--border-regular); +} + +tr:nth-child(even) { + background-color: var(--bg-secondary); +} + +/* -------------------------------------------------------------------------- + * LISTS -------------------------------------------------------------------- */ + +li.task-list-item { list-style: none; } +input.task-list-item-checkbox { + position: absolute; + transform: translateX(-1.44rem); +} + +/* -------------------------------------------------------------------------- + * FOOTNOTE ----------------------------------------------------------------- */ + +.footnotes-sep { + display: none; +} +section.footnotes { + font-size: 0.75rem; + margin-top: 1.25rem; + border-top: 0.2px solid var(--border-muted); + color: var(--text-secondary); +} + +/* -------------------------------------------------------------------------- + * DEFIITION LISTS ---------------------------------------------------------- */ + +dl { + display: flex; + flex-flow: row wrap; +} +dt { + flex-basis: 20%; + text-align: right; + font-weight: bold; + padding: 0.25em; + margin: 0.25em 0; +} +dd { + flex-basis: 80%; + flex-grow: 1; + text-align: left; + border-left: 0.2px solid var(--border-muted); + margin: 0; + padding: 0.25em; + margin: 0.25em 0; +} +dd + dd { + margin-left: 20%; + margin-top: -0.25em; +} +dt + dt { + margin-right: 80%; + margin-top: -0.25em; +} +dt + dt + dd { + margin-left: 20%; + margin-top: -2.25em; /* Align definition with last term */ +} /* Self height - margin - padding */ + +/* -------------------------------------------------------------------------- + * QUOTES AND ALERTS--------------------------------------------------------- */ + +blockquote { + padding: 0 1rem; + color: var(--text-secondary); + border-left: .25em solid var(--border-regular); + margin-left: 0; +} + +/* GitHub-style alerts */ +.markdown-alert { + padding: 0.5rem 1rem; + margin-bottom: 1rem; +} +.markdown-alert > :first-child { + margin-top: 0; +} +.markdown-alert > :last-child { + margin-bottom: 0; +} +.markdown-alert .markdown-alert-title { + display: flex; + font-weight: 500; + align-items: center; + line-height: 1; +} +.markdown-alert .markdown-alert-title .octicon { + margin-right: 0.5rem; + display: inline-block; + overflow: visible !important; + vertical-align: text-bottom; + fill: currentColor; +} +.markdown-alert-note { + border-left: .25rem solid var(--alert-note); +} +.markdown-alert-note .markdown-alert-title { + color: var(--alert-note); +} +.markdown-alert-tip { + border-left: .25rem solid var(--alert-tip); +} +.markdown-alert-tip .markdown-alert-title { + color: var(--alert-tip); +} +.markdown-alert-important { + border-left: .25rem solid var(--alert-important); +} +.markdown-alert-important .markdown-alert-title { + color: var(--alert-important); +} +.markdown-alert-warning { + border-left: .25rem solid var(--alert-warning); +} +.markdown-alert-warning .markdown-alert-title { + color: var(--alert-warning); +} +.markdown-alert-caution { + border-left: .25rem solid var(--alert-caution); +} +.markdown-alert-caution .markdown-alert-title { + color: var(--alert-caution); +} + +/* -------------------------------------------------------------------------- + * MISCELLANEOUS ------------------------------------------------------------ */ + +/* headings */ +h1, h2 { + border-bottom: 0.2px solid var(--border-muted); + padding-bottom: 0.75rem; +} + +/* images */ +img, svg { max-width: 100%; } + +/* keyboard */ +kbd { + background-color: var(--bg-secondary); + border: 1px solid var(--border-regular); + box-shadow: inset 0 -1px 0 var(--border-regular); + padding: 3px 5px; + border-radius: 6px; +} + +/* highlight/mark */ +mark { + background-color: var(--bg-mark); + color: var(--text-mark); +} + +/* horizontal rule */ +hr { + border: 0; + border-top: 0.25em solid var(--border-regular); + margin: 24px 0; +} diff --git a/static/style.css b/static/style.css index c36e34bf..e13ad262 100644 --- a/static/style.css +++ b/static/style.css @@ -1,20 +1,15 @@ -:root { - --color-alert-note: #a5d5fe; - --color-alert-tip: #b4fa72; - --color-alert-important: #ff8ffd; - --color-alert-warning: #ffaf00; - --color-alert-caution: #ff5f5f; +* { + box-sizing: border-box; } html { - background-color: black; - color: #aaa; + background-color: var(--bg-primary); + color: var(--text-primary); font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; line-height: 1.5; } body { - box-sizing: border-box; padding: 2rem 4rem; } @@ -26,68 +21,7 @@ body { .content-txt { max-width: 1200px; } /* -------------------------------------------------------------------------- - * CODE --------------------------------------------------------------------- */ -pre { - background-color: #161616; - padding: 1rem; - overflow: auto; -} -code { - background-color: #333; - padding: 0.2rem; - border-radius: 0.25rem; -} -pre > code { - background-color: unset; - padding: unset; -} - -/* -------------------------------------------------------------------------- - * LINKS -------------------------------------------------------------------- */ -a { - color: #859abc; - text-decoration: none; -} -a:hover { text-decoration: underline; } -a.header-anchor { - opacity: 0; - position: absolute; - transform: translateX(-2rem); - width: 2rem; -} -a.header-anchor:hover, -h1:hover a.header-anchor, h2:hover a.header-anchor, -h3:hover a.header-anchor, h4:hover a.header-anchor, -h5:hover a.header-anchor, h6:hover a.header-anchor { - opacity: 1; -} -a#top-nav-up:before { content: '◂'} - -/* -------------------------------------------------------------------------- - * TABLES ------------------------------------------------------------------- */ -table { - border-spacing: 0; - border-collapse: collapse; - margin-top: 0; - margin-bottom: 16px; -} - -th, td { - padding: 6px 13px; - border: 1px solid #444; -} - -tr:nth-child(even) { - background-color: #161616; -} - -/* -------------------------------------------------------------------------- - * LISTS -------------------------------------------------------------------- */ -li.task-list-item { list-style: none; } -input.task-list-item-checkbox { - position: absolute; - transform: translateX(-1.44rem); -} + * DIRECTORY LISTS ---------------------------------------------------------- */ ul.dir-list { padding: 0 } li[class^='dir-list-'] { @@ -97,221 +31,3 @@ li[class^='dir-list-'] { li[class^='dir-list-']:before { margin-right: 0.5rem; } li.dir-list-directory:before { content: '📁' } li.dir-list-file:before { content: '📄' } - -/* -------------------------------------------------------------------------- - * HORIZONTAL RULE ---------------------------------------------------------- */ -hr { - height: .25em; - margin: 24px 0; - background-color: #353535; - border: 0; -} - -/* -------------------------------------------------------------------------- - * FOOTNOTE ----------------------------------------------------------------- */ -.footnotes-sep { - display: none; -} -section.footnotes { - font-size: 0.75rem; - margin-top: 1.25rem; - border-top: 0.2px solid #444; - color: #7d7d7d; -} - -/* -------------------------------------------------------------------------- - * DEFIITION LISTS ---------------------------------------------------------- */ -dl { - display: flex; - flex-flow: row wrap; -} -dt { - flex-basis: 20%; - text-align: right; - font-weight: bold; - box-sizing: border-box; - padding: 0.25em; - margin: 0.25em 0; -} -dd { - flex-basis: 80%; - flex-grow: 1; - text-align: left; - box-sizing: border-box; - border-left: 0.2px solid #444; - margin: 0; - padding: 0.25em; - margin: 0.25em 0; -} -dd + dd { - margin-left: 20%; - margin-top: -0.25em; -} -dt + dt { - margin-right: 80%; - margin-top: -0.25em; -} -dt + dt + dd { - margin-left: 20%; - margin-top: -2.25em; /* Align definition with last term */ -} /* Self height - margin - padding */ - -/* -------------------------------------------------------------------------- - * QUOTES AND ALERTS--------------------------------------------------------- */ -blockquote { - padding: 0 1rem; - color: #6a6a6a; - border-left: .25rem solid #353535; - margin-left: 0; -} -/* GitHub-style alerts */ -.markdown-alert { - padding: 0.5rem 1rem; - margin-bottom: 1rem; -} -.markdown-alert > :first-child { - margin-top: 0; -} -.markdown-alert > :last-child { - margin-bottom: 0; -} -.markdown-alert .markdown-alert-title { - display: flex; - font-weight: 500; - align-items: center; - line-height: 1; -} -.markdown-alert .markdown-alert-title .octicon { - margin-right: 0.5rem; - display: inline-block; - overflow: visible !important; - vertical-align: text-bottom; - fill: currentColor; -} -.markdown-alert-note { - border-left: .25rem solid var(--color-alert-note); -} -.markdown-alert-note .markdown-alert-title { - color: var(--color-alert-note); -} -.markdown-alert-tip { - border-left: .25rem solid var(--color-alert-tip); -} -.markdown-alert-tip .markdown-alert-title { - color: var(--color-alert-tip); -} -.markdown-alert-important { - border-left: .25rem solid var(--color-alert-important); -} -.markdown-alert-important .markdown-alert-title { - color: var(--color-alert-important); -} -.markdown-alert-warning { - border-left: .25rem solid var(--color-alert-warning); -} -.markdown-alert-warning .markdown-alert-title { - color: var(--color-alert-warning); -} -.markdown-alert-caution { - border-left: .25rem solid var(--color-alert-caution); -} -.markdown-alert-caution .markdown-alert-title { - color: var(--color-alert-caution); -} -/* -------------------------------------------------------------------------- - * MISCELLANEOUS ------------------------------------------------------------ */ -/* headings */ -h1, h2 { - border-bottom: 0.2px solid #444; - padding-bottom: 0.75rem; -} -/* images */ -img, svg { max-width: 100%; } - -/* keyboard */ -kbd { - background-color: #161616; - border: 1px solid #242424; - box-shadow: inset 0 -1px 0 #242424; - padding: 3px 5px; - border-radius: 6px; -} - -/* highlight/mark */ -mark { - background-color: rgba(255, 255, 175, 0.8); - color: #222; -} - -/* -------------------------------------------------------------------------- - * LIGHT MODE --------------------------------------------------------------- */ -@media (prefers-color-scheme: light) { - :root { - --color-alert-note: #0969da; - --color-alert-tip: #1a7f37; - --color-alert-important: #8250df; - --color-alert-warning: #bf8700; - --color-alert-caution: #cf222e; - } - html { - background-color: white; - color: #1f2328; - } - - h1, h2 { - border-bottom: 0.2px solid #d8dee4; - } - - pre { - background-color: #f6f8fa; - } - - code { - background-color: #afb8c133; - } - - a { - color: #0969da; - } - - a#parent-dir { - background-color: #afb8c133; - } - - blockquote { - color: #656d76; - border-left: .25em solid #d0d7de; - } - - th, td { - border: 1px solid #d8dee4; - } - - tr:nth-child(even) { - background-color: #f6f8fa; - } - - hr { - background-color: #d0d7de; - } - - section.footnotes { - border-top: 0.2px solid #d8dee4; - color: #656d76; - } - - dd { - border-left: 0.2px solid #d8dee4; - } - - kbd { - background-color: #f6f8fa; - border: 1px solid #eff1f3; - box-shadow: inset 0 -1px 0 #eff1f3; - } - - mark { - background-color: rgba(255, 255, 175, 1); - color: #1f2328; - } -}