ScrollHub: The fastest way to publish
@media print {.doNotPrint {display: none !important;}}
/* gazette.css scrollHubStyle.css ./ide/codeMirror.css */
:root {
/* Base Colors */
--scrollPrimaryRgb: 10, 92, 202; /* Base primary button */
--scrollSurfaceRgb: 204, 204, 204; /* Base surface */
--scrollTextBase: 0, 0, 0;
--scrollLinkBase: 51, 102, 204;
/* Semantic Colors */
--scrollColorBackground: rgb(244, 244, 244);
--scrollColorText: rgba(var(--scrollTextBase), 1);
--scrollColorLink: rgb(var(--scrollLinkBase), 1);
--scrollColorSubdued: rgb(150, 150, 150);
/* Typography */
--scrollFontPrimary: Exchange, Georgia, serif;
--scrollFontUi: "SF Pro", "Helvetica Neue", "Segoe UI", "Arial";
--scrollFontMono: monospace;
--scrollBaseFontSize: 16px;
/* Derived Colors */
--scrollColorPrimary: rgba(var(--scrollPrimaryRgb), 0.8);
--scrollColorPrimaryHover: rgba(var(--scrollPrimaryRgb), 0.9);
--scrollColorPrimaryActive: rgb(var(--scrollPrimaryRgb));
--scrollColorSurface: rgba(var(--scrollSurfaceRgb), 0.4);
--scrollColorSurfaceAlt: rgba(var(--scrollSurfaceRgb), 0.6);
--scrollColorBorder: rgba(var(--scrollSurfaceRgb), 0.8);
}
html,
body,
div,
span,
p,
ol,
ul,
li,
table,
figure {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
border-spacing: 0;
}
html {
background-color: var(--scrollColorBackground);
font-family: var(--scrollFontPrimary);
color: var(--scrollColorText);
font-size: var(--scrollBaseFontSize);
hyphens: auto;
}
html {
height: 100%;
}
figure {
margin: 0;
padding: 0;
}
.dropcap:first-letter {
font-size: 3rem;
line-height: 0.9em;
margin-right: 0.125rem;
display: block;
float: left;
}
.dinkus {
text-align: center;
padding: 1rem;
}
.dinkus span {
vertical-align: sub;
}
details {
margin-top: 10px;
}
summary {
font-family: var(--scrollFontUi);
cursor: pointer;
}
.scrollCaptionedFigure {
display: block;
break-inside: avoid;
max-width: 100%;
text-align: center;
}
.scrollCaptionedFigure img {
max-width: 100%;
height: auto;
margin-top: 0.1875rem;
}
.scrollCaptionedFigure figcaption {
font-family: var(--scrollFontUi);
font-size: 0.8rem;
}
.scrollCaptionedFigure figcaption .scrollParagraph {
margin-top: 0;
}
.scrollCodeBlock {
overflow: auto;
font-size: 0.8rem;
hyphens: none;
white-space: pre;
break-inside: avoid;
display: block;
margin: 0.5rem 0;
padding: 0.5rem;
border-radius: 0;
position: relative;
border-left: 0.5rem solid var(--scrollColorBorder);
}
.codeWithHeader {
break-inside: avoid-column;
margin: 10px 0;
}
.codeHeader {
font-size: 80%;
text-align: center;
background: var(--scrollColorSurfaceAlt);
border: 1px solid var(--scrollColorBorder);
border-bottom: 0;
margin-bottom: -7px;
padding: 4px 2px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.scrollCodeBlock:hover .scrollCopyButton {
opacity: 0.5;
}
.scrollCodeBlock:hover .scrollCopyButton:hover {
opacity: 0.8;
}
.scrollCodeBlock:hover .scrollCopyButton:active {
opacity: 1;
}
.scrollCopyButton {
position: absolute;
top: 0.125rem;
right: 0.125rem;
font-size: 0.875rem;
cursor: pointer;
opacity: 0;
}
.scrollCopyButton::after {
content: "[ ]";
}
.scrollCopiedButton::after {
content: "[✓]";
}
ol,
ul {
padding-left: 1rem;
}
li {
margin-top: 0.4rem;
line-height: 1.4;
}
a {
text-decoration-color: transparent;
color: var(--scrollColorLink);
}
a:hover {
text-decoration-color: initial;
}
.scrollButton {
background: linear-gradient(180deg, var(--scrollColorPrimary) 0%, color-mix(in srgb, var(--scrollColorPrimary), black 15%) 100%);
border-radius: 6px;
color: white;
padding: 10px 20px;
display: inline-block;
border: 0;
cursor: pointer;
transition: all 0.2s ease;
transform: translateY(0);
/* Halved shadow distances /
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.1),
/ Ambient shadow (halved) / 0 1px 0 rgba(255, 255, 255, 0.2) inset,
/ Top highlight / 0 -1px 0 rgba(0, 0, 0, 0.2) inset,
/ Bottom shadow (halved) / 0 1.5px 0 color-mix(in srgb, var(--scrollColorPrimary), black 30%); / 3D base (halved) */
}
.scrollButton a {
color: white;
text-decoration: none;
text-shadow: 0 0.5px 0.5px rgba(0, 0, 0, 0.2); /* Text depth (halved) */
}
.scrollButton:hover {
background: linear-gradient(180deg, color-mix(in srgb, var(--scrollColorPrimary), white 10%) 0%, var(--scrollColorPrimary) 100%);
transform: translateY(-1px); /* Halved /
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.15),
/ Halved / 0 1px 0 rgba(255, 255, 255, 0.2) inset,
0 -1px 0 rgba(0, 0, 0, 0.2) inset,
0 2.5px 0 color-mix(in srgb, var(--scrollColorPrimary), black 30%); / Halved */
}
.scrollButton:active {
background: linear-gradient(180deg, color-mix(in srgb, var(--scrollColorPrimary), black 10%) 0%, var(--scrollColorPrimary) 100%);
transform: translateY(1px); /* Halved /
box-shadow:
0 0.5px 1px rgba(0, 0, 0, 0.1),
/ Halved / 0 1px 0 rgba(255, 255, 255, 0.15) inset,
0 -0.5px 0 rgba(0, 0, 0, 0.2) inset,
0 0.5px 0 color-mix(in srgb, var(--scrollColorPrimary), black 30%); / Halved */
}
sup,
sub {
vertical-align: baseline;
position: relative;
top: -0.375rem;
}
sub {
top: 0.375rem;
}
p {
margin-top: 0.4rem;
line-height: 1.4rem;
}
.scrollQuote {
break-inside: avoid;
display: block;
margin: 0.5rem 0;
padding: 0.5rem;
background: var(--scrollColorSurface);
white-space: pre-line;
border-left: 0.5rem solid var(--scrollColorBorder);
}
code {
font-family: var(--scrollFontMono);
font-size: 0.9rem;
background-color: var(--scrollColorSurface);
padding: 0.125rem 0.25rem;
border-radius: 0.25rem;
}
.scrollParagraph {
text-align: justify;
}
center .scrollParagraph {
text-align: center;
}
.subdued {
color: var(--scrollColorSubdued);
}
.scrollColumns {
column-count: auto;
column-fill: balance;
column-width: 35ch;
column-gap: 1.5rem;
padding-left: 1.25rem;
padding-right: 1.25rem;
margin: auto;
}
.scrollSnippetContainer {
padding: 1ch 0;
break-inside: avoid;
text-align: justify;
}
h1,
h2,
h3,
h4 {
margin: 0.625rem 0;
}
h1 {
font-size: 1.25rem;
}
h2 {
font-size: 1.125rem;
}
h3,
h4 {
font-size: 1rem;
}
h1.scrollTitle {
text-align: center;
margin: auto;
margin-bottom: 0.15625rem;
margin-top: 0;
font-size: 1.75rem;
max-width: calc(100vw - 2 * (1.5625rem + 1.875rem));
}
h1.scrollTitle a {
color: var(--scrollColorText);
}
.scrollDateline {
font-style: italic;
line-height: 1.4rem;
font-size: 0.75rem;
}
.scrollSection {
break-inside: avoid;
}
.scrollSection h1,
.scrollSection h2,
.scrollSection h3,
.scrollSection h4 {
text-align: center;
}
h4.scrollQuestion {
text-align: left;
margin: 1.4rem 0 0 0;
}
.scrollSection:first-child h1,
.scrollSection:first-child h2,
.scrollSection:first-child h3,
.scrollSection:first-child h4 {
margin-top: 0;
}
.scrollSection:first-child h4.scrollQuestion {
margin-top: 0;
}
.scrollNoteLink {
opacity: 0.4;
text-decoration: none;
}
.scrollNoteLink:hover {
opacity: 1;
}
.scrollFootNoteUsageLink {
opacity: 0.7;
text-decoration: none;
}
.scrollFootNoteUsageLink:hover {
opacity: 1;
}
.scrollHoverNote {
text-decoration: underline dashed 1px rgba(0, 0, 0, 0.1);
cursor: default;
}
.scrollTable {
table-layout: fixed;
font-family: var(--scrollFontUi);
margin: 0.5rem 0;
overflow: hidden;
font-size: 0.8rem;
width: 100%;
hyphens: none;
border: 1px solid var(--scrollColorBorder);
}
.scrollTable td,
.scrollTable th {
padding: 0.1875rem;
overflow: hidden;
white-space: nowrap;
}
.scrollTable th {
text-transform: capitalize;
border-bottom: 2px solid rgba(0, 0, 0, 0.6);
text-align: left;
}
.scrollTable tr:nth-child(even) {
background: var(--scrollColorSurface);
}
.scrollTable pre {
white-space: nowrap;
overflow: hidden;
margin: 0;
}
.scrollTable.expandedTable {
table-layout: unset;
background: white;
position: relative;
z-index: 10;
overflow: unset;
}
.scrollTable.expandedTable pre {
white-space: unset;
overflow: unset;
}
.scrollTable.expandedTable td,
.scrollTable.expandedTable th {
overflow: unset;
white-space: unset;
}
.scrollByLine {
font-size: 0.875rem;
font-style: italic;
margin: 0.25rem 0;
text-align: center;
}
.abstractTextLinkParser {
text-align: center;
margin: 0.5em auto;
font-family: Verdana;
font-weight: 100;
}
.abstractTextLinkParser a {
color: var(--scrollColorBorder);
}
.abstractTextLinkParser a:hover {
color: #333;
}
.scrollContinueReadingLink {
display: block;
text-align: center;
}
.scrollDashboard {
width: 100%;
font-size: 1.875rem;
text-align: center;
font-weight: bold;
break-inside: avoid;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.scrollDashboard td {
width: 33.3%;
border: 1px solid #e8e8e8;
}
.scrollDashboard span {
font-size: 1.25rem;
display: block;
}
.scrollChat span {
font-family: Verdana;
margin-top: 0.3125rem;
padding: 0.3125rem 1.25rem;
border-radius: 0.9375rem;
display: inline-block;
}
.scrollChatLeft span {
background: var(--scrollColorSurface);
}
.scrollChatRight span {
color: white;
background: rgb(0, 132, 255);
}
.scrollYouTubeHolder {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
}
.scrollYouTubeEmbed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
nav li {
padding: 0 10px;
}
:root {
--primary-color: #4a90e2;
--secondary-color: #50c878;
--background-color: #f5f5f5;
--text-color: #333;
--form-background: #ffffff;
--border-color: rgba(204, 204, 204, 0.8);
--hover-color: rgba(114, 114, 114, 1);
--light-grey: rgba(144, 144, 144, 0.8);
--shadow-color: rgba(0, 0, 0, 0.1);
--hover-bg-color: rgba(220, 220, 220, 0.3);
--border-light: #ddd;
}
/* Scroll Template Styles */
.CodeMirror {
border-radius: 8px;
border: 1px solid var(--border-color);
}
body {
font-family: "Arial", sans-serif;
color: var(--text-color);
background-color: var(--background-color);
margin: 0;
padding: 10px;
height: 100%;
}
.selectedFile {
font-weight: bold;
}
#errorMessage {
color: red;
flex: 100%;
padding: 30px 8px 0;
display: none;
}
.greyText,
.greyText a {
color: var(--light-grey);
text-align: center;
font-size: 0.8rem;
white-space: pre;
font-family: monospace;
margin: auto;
padding: 0.5rem;
}
.folderActionLink {
color: var(--light-grey);
}
.deleteLink,
.renameLink {
color: var(--light-grey);
margin-left: 20px;
cursor: pointer;
}
.drag-over {
border: 2px dashed var(--primary-color);
background-color: rgba(0, 123, 255, 0.1);
}
#previewIFrame {
height: 600px;
width: 400px;
border: 0;
transform: scale(0.5);
transform-origin: 0 0;
}
#folderName {
outline: none;
}
.iframeHolder {
width: 200px;
height: 125px;
box-shadow: 2px 2px 2px 2px var(--shadow-color);
border-radius: 8px;
margin: 10px;
display: inline-block;
position: relative;
overflow: hidden;
}
#fileList {
margin: 0 10px;
max-height: 360px;
max-width: 200px;
overflow: auto;
}
.nonScrollFile {
color: grey;
}
.untracked {
opacity: 0.5;
}
.createFileButton {
cursor: pointer;
padding: 1px 10px;
margin: 8px;
border-radius: 5px;
display: inline-block;
text-align: center;
}
.createFileButton:hover {
background-color: var(--hover-bg-color);
}
form {
background-color: var(--form-background);
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 4px var(--shadow-color);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: top;
margin: 0 auto;
max-width: 600px;
}
#importForm {
margin-top: 20px;
}
#editForm {
max-width: 1025px;
margin-top: 20px;
margin-bottom: 20px;
padding: 0;
}
.editorHolder {
border-left: 1px solid rgb(232, 232, 232);
padding: 7px;
}
input[type="text"],
textarea {
flex-grow: 1;
padding: 10px;
border: 1px solid var(--border-light);
border-radius: 4px 0 0 4px;
font-size: 16px;
}
textarea {
width: 80ch;
max-width: 100%;
}
.CodeMirror {
border: 0;
}
.scrollButton.createButton {
padding: 10px 20px;
border-radius: 0 4px 4px 0;
font-size: 16px;
margin: 0;
}
.publishButton {
margin-top: 7px;
border-radius: 4px;
}
/* Responsive adjustments */
@media (max-width: 600px) {
body {
padding: 10px;
}
form {
flex-direction: column;
align-items: stretch;
}
input[type="text"] {
border-radius: 4px;
margin-bottom: 10px;
}
}
#spinner {
position: fixed;
top: 0;
text-align: center;
left: 0;
right: 0;
}
#spinner span {
color: grey;
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid grey;
padding: 0 10px 2px 10px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content /
}
.CodeMirror pre {
padding: 0 4px; / Horizontal padding of content */
}
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {
}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker {
color: black;
}
.CodeMirror-guttermarker-subtle {
color: #999;
}
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
@-webkit-keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
@keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {
}
.cm-tab {
display: inline-block;
text-decoration: inherit;
}
.CodeMirror-rulers {
position: absolute;
left: 0;
right: 0;
top: -50px;
bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0;
bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {
color: blue;
}
.cm-s-default .cm-quote {
color: #090;
}
.cm-negative {
color: #d44;
}
.cm-positive {
color: #292;
}
.cm-header,
.cm-strong {
font-weight: bold;
}
.cm-em {
font-style: italic;
}
.cm-link {
text-decoration: underline;
}
.cm-strikethrough {
text-decoration: line-through;
}
.cm-s-default .cm-keyword {
color: #708;
}
.cm-s-default .cm-atom {
color: #219;
}
.cm-s-default .cm-number {
color: #164;
}
.cm-s-default .cm-def {
color: #00f;
}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {
}
.cm-s-default .cm-variable-2 {
color: #05a;
}
.cm-s-default .cm-variable-3,
.cm-s-default .cm-type {
color: #085;
}
.cm-s-default .cm-comment {
color: #a50;
}
.cm-s-default .cm-string {
color: #a11;
}
.cm-s-default .cm-string-2 {
color: #f50;
}
.cm-s-default .cm-meta {
color: #555;
}
.cm-s-default .cm-qualifier {
color: #555;
}
.cm-s-default .cm-builtin {
color: #30a;
}
.cm-s-default .cm-bracket {
color: #997;
}
.cm-s-default .cm-tag {
color: #170;
}
.cm-s-default .cm-attribute {
color: #00c;
}
.cm-s-default .cm-hr {
color: #999;
}
.cm-s-default .cm-link {
color: #00c;
}
.cm-s-default .cm-error {
color: #f00;
}
.cm-invalidchar {
color: #f00;
}
.CodeMirror-composing {
border-bottom: 2px solid;
}
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {
color: #0b0;
}
div.CodeMirror span.CodeMirror-nonmatchingbracket {
color: #a22;
}
.CodeMirror-matchingtag {
background: rgba(255, 150, 0, 0.3);
}
.CodeMirror-activeline-background {
background: #e8f2ff;
}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden /
/ 30px is the magic margin used to hide the element's real scrollbars /
/ See overflow: hidden in .CodeMirror /
margin-bottom: -30px;
margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; / Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar,
.CodeMirror-hscrollbar,
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0;
top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0;
left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0;
bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0;
bottom: 0;
}
.CodeMirror-gutters {
position: absolute;
left: 0;
top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0;
bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection {
background-color: transparent;
}
.CodeMirror-gutter-wrapper ::-moz-selection {
background-color: transparent;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw /
}
.CodeMirror pre {
/ Reset some styles that the rest of the page might have set */
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {
}
.CodeMirror-rtl pre {
direction: rtl;
}
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre {
position: static;
}
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected {
background: #d9d9d9;
}
.CodeMirror-focused .CodeMirror-selected {
background: #d7d4f0;
}
.CodeMirror-crosshair {
cursor: crosshair;
}
.CodeMirror-line::selection,
.CodeMirror-line > span::selection,
.CodeMirror-line > span > span::selection {
background: #d7d4f0;
}
.CodeMirror-line::-moz-selection,
.CodeMirror-line > span::-moz-selection,
.CodeMirror-line > span > span::-moz-selection {
background: #d7d4f0;
}
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, 0.4);
}
/* Used to force a border model for a node */
.cm-force-border {
padding-right: 0.1px;
}
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after {
content: "";
}
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext {
background: none;
}
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
.CodeMirror-hint {
margin: 0;
padding: 0 4px;
border-radius: 2px;
white-space: pre;
color: black;
cursor: pointer;
}
li.CodeMirror-hint-active {
background: #08f;
color: white;
}
.abstractIconButtonParser {position:absolute;top:0.25rem; }.abstractIconButtonParser svg {fill: rgba(204,204,204,.8);width:1.875rem;height:1.875rem; padding: 0 7px;} .abstractIconButtonParser:hover svg{fill: #333;}
.abstractIconButtonParser {position:absolute;top:0.25rem; }.abstractIconButtonParser svg {fill: rgba(204,204,204,.8);width:1.875rem;height:1.875rem; padding: 0 7px;} .abstractIconButtonParser:hover svg{fill: #333;}
Release Notes ·
Docs ·
Readme
ScrollHub is a super server for publishing websites, scientific articles, blog posts, books, and more.
It is the fastest way to publish. Don't take my word for it, try for yourself here: https://hub.scroll.pub
Run your own ScrollHub in 60 seconds
Follow the steps below to run your own ScrollHub server in 60 seconds!
- Launch a new Ubuntu Droplet on Digital Ocean (or your cloud provider of choice)
- SSH into your new server and run this oneliner:
apt install make zip && git clone https://github.com/tj/n && cd n && make install && n latest && cd && git clone https://github.com/breck7/ScrollHub && cd ScrollHub && npm install . && npm install scroll-cli pm2 prettier -g && git config --global receive.denyCurrentBranch updateInstead && pm2 start server.js --node-args="--max-old-space-size=4096" --log ~/ScrollHub/pm2.log && pm2 startup && pm2 save
Optional steps:
- Create a DNS A Record pointing from your domain or subdomain to your new server.
Torify your site with an onion domain: https://www.torproject.org/about/history/
sudo apt update && sudo apt install -y tor && echo -e "HiddenServiceDir /var/lib/tor/hiddenservice/\nHiddenServicePort 80 127.0.0.1:3000" | sudo tee -a /etc/tor/torrc && sudo systemctl restart tor && sudo cat /var/lib/tor/hiddenservice/hostname
Helpful Dev Environment Aliases
# Scroll
alias sb="scroll build"
Npm
alias x="npm run"
ScrollHub
alias hub="hub start"
Git
alias gs="git status"
alias ga="git add ."
alias gc="git commit --allow-empty-message -m ''"
alias acp="git add . && git commit --allow-empty-message -m '' && git push"
Make sure server side .gitignore includes all log and often changed files, to avoid local push conflicts.
Git Troubleshooting
ScrollHub uses git for versioning files.
If developing locally, occasionally you may run into merge conflicts.
To see the "git status" for a folder visit: https://hub.scroll.pub/status/[folderName]
It is recommended to prevent force pushes on your server with git config --system receive.denyNonFastForwards true
.
⁂
ScrollHub is public domain.