diff --git a/go.mod b/go.mod index 5e7681a..c28e641 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/stretchr/testify v1.8.1 github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300 github.com/teacat/noire v1.1.0 - github.com/wellington/go-libsass v0.9.2 github.com/yuin/goldmark v1.4.13 github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01 golang.org/x/crypto v0.6.0 diff --git a/public/style.build.css b/public/style.build.css new file mode 100644 index 0000000..f0b92b7 --- /dev/null +++ b/public/style.build.css @@ -0,0 +1,855 @@ +/* src/rawdata/scss/tachyons-vars.css */ +:root { + --sans-serif: + -apple-system, + BlinkMacSystemFont, + "avenir next", + avenir, + helvetica, + "helvetica neue", + ubuntu, + roboto, + noto, + "segoe ui", + arial, + sans-serif; + --serif: georgia, serif; + --code: + consolas, + monaco, + monospace; + --font-size-headline: 6rem; + --font-size-subheadline: 5rem; + --font-size-1: 3rem; + --font-size-2: 2.25rem; + --font-size-3: 1.5rem; + --font-size-4: 1.25rem; + --font-size-5: 1rem; + --font-size-6: .875rem; + --font-size-7: .75rem; + --letter-spacing-tight: -.05em; + --letter-spacing-1: .1em; + --letter-spacing-2: .25em; + --line-height-solid: 1; + --line-height-title: 1.25; + --line-height-copy: 1.5; + --measure: 30em; + --measure-narrow: 20em; + --measure-wide: 34em; + --spacing-none: 0; + --spacing-extra-small: .25rem; + --spacing-small: .5rem; + --spacing-medium: 1rem; + --spacing-large: 2rem; + --spacing-extra-large: 4rem; + --spacing-extra-extra-large: 8rem; + --spacing-extra-extra-extra-large: 16rem; + --spacing-copy-separator: 1.5em; + --height-1: 1rem; + --height-2: 2rem; + --height-3: 4rem; + --height-4: 8rem; + --height-5: 16rem; + --height-6: 32rem; + --width-1: 1rem; + --width-2: 2rem; + --width-3: 4rem; + --width-4: 8rem; + --width-5: 16rem; + --width-6: 32rem; + --width-7: 48rem; + --width-8: 64rem; + --max-width-1: 1rem; + --max-width-2: 2rem; + --max-width-3: 4rem; + --max-width-4: 8rem; + --max-width-5: 16rem; + --max-width-6: 32rem; + --max-width-7: 48rem; + --max-width-8: 64rem; + --max-width-9: 96rem; + --border-radius-none: 0; + --border-radius-1: .125rem; + --border-radius-2: .25rem; + --border-radius-3: .5rem; + --border-radius-4: 1rem; + --border-radius-circle: 100%; + --border-radius-pill: 9999px; + --border-width-none: 0; + --border-width-1: .125rem; + --border-width-2: .25rem; + --border-width-3: .5rem; + --border-width-4: 1rem; + --border-width-5: 2rem; + --box-shadow-1: 0px 0px 4px 2px rgba(0, 0, 0, 0.2); + --box-shadow-2: 0px 0px 8px 2px rgba(0, 0, 0, 0.2); + --box-shadow-3: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); + --box-shadow-4: 2px 2px 8px 0px rgba(0, 0, 0, 0.2); + --box-shadow-5: 4px 4px 8px 0px rgba(0, 0, 0, 0.2); + --black: #000; + --near-black: #111; + --dark-gray: #333; + --mid-gray: #555; + --gray: #777; + --silver: #999; + --light-silver: #aaa; + --moon-gray: #ccc; + --light-gray: #eee; + --near-white: #f4f4f4; + --white: #fff; + --transparent: transparent; + --black-90: rgba(0, 0, 0, .9); + --black-80: rgba(0, 0, 0, .8); + --black-70: rgba(0, 0, 0, .7); + --black-60: rgba(0, 0, 0, .6); + --black-50: rgba(0, 0, 0, .5); + --black-40: rgba(0, 0, 0, .4); + --black-30: rgba(0, 0, 0, .3); + --black-20: rgba(0, 0, 0, .2); + --black-10: rgba(0, 0, 0, .1); + --black-05: rgba(0, 0, 0, .05); + --black-025: rgba(0, 0, 0, .025); + --black-0125: rgba(0, 0, 0, .0125); + --white-90: rgba(255, 255, 255, .9); + --white-80: rgba(255, 255, 255, .8); + --white-70: rgba(255, 255, 255, .7); + --white-60: rgba(255, 255, 255, .6); + --white-50: rgba(255, 255, 255, .5); + --white-40: rgba(255, 255, 255, .4); + --white-30: rgba(255, 255, 255, .3); + --white-20: rgba(255, 255, 255, .2); + --white-10: rgba(255, 255, 255, .1); + --white-05: rgba(255, 255, 255, .05); + --white-025: rgba(255, 255, 255, .025); + --white-0125: rgba(255, 255, 255, .0125); + --dark-red: #e7040f; + --red: #ff4136; + --light-red: #ff725c; + --orange: #ff6300; + --gold: #ffb700; + --yellow: #ffd700; + --light-yellow: #fbf1a9; + --purple: #5e2ca5; + --light-purple: #a463f2; + --dark-pink: #d5008f; + --hot-pink: #ff41b4; + --pink: #ff80cc; + --light-pink: #ffa3d7; + --dark-green: #137752; + --green: #19a974; + --light-green: #9eebcf; + --navy: #001b44; + --dark-blue: #00449e; + --blue: #357edd; + --light-blue: #96ccff; + --lightest-blue: #cdecff; + --washed-blue: #f6fffe; + --washed-green: #e8fdf5; + --washed-yellow: #fffceb; + --washed-red: #ffdfdf; + --breakpoint-not-small: "screen and (min-width: 35em)"; + --breakpoint-medium: "screen and (min-width: 35em) and (max-width: 60em)"; + --breakpoint-large: "screen and (min-width: 60em)"; +} + +/* src/rawdata/scss/vars.css */ +:root { + --main-background-color: white; + --main-color: black; + --link-color: #cc3b95; + --theme-color: #666; + --theme-color-dim: #aaa; + --theme-color-dimmer: #bbb; + --theme-color-dimmest: #ccc; + --theme-color-dark: #666; + --theme-color-light: #666; +} +@media (prefers-color-scheme: dark) { + :root { + --main-background-color: #202020; + --main-color: #eee; + --link-color: #cc3b95; + --theme-color: #666; + --theme-color-dim: #444; + --theme-color-dimmer: #383838; + --theme-color-dimmest: #333; + --theme-color-dark: #666; + --theme-color-light: #666; + } +} + +/* src/rawdata/scss/base.css */ +* { + box-sizing: border-box; +} +br { + border-style: none; +} +body { + background-color: var(--main-background-color); + color: var(--main-color); + font-family: "Fira Sans", sans-serif; + min-height: 100vh; + box-sizing: border-box; +} +a, +.link { + color: var(--link-color); + border-bottom: none; + text-decoration: none; +} +a.external::after, +.link.external::after { + font-family: "icons"; + content: " 1"; + vertical-align: middle; +} +code, +.mono { + font-family: "Fira Mono", monospace; +} + +/* src/rawdata/scss/core.css */ +.margin-center { + margin-left: auto; + margin-right: auto; +} +.flex-shrink-0 { + flex-shrink: 0; +} +.flex-grow-1 { + flex-grow: 1; +} +.flex-fair { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; +} +@media screen and (min-width: 35em) { + .flex-fair-ns { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; + } +} +@media screen and (min-width: 60em) { + .flex-fair-l { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; + } +} +.c--normal { + color: var(--main-color); +} +.c--inherit { + color: inherit; +} +.c--inherit:hover, +.c--inherit:active { + color: inherit; +} +.b--theme { + border-color: var(--theme-color); +} +.c--dim { + color: var(--dim-color); +} +.c--theme-dim { + color: var(--theme-color-dim); +} +.b--dim { + border-color: var(--dim-color); +} +.b--theme-dim { + border-color: var(--theme-color-dim); +} +.c--dimmer { + color: var(--dimmer-color); +} +.c--theme-dimmer { + color: var(--theme-color-dimmer); +} +.b--dimmer { + border-color: var(--dimmer-color); +} +.b--theme-dimmer { + border-color: var(--theme-color-dimmer); +} +.c--dimmest { + color: var(--dimmest-color); +} +.c--theme-dimmest { + color: var(--theme-color-dimmest); +} +.b--dimmest { + border-color: var(--dimmest-color); +} +.b--theme-dimmest { + border-color: var(--theme-color-dimmest); +} +.bg--dim { + background-color: var(--dim-background); +} +.bg--content { + background-color: var(--content-background); +} +.bg--card { + background-color: var(--card-background); +} +.f8 { + font-size: 0.65rem; +} +.mw-site { + max-width: 80rem; +} +.mh-3 { + max-height: var(--height-3); +} +.mh-4 { + max-height: var(--height-4); +} +.mh-5 { + max-height: var(--height-5); +} +.mh-6 { + max-height: var(--height-6); +} +.mh-100 { + max-height: 100%; +} +.mh-50vh { + max-height: 50vh; +} +.mh-60vh { + max-height: 60vh; +} +.mh-70vh { + max-height: 70vh; +} +.mh-80vh { + max-height: 80vh; +} +.minw-100 { + min-width: 100%; +} +.minh-1 { + min-height: var(--height-1); +} +.minh-2 { + min-height: var(--height-2); +} +.minh-3 { + min-height: var(--height-3); +} +.minh-4 { + min-height: var(--height-4); +} +.minh-5 { + min-height: var(--height-5); +} +.minh-6 { + min-height: var(--height-6); +} +.h1-5 { + height: 1.5rem; +} +.fira { + font-family: "Fira Sans", sans-serif; +} +.bi-avoid { + break-inside: avoid; +} +.cc-auto { + column-count: auto; +} +.cc1 { + column-count: 1; +} +.cc2 { + column-count: 2; +} +.cc3 { + column-count: 3; +} +.cg0 { + column-gap: var(--spacing-none); +} +.cg1 { + column-gap: var(--spacing-extra-small); +} +.cg2 { + column-gap: var(--spacing-small); +} +.cg3 { + column-gap: var(--spacing-medium); +} +.cg4 { + column-gap: var(--spacing-large); +} +.cg5 { + column-gap: var(--spacing-extra-large); +} +.g0 { + gap: var(--spacing-none); +} +.g1 { + gap: var(--spacing-extra-small); +} +.g2 { + gap: var(--spacing-small); +} +.g3 { + gap: var(--spacing-medium); +} +.g4 { + gap: var(--spacing-large); +} +.g5 { + gap: var(--spacing-extra-large); +} +.grid { + display: grid; +} +.grid-1 { + grid-template-columns: 1fr; +} +.grid-2 { + grid-template-columns: 1fr 1fr; +} +.aspect-ratio--2x1 { + padding-bottom: 50%; +} +.hide-if-empty:empty { + display: none !important; +} +@media screen and (min-width: 35em) { + .bi-avoid-ns { + break-inside: avoid; + } + .cc-auto-ns { + column-count: auto; + } + .cc1-ns { + column-count: 1; + } + .cc2-ns { + column-count: 2; + } + .cc3-ns { + column-count: 3; + } + .cg0-ns { + column-gap: var(--spacing-none); + } + .cg1-ns { + column-gap: var(--spacing-extra-small); + } + .cg2-ns { + column-gap: var(--spacing-small); + } + .cg3-ns { + column-gap: var(--spacing-medium); + } + .cg4-ns { + column-gap: var(--spacing-large); + } + .cg5-ns { + column-gap: var(--spacing-extra-large); + } + .grid-1-ns { + grid-template-columns: 1fr; + } + .grid-2-ns { + grid-template-columns: 1fr 1fr; + } + .bg--dim-ns { + background-color: var(--dim-background); + } +} +@media screen and (min-width: 35em) and (max-width: 60em) { + .bi-avoid-m { + break-inside: avoid; + } + .cc-auto-m { + column-count: auto; + } + .cc1-m { + column-count: 1; + } + .cc2-m { + column-count: 2; + } + .cc3-m { + column-count: 3; + } + .cg1-m { + column-gap: var(--spacing-extra-small); + } + .cg2-m { + column-gap: var(--spacing-small); + } + .cg3-m { + column-gap: var(--spacing-medium); + } + .cg4-m { + column-gap: var(--spacing-large); + } + .cg5-m { + column-gap: var(--spacing-extra-large); + } + .grid-1-m { + grid-template-columns: 1fr; + } + .grid-2-m { + grid-template-columns: 1fr 1fr; + } + .bg--dim-m { + background-color: var(--dim-background); + } +} +@media screen and (min-width: 60em) { + .bi-avoid-l { + break-inside: avoid; + } + .cc-auto-l { + column-count: auto; + } + .cc1-l { + column-count: 1; + } + .cc2-l { + column-count: 2; + } + .cc3-l { + column-count: 3; + } + .cg1-l { + column-gap: var(--spacing-extra-small); + } + .cg2-l { + column-gap: var(--spacing-small); + } + .cg3-l { + column-gap: var(--spacing-medium); + } + .cg4-l { + column-gap: var(--spacing-large); + } + .cg5-l { + column-gap: var(--spacing-extra-large); + } + .grid-1-l { + grid-template-columns: 1fr; + } + .grid-2-l { + grid-template-columns: 1fr 1fr; + } + .bg--dim-l { + background-color: var(--dim-background); + } +} +.not-first:first-child { + display: none; +} +.not-first-of-type:first-of-type { + display: none; +} +.not-last:last-child { + display: none; +} +.not-last-of-type:last-of-type { + display: none; +} +.svgicon svg { + fill: currentColor; + stroke: currentColor; + width: 1em; + height: 1em; +} +.svgicon:not(.svgicon-nofix) svg { + transform: translate(0px, 0.1em); +} +.center-layout { + margin-right: auto; + margin-left: auto; +} +footer .list li:not(:last-child)::after { + @extend .c--dimmer; + { + & { + content: " / "; + } + } +} +@media # { + { + var(--breakpoint-not-small); + } +} +.content { + background-color: var(--content-background); + margin: auto; +} +.content p { + -moz-text-size-adjust: auto; + -webkit-text-size-adjust: auto; + text-size-adjust: auto; + margin: 0.6rem 0; +} +.content .description { + line-height: 1.42em; + text-align: left; + margin: auto; +} +.content .description p { + margin-bottom: var(--spacing-small); + text-align: left; +} +.content > .top-bar { + text-align: left; +} +.content-block { + // TODO: What the heck are these styles background-repeat: repeat-x; + border-radius: 2px; + text-align: left; + width: 100%; + position: relative; + box-sizing: border-box; +} +.content-block.top-bar { + background-image: none; +} +.content-block.language-desc { + padding: 10px; +} +.content-block.language-desc h3 { + margin-left: 10px; +} +.content-block .no-bg { + background-image: none; + background-color: transparent; + box-shadow: none; +} +.sidebar .content-block.single { + padding: 0px; + margin-top: 20px; +} +.sidebar .content-block.top-bar { + width: 80%; + display: block; + margin: 10px auto; +} +.sidebar br.sidebar-filler { + line-height: 20px; +} +.sidebar .projectlist { + background-color: transparent; +} +.content-block .bottom-padding, +.sidebar .bottom-padding { + margin-top: var(--spacing-medium); +} +.breadcrumb:hover { + text-decoration: underline; +} +.breadcrumb.current { + text-overflow: clip ellipsis; +} +.breadcrumb-before:nth-of-type(n+2)::before { + content: "\226b"; +} +.optionbar { + @extend .b--dimmest; + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + text-align: center; + align-items: center; + border-style: dashed; + border-width: 0px; + border-bottom-width: 1px; + padding-bottom: var(--spacing-small); + { + flex-direction: row; + text-align: left; + padding-bottom: 0; + } +} +@media # { + .optionbar { + var(--breakpoint-not-small); + } +} +.optionbar.bottom { + border-bottom-width: 0px; + border-top-width: 1px; + padding-bottom: 0; + padding-top: var(--spacing-small); + { + padding-top: 0; + } +} +@media # { + .optionbar.bottom { + var(--breakpoint-not-small); + } +} +.optionbar.center { + text-align: center; + // TODO: find this and kill it; +} +.optionbar .options { + display: flex; + flex-direction: column; + { + flex-direction: row; + } +} +@media # { + .optionbar .options { + var(--breakpoint-not-small); + } +} +.optionbar .options { + # { + var(--buttons); + } + { + @include lite-button; + @extend .ph2; + @extend .pv1; + @extend .pv2-ns; + } +} +.optionbar .group { + display: inline-block; + height: 100%; + margin: auto; +} +.tab { + background-color: var(--tab-background); + @extend .pa2; +} +.tab-bar { + border-color: var(--tab-border-color); + @extend .flex, .flex-row; + width: 100%; +} +.tab-bar .tab-button { + background-color: var(--tab-button-background); + border-color: var(--tab-border-color); + @extend .ph3, .pv2; + cursor: pointer; + // TODO: Should this be a link? &:hover { + background-color: var(--tab-button-background-hover); + } +} +.tab-bar .tab-button.current { + background-color: var(--tab-button-background-current); + font-weight: 500; +} +.pagination .page.current { + cursor: default; + font-weight: 600; +} +.pagination .page.current:hover { + text-decoration: none; +} +.pagination .button { + @extend .pv0, .ph2; +} +.user-link { + position: relative; +} +// TODO(ben): It appears that this code is inactive because the JS that would // create the popups is commented out. .user-popup { + opacity: 0; + max-height: 0px; + width: 340px; + text-align: center; + transition: max-height 0.2s, opacity 0.1s; + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3); + overflow: hidden; + position: absolute; + bottom: 0px; + &.expanded { + visibility: visible; + max-height: 250px; + opacity: 1; + } + table { + width: 100%; + position: relative; + border-radius: 3px; + z-index: 10; + } + td { + vertical-align: top; + padding: 15px 9px; + } + #avatar { + width: 100px; + height: 100px; + background-size: contain; + background-position: center center; + background-repeat: no-repeat; + border-radius: 3px; + margin: 0px auto; + } + .username { + font-weight: bold; + } + .bottom { + border-top: 1px solid transparent; + padding: 15px; + .bio { + vertical-align: top; + width: 90%; + } + } +} +.site-search[type=text].lite { + // wow CSS selector priority sucks // First transition copied from input .lite transition: border-bottom-color 60ms ease-in-out, width 300ms ease; +} +#search_button_homepage { + margin: 0px; + height: 100%; + height: calc(100% - 2px); + border-radius: 0px; + display: inline-block; + display: none; +} +.background-even:nth-of-type(even) { + // this is the default, and should be overridden by dynamic colors. background-color: var(--background-even-background); + --fade-color: var(--background-even-background); +} +.sr-only { + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + word-wrap: normal !important; + transition: 0.2s all; +} +.sr-focusable { + @extend .sr-only; +} +.sr-focusable:focus { + padding: 15px 10px; + height: auto; + width: auto; + background: var(--content-background); + clip: initial; + -webkit-clip-path: initial; + clip-path: initial; + z-index: 99999; +} + +/* src/rawdata/scss/style.css */ diff --git a/src/buildscss/buildscss.go b/src/buildscss/buildscss.go index 884354c..006f106 100644 --- a/src/buildscss/buildscss.go +++ b/src/buildscss/buildscss.go @@ -1,18 +1,6 @@ package buildscss -import ( - "context" - "encoding/base64" - "fmt" - "os" - "path/filepath" - - color "git.handmade.network/hmn/hmn/src/ansicolor" - "git.handmade.network/hmn/hmn/src/oops" - "git.handmade.network/hmn/hmn/src/website" - "github.com/spf13/cobra" - "github.com/wellington/go-libsass" -) +/* var compressed bool @@ -93,3 +81,5 @@ func compile(inpath, outpath string, theme string, style int) error { return compiler.Run() } + +*/ diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index a057ba5..f72cb40 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -635,6 +635,12 @@ func BuildEducationRerender() string { return Url("/education/rerender", nil) } +/* + * Style test + */ + +var RegexStyleTest = regexp.MustCompile(`^/debug/styles$`) + /* * Forums */ diff --git a/src/rawdata/scss/base.css b/src/rawdata/scss/base.css new file mode 100644 index 0000000..391b919 --- /dev/null +++ b/src/rawdata/scss/base.css @@ -0,0 +1,34 @@ +* { + box-sizing: border-box; +} + +br { + /* why, IE... */ + border-style: none; +} + +body { + background-color: var(--main-background-color); + color: var(--main-color); + font-family: "Fira Sans", sans-serif; + min-height: 100vh; + box-sizing: border-box; +} + +a, +.link { + color: var(--link-color); + border-bottom: none; + text-decoration: none; + + &.external::after { + font-family: "icons"; + content: " 1"; + vertical-align: middle; + } +} + +code, +.mono { + font-family: "Fira Mono", monospace; +} \ No newline at end of file diff --git a/src/rawdata/scss/core.css b/src/rawdata/scss/core.css new file mode 100644 index 0000000..c4d5e50 --- /dev/null +++ b/src/rawdata/scss/core.css @@ -0,0 +1,819 @@ +.margin-center { + margin-left: auto; + margin-right: auto; +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-grow-1 { + flex-grow: 1; +} + +.flex-fair { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; +} + +@media screen and (min-width: 35em) { + .flex-fair-ns { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; + } +} + +@media screen and (min-width: 60em) { + .flex-fair-l { + flex-basis: 1px; + flex-grow: 1; + flex-shrink: 1; + } +} + +.c--normal { + color: var(--main-color); +} + +.c--inherit { + color: inherit; + + &:hover, + &:active { + color: inherit; + } +} + +.b--theme { + border-color: var(--theme-color); +} + +.c--dim { + color: var(--dim-color); +} + +.c--theme-dim { + color: var(--theme-color-dim); +} + +.b--dim { + border-color: var(--dim-color); +} + +.b--theme-dim { + border-color: var(--theme-color-dim); +} + +.c--dimmer { + color: var(--dimmer-color); +} + +.c--theme-dimmer { + color: var(--theme-color-dimmer); +} + +.b--dimmer { + border-color: var(--dimmer-color); +} + +.b--theme-dimmer { + border-color: var(--theme-color-dimmer); +} + +.c--dimmest { + color: var(--dimmest-color); +} + +.c--theme-dimmest { + color: var(--theme-color-dimmest); +} + +.b--dimmest { + border-color: var(--dimmest-color); +} + +.b--theme-dimmest { + border-color: var(--theme-color-dimmest); +} + +.bg--dim { + background-color: var(--dim-background); +} + +.bg--content { + background-color: var(--content-background); +} + +.bg--card { + background-color: var(--card-background); +} + +.f8 { + font-size: 0.65rem; +} + +.mw-site { + max-width: 80rem; +} + +.mh-3 { + max-height: var(--height-3); +} + +.mh-4 { + max-height: var(--height-4); +} + +.mh-5 { + max-height: var(--height-5); +} + +.mh-6 { + max-height: var(--height-6); +} + +.mh-100 { + max-height: 100%; +} + +.mh-50vh { + max-height: 50vh; +} + +.mh-60vh { + max-height: 60vh; +} + +.mh-70vh { + max-height: 70vh; +} + +.mh-80vh { + max-height: 80vh; +} + +.minw-100 { + min-width: 100%; +} + +.minh-1 { + min-height: var(--height-1); +} + +.minh-2 { + min-height: var(--height-2); +} + +.minh-3 { + min-height: var(--height-3); +} + +.minh-4 { + min-height: var(--height-4); +} + +.minh-5 { + min-height: var(--height-5); +} + +.minh-6 { + min-height: var(--height-6); +} + +.h1-5 { + height: 1.5rem; +} + +.fira { + font-family: "Fira Sans", sans-serif; +} + +.bi-avoid { + break-inside: avoid; +} + +.cc-auto { + column-count: auto; +} + +.cc1 { + column-count: 1; +} + +.cc2 { + column-count: 2; +} + +.cc3 { + column-count: 3; +} + +.cg0 { + column-gap: var(--spacing-none); +} + +.cg1 { + column-gap: var(--spacing-extra-small); +} + +.cg2 { + column-gap: var(--spacing-small); +} + +.cg3 { + column-gap: var(--spacing-medium); +} + +.cg4 { + column-gap: var(--spacing-large); +} + +.cg5 { + column-gap: var(--spacing-extra-large); +} + +.g0 { + gap: var(--spacing-none); +} + +.g1 { + gap: var(--spacing-extra-small); +} + +.g2 { + gap: var(--spacing-small); +} + +.g3 { + gap: var(--spacing-medium); +} + +.g4 { + gap: var(--spacing-large); +} + +.g5 { + gap: var(--spacing-extra-large); +} + +.grid { + display: grid; +} + +.grid-1 { + grid-template-columns: 1fr; +} + +.grid-2 { + grid-template-columns: 1fr 1fr; +} + +.aspect-ratio--2x1 { + padding-bottom: 50%; +} + +.hide-if-empty:empty { + display: none !important; +} + +@media screen and (min-width: 35em) { + .bi-avoid-ns { + break-inside: avoid; + } + + .cc-auto-ns { + column-count: auto; + } + + .cc1-ns { + column-count: 1; + } + + .cc2-ns { + column-count: 2; + } + + .cc3-ns { + column-count: 3; + } + + .cg0-ns { + column-gap: var(--spacing-none); + } + + .cg1-ns { + column-gap: var(--spacing-extra-small); + } + + .cg2-ns { + column-gap: var(--spacing-small); + } + + .cg3-ns { + column-gap: var(--spacing-medium); + } + + .cg4-ns { + column-gap: var(--spacing-large); + } + + .cg5-ns { + column-gap: var(--spacing-extra-large); + } + + .grid-1-ns { + grid-template-columns: 1fr; + } + + .grid-2-ns { + grid-template-columns: 1fr 1fr; + } + + .bg--dim-ns { + background-color: var(--dim-background); + } +} + +@media screen and (min-width: 35em) and (max-width: 60em) { + .bi-avoid-m { + break-inside: avoid; + } + + .cc-auto-m { + column-count: auto; + } + + .cc1-m { + column-count: 1; + } + + .cc2-m { + column-count: 2; + } + + .cc3-m { + column-count: 3; + } + + .cg1-m { + column-gap: var(--spacing-extra-small); + } + + .cg2-m { + column-gap: var(--spacing-small); + } + + .cg3-m { + column-gap: var(--spacing-medium); + } + + .cg4-m { + column-gap: var(--spacing-large); + } + + .cg5-m { + column-gap: var(--spacing-extra-large); + } + + .grid-1-m { + grid-template-columns: 1fr; + } + + .grid-2-m { + grid-template-columns: 1fr 1fr; + } + + .bg--dim-m { + background-color: var(--dim-background); + } +} + +@media screen and (min-width: 60em) { + .bi-avoid-l { + break-inside: avoid; + } + + .cc-auto-l { + column-count: auto; + } + + .cc1-l { + column-count: 1; + } + + .cc2-l { + column-count: 2; + } + + .cc3-l { + column-count: 3; + } + + .cg1-l { + column-gap: var(--spacing-extra-small); + } + + .cg2-l { + column-gap: var(--spacing-small); + } + + .cg3-l { + column-gap: var(--spacing-medium); + } + + .cg4-l { + column-gap: var(--spacing-large); + } + + .cg5-l { + column-gap: var(--spacing-extra-large); + } + + .grid-1-l { + grid-template-columns: 1fr; + } + + .grid-2-l { + grid-template-columns: 1fr 1fr; + } + + .bg--dim-l { + background-color: var(--dim-background); + } +} + +.not-first:first-child { + display: none; +} + +.not-first-of-type:first-of-type { + display: none; +} + +.not-last:last-child { + display: none; +} + +.not-last-of-type:last-of-type { + display: none; +} + +.svgicon { + svg { + fill: currentColor; + stroke: currentColor; + width: 1em; + height: 1em; + } + + &:not(.svgicon-nofix) svg { + transform: translate(0px, 0.1em); + } +} + +/* +Tachyons' `center` is unfortunately overloaded by a .center +class we have in our own CSS. +*/ +.center-layout { + margin-right: auto; + margin-left: auto; +} + +footer { + .list li:not(:last-child)::after { + @extend .c--dimmer; + + @media #{var(--breakpoint-not-small)} { + & { + content: ' / '; + } + } + } +} + +.content { + background-color: var(--content-background); + + margin: auto; + + p { + -moz-text-size-adjust: auto; + -webkit-text-size-adjust: auto; + text-size-adjust: auto; + + margin: 0.6rem 0; + } + + .description { + line-height: 1.42em; + text-align: left; + margin: auto; + + p { + margin-bottom: var(--spacing-small); + text-align: left; + } + } + + >.top-bar { + text-align: left; + } +} + +.content-block { + // TODO: What the heck are these styles + /* Background color given by theme */ + background-repeat: repeat-x; + border-radius: 2px; + text-align: left; + width: 100%; + /* box-shadow: 0px 4px 7px rgba(0,0,0,0.5); /* Not themed */ + position: relative; + box-sizing: border-box; + + &.top-bar { + background-image: none; + } + + &.language-desc { + padding: 10px; + + h3 { + margin-left: 10px; + } + } + + .no-bg { + background-image: none; + background-color: transparent; + box-shadow: none; + } +} + +.sidebar { + .content-block { + &.single { + padding: 0px; + /* for project list, TODO */ + margin-top: 20px; + } + + &.top-bar { + /* box-shadow: 0px 2px 4px rgba(0,0,0,0.2); /* Not themed */ + width: 80%; + display: block; + margin: 10px auto; + } + } + + br.sidebar-filler { + line-height: 20px; + } + + .projectlist { + background-color: transparent; + } +} + +.content-block .bottom-padding, +.sidebar .bottom-padding { + margin-top: var(--spacing-medium); +} + +.breadcrumb { + &:hover { + text-decoration: underline; + } + + &.current { + text-overflow: clip ellipsis; + } +} + +.breadcrumb-before:nth-of-type(n+2)::before { + content: '≫'; +} + +.optionbar { + @extend .b--dimmest; + + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + text-align: center; + align-items: center; + border-style: dashed; + border-width: 0px; + border-bottom-width: 1px; + padding-bottom: var(--spacing-small); + + @media #{var(--breakpoint-not-small)} { + flex-direction: row; + text-align: left; + padding-bottom: 0; + } + + &.bottom { + border-bottom-width: 0px; + border-top-width: 1px; + padding-bottom: 0; + padding-top: var(--spacing-small); + + @media #{var(--breakpoint-not-small)} { + padding-top: 0; + } + } + + &.center { + text-align: center; // TODO: find this and kill it + } + + .options { + display: flex; + flex-direction: column; + + @media #{var(--breakpoint-not-small)} { + flex-direction: row; + } + + & { + #{var(--buttons)} { + @include lite-button; + @extend .ph2; + @extend .pv1; + @extend .pv2-ns; + } + } + } + + .group { + display: inline-block; + height: 100%; + margin: auto; + } +} + +.tab { + background-color: var(--tab-background); + @extend .pa2; +} + +.tab-bar { + border-color: var(--tab-border-color); + @extend .flex, .flex-row; + + width: 100%; + + .tab-button { + background-color: var(--tab-button-background); + border-color: var(--tab-border-color); + @extend .ph3, .pv2; + + cursor: pointer; // TODO: Should this be a link? + + &:hover { + background-color: var(--tab-button-background-hover); + } + + &.current { + background-color: var(--tab-button-background-current); + font-weight: 500; + } + } +} + +.pagination { + .page.current { + cursor: default; + font-weight: 600; + + &:hover { + text-decoration: none; + } + } + + .button { + @extend .pv0, .ph2; + } +} + +.user-link { + position: relative; +} + +// TODO(ben): It appears that this code is inactive because the JS that would +// create the popups is commented out. +.user-popup { + opacity: 0; + max-height: 0px; + width: 340px; + + text-align: center; + + transition: max-height 0.2s, opacity 0.1s; + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3); + + overflow: hidden; + position: absolute; + bottom: 0px; + + &.expanded { + visibility: visible; + max-height: 250px; + opacity: 1; + } + + table { + /* Background color given by theme */ + width: 100%; + position: relative; + border-radius: 3px; + z-index: 10; + } + + td { + vertical-align: top; + padding: 15px 9px; + } + + #avatar { + width: 100px; + height: 100px; + background-size: contain; + background-position: center center; + background-repeat: no-repeat; + border-radius: 3px; + margin: 0px auto; + } + + .username { + font-weight: bold; + } + + .bottom { + /* Border color given by theme */ + border-top: 1px solid transparent; + padding: 15px; + + .bio { + vertical-align: top; + width: 90%; + } + } +} + +.site-search { + &[type=text].lite { + // wow CSS selector priority sucks + + // First transition copied from input .lite + transition: border-bottom-color 60ms ease-in-out, width 300ms ease; + } +} + +#search_button_homepage { + margin: 0px; + height: 100%; + height: calc(100% - 2px); + border-radius: 0px; + display: inline-block; + display: none; +} + +.background-even:nth-of-type(even) { + // this is the default, and should be overridden by dynamic colors. + background-color: var(--background-even-background); + --fade-color: var(--background-even-background); +} + +.sr-only { + border: 0; + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + word-wrap: normal !important; + transition: 0.2s all; +} + +.sr-focusable { + @extend .sr-only; + + &:focus { + padding: 15px 10px; + height: auto; + width: auto; + background: var(--content-background); + clip: initial; + clip-path: initial; + z-index: 99999; + } +} \ No newline at end of file diff --git a/src/rawdata/scss/style.css b/src/rawdata/scss/style.css new file mode 100644 index 0000000..6c29ed3 --- /dev/null +++ b/src/rawdata/scss/style.css @@ -0,0 +1,4 @@ +@import "vars.css"; +@import "base.css"; + +@import "core.css"; \ No newline at end of file diff --git a/src/rawdata/scss/tachyons-vars.css b/src/rawdata/scss/tachyons-vars.css new file mode 100644 index 0000000..d2f5caf --- /dev/null +++ b/src/rawdata/scss/tachyons-vars.css @@ -0,0 +1,140 @@ +/* Variables copied from tachyons/variables.scss and adapted to CSS variables. */ + +:root { + --sans-serif: -apple-system, BlinkMacSystemFont, 'avenir next', avenir, helvetica, 'helvetica neue', ubuntu, roboto, noto, 'segoe ui', arial, sans-serif; + --serif: georgia, serif; + --code: consolas, monaco, monospace; + --font-size-headline: 6rem; + --font-size-subheadline: 5rem; + --font-size-1: 3rem; + --font-size-2: 2.25rem; + --font-size-3: 1.5rem; + --font-size-4: 1.25rem; + --font-size-5: 1rem; + --font-size-6: .875rem; + --font-size-7: .75rem; + --letter-spacing-tight: -.05em; + --letter-spacing-1: .1em; + --letter-spacing-2: .25em; + --line-height-solid: 1; + --line-height-title: 1.25; + --line-height-copy: 1.5; + --measure: 30em; + --measure-narrow: 20em; + --measure-wide: 34em; + --spacing-none: 0; + --spacing-extra-small: .25rem; + --spacing-small: .5rem; + --spacing-medium: 1rem; + --spacing-large: 2rem; + --spacing-extra-large: 4rem; + --spacing-extra-extra-large: 8rem; + --spacing-extra-extra-extra-large: 16rem; + --spacing-copy-separator: 1.5em; + --height-1: 1rem; + --height-2: 2rem; + --height-3: 4rem; + --height-4: 8rem; + --height-5: 16rem; + --height-6: 32rem; + --width-1: 1rem; + --width-2: 2rem; + --width-3: 4rem; + --width-4: 8rem; + --width-5: 16rem; + --width-6: 32rem; + --width-7: 48rem; + --width-8: 64rem; + --max-width-1: 1rem; + --max-width-2: 2rem; + --max-width-3: 4rem; + --max-width-4: 8rem; + --max-width-5: 16rem; + --max-width-6: 32rem; + --max-width-7: 48rem; + --max-width-8: 64rem; + --max-width-9: 96rem; + --border-radius-none: 0; + --border-radius-1: .125rem; + --border-radius-2: .25rem; + --border-radius-3: .5rem; + --border-radius-4: 1rem; + --border-radius-circle: 100%; + --border-radius-pill: 9999px; + --border-width-none: 0; + --border-width-1: .125rem; + --border-width-2: .25rem; + --border-width-3: .5rem; + --border-width-4: 1rem; + --border-width-5: 2rem; + --box-shadow-1: 0px 0px 4px 2px rgba(0, 0, 0, 0.2); + --box-shadow-2: 0px 0px 8px 2px rgba(0, 0, 0, 0.2); + --box-shadow-3: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); + --box-shadow-4: 2px 2px 8px 0px rgba(0, 0, 0, 0.2); + --box-shadow-5: 4px 4px 8px 0px rgba(0, 0, 0, 0.2); + --black: #000; + --near-black: #111; + --dark-gray: #333; + --mid-gray: #555; + --gray: #777; + --silver: #999; + --light-silver: #aaa; + --moon-gray: #ccc; + --light-gray: #eee; + --near-white: #f4f4f4; + --white: #fff; + --transparent: transparent; + --black-90: rgba(0, 0, 0, .9); + --black-80: rgba(0, 0, 0, .8); + --black-70: rgba(0, 0, 0, .7); + --black-60: rgba(0, 0, 0, .6); + --black-50: rgba(0, 0, 0, .5); + --black-40: rgba(0, 0, 0, .4); + --black-30: rgba(0, 0, 0, .3); + --black-20: rgba(0, 0, 0, .2); + --black-10: rgba(0, 0, 0, .1); + --black-05: rgba(0, 0, 0, .05); + --black-025: rgba(0, 0, 0, .025); + --black-0125: rgba(0, 0, 0, .0125); + --white-90: rgba(255, 255, 255, .9); + --white-80: rgba(255, 255, 255, .8); + --white-70: rgba(255, 255, 255, .7); + --white-60: rgba(255, 255, 255, .6); + --white-50: rgba(255, 255, 255, .5); + --white-40: rgba(255, 255, 255, .4); + --white-30: rgba(255, 255, 255, .3); + --white-20: rgba(255, 255, 255, .2); + --white-10: rgba(255, 255, 255, .1); + --white-05: rgba(255, 255, 255, .05); + --white-025: rgba(255, 255, 255, .025); + --white-0125: rgba(255, 255, 255, .0125); + --dark-red: #e7040f; + --red: #ff4136; + --light-red: #ff725c; + --orange: #ff6300; + --gold: #ffb700; + --yellow: #ffd700; + --light-yellow: #fbf1a9; + --purple: #5e2ca5; + --light-purple: #a463f2; + --dark-pink: #d5008f; + --hot-pink: #ff41b4; + --pink: #ff80cc; + --light-pink: #ffa3d7; + --dark-green: #137752; + --green: #19a974; + --light-green: #9eebcf; + --navy: #001b44; + --dark-blue: #00449e; + --blue: #357edd; + --light-blue: #96ccff; + --lightest-blue: #cdecff; + --washed-blue: #f6fffe; + --washed-green: #e8fdf5; + --washed-yellow: #fffceb; + --washed-red: #ffdfdf; + + --breakpoint-not-small: 'screen and (min-width: 35em)'; + --breakpoint-medium: 'screen and (min-width: 35em) and (max-width: 60em)'; + --breakpoint-large: 'screen and (min-width: 60em)'; +} \ No newline at end of file diff --git a/src/rawdata/scss/vars.css b/src/rawdata/scss/vars.css new file mode 100644 index 0000000..0b32c69 --- /dev/null +++ b/src/rawdata/scss/vars.css @@ -0,0 +1,40 @@ +/* +Media queries cannot have variables, so here are media queries you can copy-paste as necessary: + +$breakpoint-not-small: screen and (min-width: 35em) +$breakpoint-medium: screen and (min-width: 35em) and (max-width: 60em) +$breakpoint-large: screen and (min-width: 60em) +*/ + +@import "tachyons-vars.css"; + +:root { + --main-background-color: white; + --main-color: black; + --link-color: #cc3b95; + + /* Default theme colors in case the project.css is busted */ + --theme-color: #666; + --theme-color-dim: #aaa; + --theme-color-dimmer: #bbb; + --theme-color-dimmest: #ccc; + + --theme-color-dark: #666; + --theme-color-light: #666; +} + +@media (prefers-color-scheme: dark) { + :root { + --main-background-color: #202020; + --main-color: #eee; + --link-color: #cc3b95; + + --theme-color: #666; + --theme-color-dim: #444; + --theme-color-dimmer: #383838; + --theme-color-dimmest: #333; + + --theme-color-dark: #666; + --theme-color-light: #666; + } +} \ No newline at end of file diff --git a/src/templates/src/style_test.html b/src/templates/src/style_test.html new file mode 100644 index 0000000..dbfe52a --- /dev/null +++ b/src/templates/src/style_test.html @@ -0,0 +1,75 @@ + + + + Style test + + + + + + +

