/* Lay out the main containers. */ body { --top-min-spacing: 40px; margin: 0; display: grid; grid-template-columns: [left] minmax( 0, clamp(80px, calc(100vw - (1920px - 360px - 160px)), 160px) ) [center] minmax(0, auto) [right] minmax(0, calc(100vw - (1920px - 360px))); grid-template-rows: [top] minmax( clamp( var(--top-min-spacing), calc(100vw - (1920px - 360px - 160px)), 128px ), min-content ) [title] minmax(9.6rem, min-content) [main] 1fr [bottom] min-content; } html { /* Try to always leave a bunch of empty space at the bottom, but don't overdo it. It's kind of awkward when you scroll to the bottom and your page just turns blank. */ --virtual-space-ratio: 1.75; height: calc(100% * var(--virtual-space-ratio)); } body { min-height: calc(100% / var(--virtual-space-ratio)); } .noscript { grid-row: top; grid-column: center; } #nav-logo { grid-row: title; grid-column: left; align-self: center; justify-self: end; } section.page-header { grid-row: title; grid-column: center; align-self: center; } main { grid-row: main; grid-column: center / center; margin-right: 0.8rem; } footer { grid-row: bottom; grid-column: center / center; } @media (max-width: 1200px) { main { grid-column: left / -1; } footer { grid-column: 1 / -1; } } @media (max-width: 450px) { body { --top-min-spacing: 0px; } section.page-header { grid-column: 1 / -1; } nav#nav-logo { display: none; } } /* Choose more pretty colors than vanilla HTML */ body { background-color: var(--background-color); color: var(--text-color); } :root { scrollbar-color: var(--border-2) var(--shaded-background); scrollbar-width: auto; scrollbar-gutter: stable; } :focus-visible { outline: 0.1rem solid var(--liquidex-brand-blue); outline-offset: 0.2rem; } /* Set up typography */ @font-face { font-family: "RecVar"; /* NOTE: I put the hash in here manually instead of adding the complexity of piping CSS through Handlebars because I don't really think it's worth it for this single asset. Other assets are referenced rarely enough that caching probably isn't gonna make too much of an impact. It's unlikely I'll ever update the font anyways, so eh, whatever. */ src: url("../font/Recursive_VF_1.085.woff2?v=b3-445487d5"); } @font-face { font-family: "RecVarMono"; src: url("../font/Recursive_VF_1.085.woff2?v=b3-445487d5"); font-variation-settings: "MONO" 1; } body, pre, code, kbd, button, select, input, dfn { font-family: "RecVar", sans-serif; font-style: normal; line-height: 1.5; } html { font-size: 62.5%; } body { font-size: 1.4rem; } pre, code, kbd, button, select, input { font-size: inherit; } :root { --recursive-mono: 0; --recursive-casl: 1; --recursive-wght: 400; --recursive-slnt: 0; --recursive-crsv: 0.5; --recursive-simplified-f: "ss03"; --recursive-simplified-g: "ss04"; --recursive-simplified-l: "ss05"; --recursive-simplified-r: "ss06"; --recursive-no-serif-L-Z: "ss08"; } *, *:before, *:after { font-variation-settings: "MONO" var(--recursive-mono), "CASL" var(--recursive-casl), "wght" var(--recursive-wght), "slnt" var(--recursive-slnt), "CRSV" var(--recursive-crsv); font-feature-settings: var(--recursive-simplified-f), var(--recursive-simplified-g), var(--recursive-simplified-l), var(--recursive-simplified-r), var(--recursive-no-serif-L-Z); } h1 { --recursive-casl: 0; --recursive-wght: 900; font-size: 5.6rem; font-feature-settings: var(--recursive-simplified-r) 0; } h2 { --recursive-casl: 0.5; --recursive-wght: 800; font-size: 3.2rem; } h3 { --recursive-casl: 0.5; --recursive-wght: 700; font-size: 2.4rem; } h4 { --recursive-casl: 0.5; --recursive-wght: 700; font-size: 1.6rem; } pre, code, kbd, th-literate-program { --recursive-mono: 1; --recursive-casl: 0; --recursive-wght: 450; } strong code { --recursive-wght: 800; } b, strong { --recursive-wght: 700; } i, em { --recursive-slnt: -16; font-style: normal; } h1, h2, h3, h4, h5, h6 { text-wrap: balance; } /* Lay out elements a bit more compactly */ p, pre { margin: 0 0; } h1, h2, h3, h4, h5, h6 { margin: 0.4rem 0; } /* Make code examples a little prettier by giving them visual separation from the rest of the page */ code, th-literate-program { padding: 0.3rem 0.4rem; background-color: var(--shaded-background); border-radius: 0.4rem; } th-literate-program, th-literate-output { display: block; } kbd { padding: 0.3rem 0.6rem; border: 0.1rem solid var(--border-1); border-radius: 0.4rem; } pre, th-literate-program { padding: 0.8rem 1.2rem; margin: 1.2rem 0; background-color: var(--shaded-background); border-radius: 0.5em; transition: background-color var(--transition-duration); } @media (prefers-color-scheme: light) { pre, th-literate-program { background-color: transparent; border: 0.1rem solid var(--border-1); } } pre > code, th-literate-program > code { padding: 0; background: none; border-radius: 0; } th-literate-program { white-space: pre; } /* And don't let code examples fly off and overflow the window */ pre, th-literate-program { min-width: 0; width: auto; overflow: auto; } /* Also don't let images get out of hand */ img { max-width: 100%; } /* Also regarding images - make them look a bit more pretty by default */ img.pic { border-radius: 0.6rem; margin: 0.8rem 0; } /* Image hints for tweaking rendering */ img { &[src*="+pixel"] { image-rendering: pixelated; border-radius: 0; } /* TODO: These could be autogenerated! */ &[src*="+width72"] { width: 7.2rem; height: auto; } &[src*="+width160"] { width: 16rem; height: auto; } &[src*="+width640"] { width: 64rem; height: auto; } &[src*="+width752"] { width: 75.2rem; height: auto; } /* Resources for use in JavaScript. */ &.resource { display: none; } } /* Fix the default blue and ugly purple links normally have */ a { color: var(--link-color); } a:visited { color: var(--link-color-visited); } /* Allow for some secret links */ a.secret { color: var(--text-color); text-decoration: none; } /* Make blockquotes a bit prettier */ blockquote { margin: 0; padding: 0.4rem 1.2rem; margin: 0.4rem 0; border-left: 0.4rem solid var(--border-1); } /* And tables. */ table { margin: 0.8rem 0; } table, th, td { border: 0.1rem solid var(--border-2); border-collapse: collapse; padding: 0.4rem 1rem; } th { background-color: var(--shaded-background); --recursive-wght: 700; --recursive-casl: 0.5; } /* Horizontal rules */ hr { width: 100%; border: none; border-top: 0.1rem solid var(--border-1); margin-top: 2em; margin-bottom: 2em; } /* Style the noscript box a little more prettily. */ .noscript { padding: 1.6rem; background-color: #fde748; color: var(--text-color-light); border: 0.1rem solid #6c581c; border-radius: 0.8rem; width: fit-content; margin-left: auto; margin-right: auto; margin-top: 1.6rem; margin-bottom: 1.6rem; } .noscript:empty { display: none; } .noscript p { margin-top: 0; margin-bottom: 1.6rem; } .noscript p:last-child { margin-bottom: 0; } .noscript a { color: var(--link-color-light); } .noscript a:visited { color: var(--link-color-visited-light); } /* Navigation button */ #nav-logo { width: min-content; height: min-content; } #nav-logo .logo { /* NOTE: Measurements in px for pixel perfection */ width: 64px; height: 64px; display: block; opacity: 100%; color: var(--text-color); } /* Navigation header (contains page title & breadcrumbs) */ h1.page-title { --recursive-wght: 850; margin-top: 0.32rem; margin-bottom: 0.32rem; margin-left: 3.6rem; font-size: 4rem; & a { color: var(--text-color); text-decoration: underline; text-decoration-color: transparent; transition: var(--transition-duration) text-decoration-color; &:hover { text-decoration-color: var(--text-color); } } } @media (hover: none) { h1.page-title a { text-decoration: underline; } } /* Style badges */ span.badge { --recursive-wght: 800; --recursive-mono: 1; --recursive-casl: 0; border-radius: 100rem; padding: 0.2rem 0.6rem; font-size: 0.9em; &.red { color: white; background-color: #d01243; } &.blue { color: white; background-color: #058ef0; } &.before-content { margin-right: 0.6rem; } } /* Style the footer */ footer { padding-left: 1.6rem; padding-right: 1.6rem; margin-top: 6.4rem; padding-bottom: 6.4rem; display: flex; flex-direction: row; & > .left { flex-grow: 1; } & > .right { flex-shrink: 0; } & #footer-icon { display: block; & > svg { display: block; color: var(--text-color); opacity: 40%; } } & #open-command-line { width: 3.2rem; height: 3.2rem; background: none; border: none; padding: 0; background-image: var(--icon-cmd); background-repeat: no-repeat; background-position: 50% 50%; opacity: 50%; transition: var(--transition-duration) opacity; &:hover { opacity: 100%; } &:active { opacity: 75%; } } } @media (hover: none) { footer > #version-info { & > ul { opacity: 100%; } } } /* Style dialogues */ dialog[open] { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); color: var(--text-color); background-color: var(--background-color); border: 0.1rem solid var(--border-1); border-radius: 1.2rem; } /* Style emojis to be readable */ img[data-cast~="emoji"] { max-width: 1.5em; max-height: 1.5em; vertical-align: bottom; object-fit: contain; } /* And also style emoji tooltips. */ th-emoji-tooltip { display: flex; flex-direction: column; align-items: center; position: fixed; transform: translateX(-50%) translateY(-10%) scale(0.8); width: max-content; z-index: 100; background-color: var(--background-color-tooltip); padding: 0.8rem; margin-top: 0.8rem; border-radius: 0.6rem; transition: opacity var(--transition-duration) cubic-bezier(0.22, 1, 0.36, 1), filter var(--transition-duration) cubic-bezier(0.22, 1, 0.36, 1), transform var(--transition-duration) cubic-bezier(0.22, 1, 0.36, 1); opacity: 0%; filter: blur(0.3rem); pointer-events: none; } th-emoji-tooltip.transitioned-in { opacity: 100%; filter: blur(0); transform: translateX(-50%) scale(1); } th-emoji-tooltip img { display: block; max-width: 7.2rem; max-height: 7.2rem; } th-emoji-tooltip p { --recursive-wght: 550; color: var(--text-color); font-size: 0.9em; margin: 0; padding-top: 0.6rem; line-height: 1; } .th-emoji-unknown { text-decoration: 0.1rem underline var(--error-color); cursor: help; } /* Command line */ th-command-line { --recursive-mono: 1; --recursive-casl: 0; display: none; flex-direction: column; background-color: var(--background-color-tooltip); font-size: 87.5%; &.visible { display: flex; position: fixed; left: 0; bottom: 0; width: 100%; } & > .input-wrapper { display: flex; flex-direction: row; align-items: center; padding: 0 0.4rem; width: 100%; &::before { content: ":"; padding-right: 0.2rem; opacity: 50%; } & > input { background: none; color: var(--text-color); border: none; flex-grow: 1; padding: 0.2rem 0; &:focus { outline: none; } } } & > ul.suggestions { list-style: none; display: flex; flex-direction: column; margin: 0; padding: 0; max-height: 25vh; overflow: auto; & > li { padding: 0.2rem 0.8rem; cursor: default; & > dfn { --recursive-crsv: 0; --recursive-wght: 700; margin-right: 2ch; } &:hover, &.tabbed { background-color: var(--liquidex-brand-blue); color: white; } &.immediate { cursor: pointer; } } } } @media (hover: none) { th-command-line { & > ul.suggestions > li { border-bottom: 0.1rem solid var(--border-1); } } } @media (pointer: coarse) { th-command-line { & > .input-wrapper > input { padding: 0.8rem 0; } & > ul.suggestions > li { padding: 0.8rem 0.8rem; } } } /* Literate programming support */ :root { --error-color: #d94141; } @media (prefers-color-scheme: dark) { :root { --error-color: #e39393; } } th-literate-program[data-mode="input"] { /* Override the cursor with an I-beam, because the editor captures clicks and does not bubble them back up to the caller */ cursor: text; } th-literate-program[data-mode="output"] { padding: 0; background: none; border: none; border-radius: 0; & iframe, & img.placeholder-image { border-style: none; border-radius: 0.4rem; display: block; } & iframe { width: 100%; } & img.placeholder-image.js { transition: opacity var(--transition-duration); } & iframe, & img.placeholder-image.loading { opacity: 50%; } & iframe.loaded { opacity: 100%; } /* The inner iframe is hidden until something requests display. */ & iframe.hidden { display: none; } & pre > code { display: block; } & pre.error { color: var(--error-color); position: relative; &:empty { display: none; } &::after { content: "Error"; padding: 0.8rem; position: absolute; right: 0; top: 0; color: var(--text-color); opacity: 50%; } } & pre.console, & pre.placeholder-console { position: relative; margin-top: 0; margin-bottom: 0; &:empty { display: none; } &::after { content: "Console"; padding: 0.8rem; position: absolute; right: 0; top: 0; color: var(--text-color); opacity: 50%; } } } /* Syntax highlighting */ :root { --syntax-comment: #9b8580; --syntax-identifier: var(--text-color); --syntax-keyword1: #e15e2b; --syntax-keyword2: #199aca; --syntax-operator: #e3755b; --syntax-function: #d57b07; --syntax-literal: #a64fb3; --syntax-string: #79ac3b; --syntax-punct: #a28680; } @media (prefers-color-scheme: dark) { :root { --syntax-comment: #aca8a4; --syntax-identifier: var(--text-color); --syntax-keyword1: #ffb06a; --syntax-keyword2: #8ad4f9; --syntax-operator: #ec9f8d; --syntax-function: #fbd283; --syntax-literal: #e9b9f0; --syntax-string: #b0dd7a; --syntax-punct: #9d9a96; } } .th-syntax-highlighting span { &.comment { --recursive-slnt: -16; color: var(--syntax-comment); } &.identifier { color: var(--syntax-identifier); } &.keyword1 { color: var(--syntax-keyword1); } &.keyword2 { color: var(--syntax-keyword2); } &.operator { color: var(--syntax-operator); } &.function { color: var(--syntax-function); } &.literal { color: var(--syntax-literal); } &.string { color: var(--syntax-string); } &.punct { color: var(--syntax-punct); } &.error { color: var(--error-color); text-decoration: wavy underline; } &.hidden { display: none; } &.type-hint { color: var(--syntax-comment); font-size: 80%; } } .th-syntax-highlighting { & .export { text-decoration: underline dotted; cursor: help; text-decoration-color: transparent; transition: text-decoration-color var(--transition-duration); } &:hover, &:focus { & .export { text-decoration-color: var(--syntax-keyword1); } } } /* Style settings sections */ section[data-cast~="settings"] { /* Don't display settings when JavaScript is disabled. JS overrides this value on the element itself. */ display: none; }