:root { --color-black: #000000; --color-white: #ffffff; --color-fog: #eeeeee; --color-parchment: #f5edeb; --color-mustard: #e5c299; --color-navy: #16323f; --color-walnut: #473a3a; --color-crimson: #803847; --color-lilac: #cabdc8; --color-lime: #c5e0af; --color-lemon: #efe2b2; --color-ale: #cd8f7a; --color-flamingo: #d2697c; --color-seaside: #a5d5c8; --color-cove: #60b3ae; --color-storm: #627088; --color-sage: #739c7e; --color-seaside-rgb: 165, 213, 200; --font-size-intro-heading: calc(var(--font-size-heading-h1) * 1.25); --font-size-intro-body: 22px; --font-size-link: 24px; --font-size-heading-h1: 48px; --font-size-heading-h2: 42px; --font-size-subheading: 24px; --font-size-body: 18px; --font-size-article-h1: 32px; --font-size-article-h2: 24px; --font-size-article-h3: 18px; --max-width: 1600px; --max-width-plus-padding: calc(var(--max-width) + 40px * 2); --variable-px: Min(1px, 0.15vw); --page-edge-padding: 40px; --border-thickness: 2px; @media screen and (max-width: 760px) { --font-size-intro-heading: 40px; --font-size-intro-body: 18px; --font-size-link: 20px; --font-size-heading-h1: 38px; --font-size-heading-h2: 36px; --font-size-body: 16px; --page-edge-padding: 28px; --border-thickness: 1px; } @media screen and (max-width: 500px) { --font-size-intro-heading: 32px; --font-size-intro-body: 16px; --font-size-link: 16px; --font-size-heading-h1: 34px; --font-size-heading-h2: 32px; --font-size-body: 16px; --page-edge-padding: 20px; } @media screen and (max-width: 400px) { --font-size-intro-heading: 24px; --font-size-intro-body: 14px; --font-size-link: 14px; --font-size-heading-h1: 28px; --font-size-heading-h2: 26px; --font-size-body: 16px; --page-edge-padding: 12px; } } // Global element styles html, body { width: 100%; height: 100%; margin: 0; background: var(--color-white); font-family: "Inter", sans-serif; line-height: 1.5; font-weight: 500; font-size: var(--font-size-body); color: var(--color-navy); tab-size: 4; } * { min-width: 0; min-height: 0; } a { color: var(--color-crimson); } h1.box-header { font-family: "Inter", sans-serif; line-height: 1.5; font-size: var(--font-size-link); font-weight: 800; text-transform: uppercase; span { white-space: pre; } ~ hr { margin-top: 20px; } + hr + * { margin-top: 40px; } } h1 { font-family: "Bona Nova", Palatino, serif; font-feature-settings: "lnum"; line-height: 1.25; font-weight: 700; font-size: var(--font-size-heading-h1); } h2 { font-family: "EB Garamond", Garamond, serif; font-feature-settings: "lnum"; line-height: 1.2; font-weight: 500; font-size: var(--font-size-heading-h2); } h3 { font-size: var(--font-size-subheading); } h1, h2, h3, h4, h5, h6 { margin: 0; display: inline-block; } p { margin: 0; -webkit-hyphens: auto; hyphens: auto; text-align: justify; } p ~ img, p ~ iframe { width: 100%; height: auto; } p ~ p { margin-top: 1.5em; } h1, h2, h3 { & ~ p, & ~ ol li p, & ~ img { margin-top: 20px; } } h1 ~ .informational-group, p ~ h1, p ~ h2, p ~ h3, p ~ details summary, p ~ blockquote, p ~ .informational-group, p ~ .image-comparison, p + .link, p ~ .video-background, p ~ .video-embed, .video-embed + p, .video-embed + .link, .video-embed + .button, img + .link { margin-top: 20px; } h1 ~ h2 { margin-top: 40px; } h1 ~ hr { margin-top: 40px; margin-bottom: 20px; } ol + p { margin-top: 0; } li + li { margin-top: 0.5em; } code { background: var(--color-fog); color: var(--color-black); padding: 0 4px; overflow-wrap: anywhere; -webkit-hyphens: none; hyphens: none; } pre { display: flex; max-width: 100%; color: var(--color-fog); // This zero transform sets this element as the root for `position: fixed` transform: translate(0); // Color overrides &, &.z-code { background: var(--color-navy); .z-path { color: #679f70; span { color: #e6e1dc; } } } // Container for the element (span or table) containing the lines of code code { background: initial; color: inherit; display: block; overflow-x: auto; padding: 20px; width: 0; flex: 1 1 auto; } // Language name in top right corner &[data-lang] { padding-top: 28px; &::before { content: attr(data-lang); color: rgba(var(--color-seaside-rgb), 0.5); text-transform: lowercase; font-family: "Inter", sans-serif; font-size: 0.75em; font-weight: bold; font-style: italic; user-select: none; pointer-events: none; position: fixed; top: 0; line-height: 28px; display: block; width: 100%; text-indent: 20px; background: rgba(0, 0, 0, 0.25); &[data-lang="sh"] { content: "Shell"; } &[data-lang="rs"] { content: "Rust"; } &[data-lang="js"] { content: "JavaScript"; } &[data-lang="ts"] { content: "TypeScript"; } } } // Code blocks with line numbers &[data-linenos] table { border-spacing: 0; margin: -20px; tr { &:first-child td { padding-top: 20px; } &:last-child td { padding-bottom: 20px; } td { &:first-child { padding-left: 20px; padding-right: 10px; user-select: none; vertical-align: top; text-align: right; background: rgba(0, 0, 0, 0.25); } &:last-child { padding-left: 10px; padding-right: 20px; } } } } } .atlas { object-fit: cover; object-position: calc(-48px * var(--atlas-index)) 0; width: 48px; height: 48px; } kbd { background: var(--color-fog); border-radius: calc(var(--variable-px) * 2); outline: calc(var(--border-thickness) / 2) solid var(--color-navy); padding: 0 4px; margin: 0 4px; color: var(--color-navy); } summary { cursor: pointer; } .reading-material.reading-material.reading-material { max-width: 800px; hr { margin-top: 40px; margin-bottom: 40px; } article { margin-top: 20px; h1, h2, h3 { font-family: "Inter", sans-serif; line-height: 1.5; font-weight: 800; } h1 { font-size: var(--font-size-article-h1); } h2 { font-size: var(--font-size-article-h2); } h3 { font-size: var(--font-size-article-h3); } h1, h2, h3, h4, h5, h6 { display: block; } } } .video-embed { position: relative; width: 100%; &.aspect-16x9 { padding-top: calc(100% / (16 / 9)); } img, iframe { position: absolute; width: 100%; height: 100%; top: 0; left: 0; } img { cursor: pointer; } } .video-background { position: relative; font-size: 0; video { max-width: Min(100%, 1280px); } // Uses a white border over the video to cover up the edges of the video which, due to a Chrome rendering bug, displays black edges sometimes when scrolling &::after { content: ""; position: absolute; inset: 0; border: 2px solid white; pointer-events: none; } } .image-comparison { position: relative; touch-action: pan-y pinch-zoom; max-width: Min(100%, 512px); .crop-container { height: 100%; &:nth-child(2) { overflow: hidden; width: calc(100% - var(--comparison-percent)); &, img { position: absolute; top: 0; right: 0; } } &.crop-container.crop-container { img { display: block; width: auto; height: 100%; } &:first-child img { width: 100%; } } } .slide-bar { position: absolute; background: var(--color-navy); margin-left: -2px; width: 4px; height: 100%; top: 0; left: var(--comparison-percent); box-shadow: 0 0 2px rgba(255, 255, 255, 0.5); .arrows { position: absolute; top: calc(50% - (40px / 2)); left: calc(4px / 2); width: 0; height: 0; opacity: 1; transition: opacity 0.25s; svg { position: absolute; width: 6.5px; height: 11px; top: calc(11px / -2); fill: var(--color-white); @keyframes pulse-left { from { right: 2px; } to { right: 9px; } } @keyframes pulse-right { from { left: 1px; } to { left: 9px; } } @keyframes pulse-opacity { 0% { opacity: 0; } 40% { opacity: 1; } 90% { opacity: 1; } 100% { opacity: 0; } } &:nth-of-type(1) { animation: 3s infinite ease-out pulse-left, 3s infinite ease-out pulse-opacity; right: 6px; } &:nth-of-type(2) { animation: 3s infinite ease-out pulse-right, 3s infinite ease-out pulse-opacity; left: 6px; transform: scaleX(-1); } } div { content: ""; position: absolute; background: var(--color-navy); // border-radius: 50%; top: 0; left: 0; width: 32px; height: 32px; transform: translate(-50%, -50%) rotate(45deg); box-shadow: 0 0 2px rgba(255, 255, 255, 0.5); } // Cover up the box-shadow at the top and bottom of the circle so it connects to the vertical line &::after { content: ""; position: absolute; background: var(--color-navy); left: -2px; top: -24px; width: 4px; height: 48px; } } } &:hover .slide-bar .arrows { opacity: 0; } } .carousel { margin-top: calc(80 * var(--variable-px)); transform: translate(0); .carousel-slide { display: flex; white-space: nowrap; touch-action: pan-y pinch-zoom; cursor: grab; img { position: relative; display: inline-block; flex: 0 0 auto; padding: 0 20px; &:first-child { margin-left: -20px; } &:last-child { margin-right: -20px; } } } &:not(.dragging) .carousel-slide img { transition: transform 500ms; } .carousel-slide:not(.torn) { overflow: hidden; } .carousel-slide.torn { position: fixed; top: 0; z-index: -1; // Torn edge mask -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; &.left { padding-left: 80px; margin-left: -80px; -webkit-mask-image: url("https://static.graphite.rs/textures/torn-edge-left.png"); // TODO: Switch PNG to AVIF when Edge support has rolled out mask-image: url("https://static.graphite.rs/textures/torn-edge-left.png"); -webkit-mask-position: top left; mask-position: top left; } &.right { padding-right: 120px; margin-right: -120px; -webkit-mask-image: url("https://static.graphite.rs/textures/torn-edge-right.png"); // TODO: Switch PNG to AVIF when Edge support has rolled out mask-image: url("https://static.graphite.rs/textures/torn-edge-right.png"); -webkit-mask-position: top right; mask-position: top right; } } .screenshot-details { display: flex; margin: 20px 0; gap: 20px 40px; @media screen and (max-width: 800px) { flex-wrap: wrap; justify-content: center; } .carousel-controls { display: flex; align-items: center; flex: 0 0 auto; button { outline: none; background: none; border: none; padding: 0; color: inherit; cursor: pointer; svg { display: block; } + button { margin-left: 20px; } } .direction { fill: currentColor; } .dot { width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%; border: var(--border-thickness) solid currentColor; &.active { border: none; background: var(--color-crimson); } } } .screenshot-description { display: flex; align-items: center; min-height: calc(2em * 1.5); p + p { margin: 0; } p:not(.active) { display: none; } } } &.window-size-1 .carousel-slide img { width: 100%; } &.window-size-2 .carousel-slide img { width: calc(100% / 2); } &.window-size-3 .carousel-slide img { width: calc((100% + 2 * 10px) / 3 - (3 - 1) * 10px); padding: 0 10px; &:first-child { margin-left: -10px; } &:last-child { margin-right: -10px; } } @media screen and (max-width: 1000px) { margin-left: calc(-1 * var(--page-edge-padding)); margin-right: calc(-1 * var(--page-edge-padding)); .screenshot-details { margin-left: var(--page-edge-padding); margin-right: var(--page-edge-padding); } hr { width: calc(100% - (32px + var(--page-edge-padding)) * 2); margin-left: auto; margin-right: auto; } } // 1600px is var(--max-width) @media screen and (max-width: 1600px) { .carousel-slide.torn { display: none; } } } .link { display: inline-block; font-size: var(--font-size-link); font-weight: 800; text-decoration: none; color: var(--color-crimson); white-space: nowrap; &:not(.not-uppercase) { text-transform: uppercase; } } .button.button.button.button { color: var(--color-crimson); display: inline-block; border: var(--border-thickness) solid currentColor; height: calc(var(--font-size-link) * 2); line-height: calc(var(--font-size-link) * 2 - 2 * var(--border-thickness)); font-size: var(--font-size-link); padding: 0 var(--font-size-link); box-sizing: border-box; text-decoration: none; font-weight: 800; white-space: nowrap; img { height: calc(var(--font-size-link) * 1.5); margin-right: calc(var(--font-size-link) / 2); } img, span { vertical-align: middle; } } .arrow::after { content: " »"; font-family: "Inter", sans-serif; } hr { overflow: visible; } hr, .ripple { width: calc(100% - 32px * 2); height: var(--border-thickness); margin: 0 32px; background: currentColor; position: relative; border: none; &::before { left: -40px; border-width: 0 0 var(--border-thickness) 40px; } &::after { right: -40px; border-width: 0 40px var(--border-thickness) 0; } &::before, &::after { content: ""; display: block; width: 0; height: 0; position: absolute; border-color: transparent transparent currentColor transparent; border-style: solid; } } .graphic { max-width: 200px; flex: 1 1 100%; display: flex; img { display: block; width: 100%; object-fit: contain; @media screen and (max-width: 800px) { width: auto; height: 120px; } } } .section { display: flex; flex-direction: column; align-items: flex-start; width: 100%; &.centered { align-items: center; } } .info-box { margin-top: calc(40 * var(--variable-px)); padding: calc(80 * var(--variable-px)); background-image: url("https://static.graphite.rs/textures/noise.png"); background-blend-mode: overlay; background-position: center; } .feature-box { padding: calc(80 * var(--variable-px)); background-image: url("https://static.graphite.rs/textures/noise.png"); background-blend-mode: overlay; background-position: center; &.feature-box.feature-box { max-width: unset; } @media screen and (max-width: 1000px) { &.feature-box.feature-box { margin-left: -40px; margin-right: -40px; } } .box { max-width: var(--max-width); margin: 0 auto; .section h2 + .graphic { margin-top: 20px; img { margin: auto; } } } } .diptych, .triptych { display: flex; flex-wrap: wrap; gap: calc(80 * var(--variable-px)); .section { flex: 1 1 0; } &.diptych .section { min-width: 320px; } &.triptych .section { min-width: 280px; } @media screen and (max-width: 600px) { &.diptych .section, &.triptych .section { min-width: 100%; } } img[alt=""] { display: block; &::after { content: ""; display: block; width: 100%; height: 240px; background: var(--color-crimson); } } } .informational-group { display: flex; flex-wrap: wrap; width: 100%; margin-bottom: 20px; &.features { gap: 16px; .informational { padding: 16px; gap: 16px; background: rgba(0, 0, 0, 0.0625); // Half width, minus own padding on both sides, minus half a gap flex: 1 0 calc(50% - (16px * 2) - (16px / 2)); @media screen and (max-width: 1100px) { // Quarter width, minus own padding on both sides flex: 1 0 calc(100% - (16px * 2)); } } &.four-wide .informational { flex: 1 0 calc(25% - (16px * 4) - (16px / 4)); @media screen and (max-width: 1100px) { // Half width, minus own padding on both sides, minus half a gap flex: 1 0 calc(50% - (16px * 2) - (16px / 2)); } @media screen and (max-width: 840px) { // Quarter width, minus own padding on both sides flex: 1 0 calc(100% - (16px * 2)); } } } &.concepts { justify-content: space-between; margin: 0 -10px; width: calc(100% + 20px); .informational { flex-direction: column; flex: 0 1 auto; margin: 0 10px; @media screen and (max-width: 1100px) { width: calc(100% / 3 - 40px); } @media screen and (max-width: 400px) { width: calc(100% / 2 - 20px); } img { width: 72px; height: 72px; object-position: calc(-72px * var(--atlas-index)) 0; margin-bottom: 8px; } span { text-align: center; } } } .informational { display: flex; align-items: center; img { flex: 0 0 auto; } } } blockquote { padding: 32px 80px; background: rgba(0, 0, 0, 0.0625); position: relative; border-left: 4px solid var(--color-navy); &::before, &::after { content: "“"; font-family: "EB Garamond", Garamond, serif; font-weight: 500; font-size: 8em; line-height: 1; position: absolute; opacity: 0.25; } &::before { top: -8px; left: 8px; } &::after { transform: rotate(180deg); bottom: -8px; right: 8px; } } body > .page { box-sizing: border-box; min-width: 320px; header { padding: 0 var(--page-edge-padding); color: var(--color-walnut); position: relative; z-index: 1000; nav { margin: auto; max-width: var(--max-width); .row { display: flex; justify-content: space-between; --nav-padding-above-below: 30px; padding-top: var(--nav-padding-above-below); padding-bottom: calc(var(--nav-padding-above-below) - 16px); margin-bottom: calc(var(--nav-padding-above-below) - 16px); // Covers up content that extends up underneath the header background: white; @media screen and (max-width: 760px) { --nav-padding-above-below: 24px; } .left, .right { z-index: 1; display: flex; align-items: center; gap: 40px; a { color: inherit; font-family: "Bona Nova", Palatino, serif; font-feature-settings: "lnum"; line-height: 1.25; font-weight: 700; text-decoration: none; --height: 60px; --button-padding: 24px; --nav-font-size: 28px; // Keep up to date with `NAV_BUTTON_INITIAL_FONT_SIZE` in navbar.js font-size: var(--nav-font-size); &.button.button { height: var(--height); padding-left: var(--button-padding); padding-right: var(--button-padding); line-height: calc(var(--height) - 2 * var(--border-thickness)); font-size: var(--nav-font-size); } img { display: block; width: var(--height); height: var(--height); } } &.left img { // Don't show the alt text if the image doesn't load font-size: 0; } @media screen and (max-width: 1200px) { gap: 30px; a { --height: 50px; --button-padding: 16px; --nav-font-size: 24px; } } @media screen and (max-width: 960px) { gap: 30px; a { --height: 50px; --button-padding: 16px; --nav-font-size: 20px; } } @media screen and (max-width: 880px) { gap: 20px; a { --height: 40px; --button-padding: 12px; --nav-font-size: 16px; } } @media screen and (max-width: 680px) { gap: 16px; a { --height: 30px; --button-padding: 8px; --nav-font-size: 14px; } } @media screen and (max-width: 600px) { gap: 12px; a { --height: 24px; --button-padding: 8px; --nav-font-size: 13px; } } @media screen and (max-width: 540px) { gap: 10px; a { --height: 22px; --button-padding: 6px; --nav-font-size: 12px; } } @media screen and (max-width: 480px) { gap: 8px; a { --height: 20px; --button-padding: 4px; --nav-font-size: 11px; } } @media screen and (max-width: 430px) { gap: 6px; a { --height: 20px; --button-padding: 4px; --nav-font-size: 10px; } } } } } .ripple { display: block; background: none; // Covers up content that extends up underneath the header fill: white; stroke: currentColor; --ripple-height: 16px; height: var(--ripple-height); margin-top: calc(-1 * var(--ripple-height) + var(--border-thickness)); margin-bottom: calc(-1 * var(--border-thickness)); stroke-width: var(--border-thickness); &::before, &::after { content: none; } } hr { background: none; } @media screen and (max-width: 1824px) { .ripple { width: calc(100% + (var(--page-edge-padding) * 2)); margin-left: calc(-1 * var(--page-edge-padding)); margin-right: calc(-1 * var(--page-edge-padding)); } hr { display: none; } } } main { padding: 0 var(--page-edge-padding); .content { padding: calc(120 * var(--variable-px)) 0; section { max-width: var(--max-width); margin: 0 auto; // Puts the content in front of the hexagon decoration position: relative; z-index: 1; ~ section { margin-top: calc(120 * var(--variable-px)); } p img { max-width: 100%; } pre { box-sizing: border-box; overflow: auto; } details { width: 100%; } } } } footer { display: flex; flex-direction: column; align-items: center; gap: 40px; padding: 40px; padding-top: 0; color: var(--color-walnut); nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 40px; a { color: var(--color-walnut); } @media screen and (max-width: 900px) { max-width: 500px; } @media screen and (max-width: 760px) { max-width: 440px; } @media screen and (max-width: 400px) { gap: 6px 20px; } } span { text-align: center; } } } .fundraising { margin-top: 20px; width: 100%; .fundraising-bar { width: 100%; height: 32px; border-radius: 10000px; background: var(--color-fog); overflow: hidden; .fundraising-bar-progress { width: calc(var(--fundraising-percent) - (4px * 2) - (32px - 4px * 2)); padding-left: calc(32px - 4px * 2); height: calc(100% - 4px * 2); margin: 4px; border-radius: 10000px; background: linear-gradient(to right, var(--color-navy), var(--color-crimson)); transition: opacity 1s, width 2s; } } .goal-metrics { display: flex; justify-content: space-between; font-weight: 800; margin-top: 8px; margin-left: 20px; width: calc(100% - 40px); > span { transition: opacity 1s; } } &.fundraising.loading { .goal-metrics > span, .fundraising-bar .fundraising-bar-progress { opacity: 0; } } }