Base style test

+ +

+ This page demonstrates the baseline styles for the HMN website. +

+

+ These styles intentionally do not affect layout, only text appearance, colors, etc. We do this because mixing layout and themeing in CSS is a bad idea. Modifying "layout" properties like margin and padding in your base styles makes it hard to ever use those tags across your site, and leads to lots of padding: 0 !important; overrides across your site. +

+

+ This does not produce good-looking longform text, like you want in forum posts or articles. This is the purpose of the .post-content class, which opts into layout properties that are good for textual content. +

+ +

Text & links

+ Text outside paragraphs looks like this. +

+ Text can be strong and bold, emphasized and italic. +

+

+ The Handmade Network started as a simple forum site for fans of Handmade Hero. +

+ +

Lists

+

+ Lists are really not used outside of post-content, but we can at least ensure that the bullets render the way we want. +

+
    +
  1. Ordered lists use numbers, obviously.
  2. +
  3. What else would they do?
  4. +
  5. It is the only sensible option.
  6. +
+

+ The layout of lists obviously looks kind of bad, but again, we are not worried about that here. Better to leave the styles alone so we can more easily disable them in contexts like navigation. +

+ + +

Monospace

+

+ This is a website for programmers, after all. +

+

+ Inline code in a paragraph looks like printf("Hello, world!");. +

