mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 02:15:05 +03:00
Merge pull request #13488 from supabase/fs/blog-post-updates
chore: blog post updates
This commit is contained in:
8 files changed
+264
-82
No files matched your search
@@ -0,0 +1,64 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
const ShareArticleActions = ({ title, slug }: { title: string; slug: string }) => (
|
||||
<div className="mt-4 flex items-center space-x-4">
|
||||
<Link
|
||||
passHref
|
||||
href={`https://twitter.com/share?text=${title}&url=https://supabase.com/blog/${slug}`}
|
||||
>
|
||||
<a target="_blank" className="text-scale-900 hover:text-scale-1200">
|
||||
<svg
|
||||
height="26"
|
||||
width="26"
|
||||
viewBox="-89 -46.8 644 446.8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="m154.729 400c185.669 0 287.205-153.876 287.205-287.312 0-4.37-.089-8.72-.286-13.052a205.304 205.304 0 0 0 50.352-52.29c-18.087 8.044-37.55 13.458-57.968 15.899 20.841-12.501 36.84-32.278 44.389-55.852a202.42 202.42 0 0 1 -64.098 24.511c-18.42-19.628-44.644-31.904-73.682-31.904-55.744 0-100.948 45.222-100.948 100.965 0 7.925.887 15.631 2.619 23.025-83.895-4.223-158.287-44.405-208.074-105.504a100.739 100.739 0 0 0 -13.668 50.754c0 35.034 17.82 65.961 44.92 84.055a100.172 100.172 0 0 1 -45.716-12.63c-.015.424-.015.837-.015 1.29 0 48.903 34.794 89.734 80.982 98.986a101.036 101.036 0 0 1 -26.617 3.553c-6.493 0-12.821-.639-18.971-1.82 12.851 40.122 50.115 69.319 94.296 70.135-34.549 27.089-78.07 43.224-125.371 43.224a204.9 204.9 0 0 1 -24.078-1.399c44.674 28.645 97.72 45.359 154.734 45.359"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
passHref
|
||||
href={`https://www.linkedin.com/shareArticle?url=https://supabase.com/blog/${slug}&title=${title}`}
|
||||
>
|
||||
<a target="_blank" className="text-scale-900 hover:text-scale-1200">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 5 1036 990"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M0 120c0-33.334 11.667-60.834 35-82.5C58.333 15.833 88.667 5 126 5c36.667 0 66.333 10.666 89 32 23.333 22 35 50.666 35 86 0 32-11.333 58.666-34 80-23.333 22-54 33-92 33h-1c-36.667 0-66.333-11-89-33S0 153.333 0 120zm13 875V327h222v668H13zm345 0h222V622c0-23.334 2.667-41.334 8-54 9.333-22.667 23.5-41.834 42.5-57.5 19-15.667 42.833-23.5 71.5-23.5 74.667 0 112 50.333 112 151v357h222V612c0-98.667-23.333-173.5-70-224.5S857.667 311 781 311c-86 0-153 37-201 111v2h-1l1-2v-95H358c1.333 21.333 2 87.666 2 199 0 111.333-.667 267.666-2 469z" />
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
<Link
|
||||
passHref
|
||||
href={`https://news.ycombinator.com/submitlink?u=https://supabase.com/blog/${slug}&t=${title}`}
|
||||
>
|
||||
<a target="_blank" className="text-scale-900 hover:text-scale-1200">
|
||||
<svg
|
||||
width="23"
|
||||
height="23"
|
||||
viewBox="0 0 23 23"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M22.7969 0.878906H0.703125V22.9727H22.7969V0.878906Z" fill="currentColor" />
|
||||
<path
|
||||
d="M11.0093 13.3976L7.17969 6.25391H8.94719L11.1566 10.7463C11.1566 10.8199 11.2302 10.8936 11.3039 10.9672C11.3775 11.0409 11.3775 11.1145 11.4511 11.2618L11.5248 11.3355V11.4091C11.5984 11.5564 11.5984 11.6301 11.6721 11.7773C11.7457 11.851 11.7457 11.9983 11.8194 12.0719C11.893 11.851 12.0403 11.7037 12.114 11.4091C12.1876 11.1882 12.3349 10.9672 12.4822 10.7463L14.6916 6.25391H16.3118L12.4822 13.4712V18.0372H11.0093V13.3976Z"
|
||||
fill="#1C1C1C"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default ShareArticleActions
|
||||
@@ -0,0 +1,32 @@
|
||||
import Image from 'next/image'
|
||||
import React from 'react'
|
||||
import days from '~/components/LaunchWeek/lw7_days'
|
||||
|
||||
const HackernewsShare = ({ url, title }: { url: string; title: string }) => {
|
||||
const hackerNewsLink = `https://news.ycombinator.com/submitlink?u=${encodeURIComponent(
|
||||
url
|
||||
)}&t=${encodeURIComponent(title)}`
|
||||
|
||||
return (
|
||||
<div className="flex gap-4 lg:gap-6">
|
||||
<p className="text-lg">Start a conversation about this topic</p>
|
||||
<a href={hackerNewsLink} target="_blank" rel="noopener noreferrer">
|
||||
<svg
|
||||
width="23"
|
||||
height="23"
|
||||
viewBox="0 0 23 23"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M22.7969 0.878906H0.703125V22.9727H22.7969V0.878906Z" fill="#A0A0A0" />
|
||||
<path
|
||||
d="M11.0093 13.3976L7.17969 6.25391H8.94719L11.1566 10.7463C11.1566 10.8199 11.2302 10.8936 11.3039 10.9672C11.3775 11.0409 11.3775 11.1145 11.4511 11.2618L11.5248 11.3355V11.4091C11.5984 11.5564 11.5984 11.6301 11.6721 11.7773C11.7457 11.851 11.7457 11.9983 11.8194 12.0719C11.893 11.851 12.0403 11.7037 12.114 11.4091C12.1876 11.1882 12.3349 10.9672 12.4822 10.7463L14.6916 6.25391H16.3118L12.4822 13.4712V18.0372H11.0093V13.3976Z"
|
||||
fill="#1C1C1C"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HackernewsShare
|
||||
@@ -11,13 +11,14 @@ import SolutionsData from 'data/Solutions.json'
|
||||
import Solutions from '~/components/Nav/Product'
|
||||
import Developers from '~/components/Nav/Developers'
|
||||
import Announcement from '~/components/Nav/Announcement'
|
||||
import CountdownBanner from '~/components/LaunchWeek/Banners/CountdownBanner'
|
||||
import ScrollProgress from '~/components/ScrollProgress'
|
||||
|
||||
import { useIsLoggedIn, useTheme } from 'common'
|
||||
import TextLink from '../TextLink'
|
||||
import Image from 'next/image'
|
||||
import * as supabaseLogoWordmarkDark from 'common/assets/images/supabase-logo-wordmark--dark.png'
|
||||
import * as supabaseLogoWordmarkLight from 'common/assets/images/supabase-logo-wordmark--light.png'
|
||||
import CountdownBanner from '../LaunchWeek/Banners/CountdownBanner'
|
||||
|
||||
const Nav = () => {
|
||||
const { isDarkMode } = useTheme()
|
||||
@@ -436,6 +437,7 @@ const Nav = () => {
|
||||
<FlyOut open={openDevelopers} handleCancel={handleCancel}>
|
||||
<Developers />
|
||||
</FlyOut>
|
||||
<ScrollProgress />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
const ScrollProgress = () => {
|
||||
const [progressPercentage, setProgressPercentage] = useState(0)
|
||||
const { pathname } = useRouter()
|
||||
|
||||
const isBlogPost = pathname.includes('/blog/')
|
||||
if (!isBlogPost) return null
|
||||
|
||||
const handleScroll = () => {
|
||||
if (typeof document === 'undefined') return null
|
||||
const article = document?.querySelector('article')
|
||||
const { top, height } = (article as any)?.getBoundingClientRect()
|
||||
let scrollDistance = -top
|
||||
let progressPercentage =
|
||||
(scrollDistance / (height - document.documentElement.clientHeight)) * 100
|
||||
setProgressPercentage(progressPercentage)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [])
|
||||
|
||||
let isActive = progressPercentage <= 100
|
||||
|
||||
return (
|
||||
<div className="h-[2px] w-full flex justify-start relative">
|
||||
<div
|
||||
className="h-full top-0 bottom-0 right-0 absolute w-screen bg-brand-900 will-change-transform transition-opacity"
|
||||
style={{
|
||||
display: isActive ? 'absolute' : 'relative',
|
||||
transform: `translate3d(${isActive ? progressPercentage - 100 + '%' : '0'},0,0)`,
|
||||
opacity: isActive ? 1 : 0,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScrollProgress
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
const useActiveAnchors = (
|
||||
anchorsQuerySelector: string = 'h2',
|
||||
tocQuerySelector: string = '.prose-toc a',
|
||||
offset: number = 200
|
||||
) => {
|
||||
const anchors = useRef<NodeListOf<HTMLHeadingElement> | null>(null)
|
||||
const toc = useRef<NodeListOf<HTMLHeadingElement> | null>(null)
|
||||
|
||||
const handleScroll = () => {
|
||||
const pageYOffset = window.pageYOffset
|
||||
let newActiveAnchor: string = ''
|
||||
|
||||
anchors.current?.forEach((anchor) => {
|
||||
if (pageYOffset >= anchor.offsetTop - offset) {
|
||||
newActiveAnchor = anchor.id
|
||||
}
|
||||
})
|
||||
|
||||
toc.current?.forEach((link) => {
|
||||
link.classList.remove('toc-animate')
|
||||
// TODO: escape emojis
|
||||
// The problem is that MDXRemote strips out emojis on slugs
|
||||
// but ReactMarkdown doesn't,instead it encodes them
|
||||
const sanitizedHref = (link.getAttribute('href') ?? '').replace('#', '')
|
||||
const isMatch = sanitizedHref === newActiveAnchor
|
||||
|
||||
if (isMatch) {
|
||||
link.classList.add('toc-animate')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
anchors.current = document.querySelectorAll(anchorsQuerySelector)
|
||||
toc.current = document.querySelectorAll(tocQuerySelector)
|
||||
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default useActiveAnchors
|
||||
@@ -1,19 +1,22 @@
|
||||
import { Badge, Divider, IconChevronLeft, IconFile } from 'ui'
|
||||
import matter from 'gray-matter'
|
||||
import authors from 'lib/authors.json'
|
||||
import { MDXRemote } from 'next-mdx-remote'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import matter from 'gray-matter'
|
||||
import authors from 'lib/authors.json'
|
||||
import { MDXRemote } from 'next-mdx-remote'
|
||||
import { Badge, Divider, IconChevronLeft } from 'ui'
|
||||
|
||||
import CTABanner from '~/components/CTABanner'
|
||||
import DefaultLayout from '~/components/Layouts/Default'
|
||||
import BlogLinks from '~/components/LaunchWeek/7/BlogLinks'
|
||||
import { generateReadingTime } from '~/lib/helpers'
|
||||
import ShareArticleActions from '~/components/Blog/ShareArticleActions'
|
||||
import useActiveAnchors from '~/hooks/useActiveAnchors'
|
||||
import mdxComponents from '~/lib/mdx/mdxComponents'
|
||||
import { mdxSerialize } from '~/lib/mdx/mdxSerialize'
|
||||
import { getAllPostSlugs, getPostdata, getSortedPosts } from '~/lib/posts'
|
||||
import { ReactMarkdown } from 'react-markdown/lib/react-markdown'
|
||||
|
||||
// table of contents extractor
|
||||
const toc = require('markdown-toc')
|
||||
@@ -65,6 +68,7 @@ export async function getStaticProps({ params }: any) {
|
||||
function BlogPostPage(props: any) {
|
||||
const content = props.blog.content
|
||||
const authorArray = props.blog.author.split(',')
|
||||
// useActiveAnchors('h2, h3, h4')
|
||||
const isLaunchWeek7 = props.blog.launchweek === 7
|
||||
|
||||
const author = []
|
||||
@@ -105,7 +109,7 @@ function BlogPostPage(props: any) {
|
||||
const toc = props.blog.toc && (
|
||||
<div className="space-y-8 py-8 lg:py-0">
|
||||
<div>
|
||||
<div className="space-x-2">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{props.blog.tags.map((tag: string) => {
|
||||
return (
|
||||
<a href={`/blog/tags/${tag}`} key={`category-badge-${tag}`}>
|
||||
@@ -199,39 +203,41 @@ function BlogPostPage(props: any) {
|
||||
<p>•</p>
|
||||
<p>{generateReadingTime(props.blog.source)}</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 pt-6 md:flex-row md:gap-0 lg:gap-3">
|
||||
{author.map((author: any, i: number) => {
|
||||
return (
|
||||
<div className="mr-4 w-max" key={i}>
|
||||
<Link href={author.author_url}>
|
||||
<a className="cursor-pointer">
|
||||
<div className="flex items-center gap-3">
|
||||
{author.author_image_url && (
|
||||
<div className="w-10">
|
||||
<Image
|
||||
src={author.author_image_url}
|
||||
className="dark:border-dark rounded-full border"
|
||||
alt={`${author.author} avatar`}
|
||||
width="100%"
|
||||
height="100%"
|
||||
layout="responsive"
|
||||
/>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex-1 flex flex-col gap-3 pt-6 md:flex-row md:gap-0 lg:gap-3">
|
||||
{author.map((author: any, i: number) => {
|
||||
return (
|
||||
<div className="mr-4 w-max" key={i}>
|
||||
<Link href={author.author_url}>
|
||||
<a className="cursor-pointer">
|
||||
<div className="flex items-center gap-3">
|
||||
{author.author_image_url && (
|
||||
<div className="w-10">
|
||||
<Image
|
||||
src={author.author_image_url}
|
||||
className="dark:border-dark rounded-full border"
|
||||
alt={`${author.author} avatar`}
|
||||
width="100%"
|
||||
height="100%"
|
||||
layout="responsive"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col">
|
||||
<span className="text-scale-1200 mb-0 text-sm">
|
||||
{author.author}
|
||||
</span>
|
||||
<span className="text-scale-900 mb-0 text-xs">
|
||||
{author.position}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col">
|
||||
<span className="text-scale-1200 mb-0 text-sm">
|
||||
{author.author}
|
||||
</span>
|
||||
<span className="text-scale-900 mb-0 text-xs">
|
||||
{author.position}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -267,48 +273,11 @@ function BlogPostPage(props: any) {
|
||||
</div>
|
||||
</article>
|
||||
{isLaunchWeek7 && <BlogLinks />}
|
||||
<div className="py-16">
|
||||
<div className="block lg:hidden py-8">
|
||||
<div className="text-scale-900 dark:text-scale-1000 text-sm">
|
||||
Share this article
|
||||
</div>
|
||||
<div className="mt-4 flex items-center space-x-4">
|
||||
<Link
|
||||
passHref
|
||||
href={`https://twitter.com/share?text=${props.blog.title}&url=https://supabase.com/blog/${props.blog.slug}`}
|
||||
>
|
||||
<a target="_blank" className="text-scale-900 hover:text-scale-1200">
|
||||
<svg
|
||||
height="26"
|
||||
width="26"
|
||||
viewBox="-89 -46.8 644 446.8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="m154.729 400c185.669 0 287.205-153.876 287.205-287.312 0-4.37-.089-8.72-.286-13.052a205.304 205.304 0 0 0 50.352-52.29c-18.087 8.044-37.55 13.458-57.968 15.899 20.841-12.501 36.84-32.278 44.389-55.852a202.42 202.42 0 0 1 -64.098 24.511c-18.42-19.628-44.644-31.904-73.682-31.904-55.744 0-100.948 45.222-100.948 100.965 0 7.925.887 15.631 2.619 23.025-83.895-4.223-158.287-44.405-208.074-105.504a100.739 100.739 0 0 0 -13.668 50.754c0 35.034 17.82 65.961 44.92 84.055a100.172 100.172 0 0 1 -45.716-12.63c-.015.424-.015.837-.015 1.29 0 48.903 34.794 89.734 80.982 98.986a101.036 101.036 0 0 1 -26.617 3.553c-6.493 0-12.821-.639-18.971-1.82 12.851 40.122 50.115 69.319 94.296 70.135-34.549 27.089-78.07 43.224-125.371 43.224a204.9 204.9 0 0 1 -24.078-1.399c44.674 28.645 97.72 45.359 154.734 45.359"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
passHref
|
||||
href={`https://www.linkedin.com/shareArticle?url=https://supabase.com/blog/${props.blog.slug}&title=${props.blog.title}`}
|
||||
>
|
||||
<a target="_blank" className="text-scale-900 hover:text-scale-1200">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 5 1036 990"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M0 120c0-33.334 11.667-60.834 35-82.5C58.333 15.833 88.667 5 126 5c36.667 0 66.333 10.666 89 32 23.333 22 35 50.666 35 86 0 32-11.333 58.666-34 80-23.333 22-54 33-92 33h-1c-36.667 0-66.333-11-89-33S0 153.333 0 120zm13 875V327h222v668H13zm345 0h222V622c0-23.334 2.667-41.334 8-54 9.333-22.667 23.5-41.834 42.5-57.5 19-15.667 42.833-23.5 71.5-23.5 74.667 0 112 50.333 112 151v357h222V612c0-98.667-23.333-173.5-70-224.5S857.667 311 781 311c-86 0-153 37-201 111v2h-1l1-2v-95H358c1.333 21.333 2 87.666 2 199 0 111.333-.667 267.666-2 469z" />
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<ShareArticleActions title={props.blog.title} slug={props.blog.slug} />
|
||||
</div>
|
||||
<div className="grid gap-8 py-8 lg:grid-cols-1">
|
||||
<div>
|
||||
@@ -323,21 +292,21 @@ function BlogPostPage(props: any) {
|
||||
</div>
|
||||
{/* Sidebar */}
|
||||
<div className="col-span-12 space-y-8 lg:col-span-5 xl:col-span-3 xl:col-start-9">
|
||||
<div className="space-y-8 lg:sticky lg:top-24 lg:mb-24">
|
||||
<div className="space-y-6 lg:sticky lg:top-24 lg:mb-48">
|
||||
<div className="hidden lg:block">{toc}</div>
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<p className="text-scale-1200 text-sm">Related articles</p>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-2">
|
||||
{props.relatedPosts.map((post: any, i: number) => (
|
||||
<Link href={`${post.path}`} as={`${post.path}`} key={i}>
|
||||
<div>
|
||||
<p className="cursor-pointer">
|
||||
<div className="flex gap-2">
|
||||
<div className="text-scale-900">
|
||||
{/* <div className="text-scale-900">
|
||||
<IconFile size={'small'} style={{ minWidth: '1.2rem' }} />
|
||||
</div>
|
||||
</div> */}
|
||||
<span className="text-scale-1100 hover:text-gray-1200 text-sm">
|
||||
{post.title}
|
||||
</span>
|
||||
@@ -349,11 +318,15 @@ function BlogPostPage(props: any) {
|
||||
))}
|
||||
<div className="mt-2">
|
||||
<Link href={`/blog`} passHref>
|
||||
<a className="text-scale-1100 hover:text-scale-1200 cursor-pointer text-sm">
|
||||
<a className="text-scale-1100 hover:text-scale-1200 cursor-pointer text-xs">
|
||||
View all posts
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="py-4 hidden lg:block">
|
||||
<div className="text-scale-1200 text-sm">Share this article</div>
|
||||
<ShareArticleActions title={props.blog.title} slug={props.blog.slug} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 578 KiB |
@@ -70,11 +70,29 @@ h6 { */
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
h1:not(.overwrite),
|
||||
h2:not(.overwrite),
|
||||
h3:not(.overwrite),
|
||||
h4:not(.overwrite),
|
||||
h5:not(.overwrite),
|
||||
h6:not(.overwrite) {
|
||||
scroll-margin-top: 90px;
|
||||
}
|
||||
|
||||
.h1:not(.prose *):not(.overwrite),
|
||||
.h2:not(.prose *):not(.overwrite) {
|
||||
line-height: 1.2 !important;
|
||||
}
|
||||
|
||||
.toc-animate {
|
||||
transform: translate3d(3px, 0, 0) !important;
|
||||
color: hsla(153, 60%, 53%, 1) !important;
|
||||
}
|
||||
|
||||
.prose-toc a {
|
||||
transition: all 0.07s ease-in-out;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
.h1:not(.prose *):not(.overwrite) {
|
||||
font-size: 2.2rem !important;
|
||||
|
||||
Reference in new issue
Block a user