+

+ A block of code looks like: +

+
#include <stdio.h>
+
+int main() {
+    printf("Hello, world!\n");
+}
+
+

+ The same block of code in a paragraph looks different. Browsers are fun. +

+

#include <stdio.h>
+
+int main() {
+    printf("Hello, world!\n");
+}
+

+ diff --git a/src/website/debug.go b/src/website/debug.go new file mode 100644 index 0000000..3a20649 --- /dev/null +++ b/src/website/debug.go @@ -0,0 +1,7 @@ +package website + +func StyleTest(c *RequestContext) ResponseData { + var res ResponseData + res.MustWriteTemplate("style_test.html", nil, c.Perf) + return res +} diff --git a/src/website/routes.go b/src/website/routes.go index 76bad97..cb80116 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -155,6 +155,8 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { hmnOnly.GET(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(EducationArticleDelete)) hmnOnly.POST(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(csrfMiddleware(EducationArticleDeleteSubmit))) + hmnOnly.GET(hmnurl.RegexStyleTest, StyleTest) + hmnOnly.POST(hmnurl.RegexAPICheckUsername, csrfMiddleware(APICheckUsername)) hmnOnly.GET(hmnurl.RegexLibraryAny, func(c *RequestContext) ResponseData { diff --git a/todo-styles.md b/todo-styles.md new file mode 100644 index 0000000..efcbda9 --- /dev/null +++ b/todo-styles.md @@ -0,0 +1,17 @@ +Styling TODO + +- [ ] Fix spacing of podcast episodes (used to use p-spaced) +- [x] Audit uses of tables across the site to see where we might actually need to apply table-layout: fixed and border-collapse: collapse + - There are zero tables on the site except one used for Asaf's debugging. +- [ ] Recover
styles and use them only in post-content +- [ ] Audit and fix all uses of: + - [ ] big + - [ ] title + - [x] clear + - [x] full + - [ ] hidden + - [x] empty (?!) + - [x] column +- [ ] Re-evaluate form styles + - [ ] theme-color-light is used only for buttons +- [ ] center-layout vs. margin-center