more visual polish, adjust colours and spacing
This commit is contained in:
		@@ -22,6 +22,7 @@ const contentPageLayout: PageLayout = {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  left: [
 | 
					  left: [
 | 
				
			||||||
    Component.PageTitle(),
 | 
					    Component.PageTitle(),
 | 
				
			||||||
 | 
					    Component.MobileOnly(Component.Spacer()),
 | 
				
			||||||
    Component.Search(),
 | 
					    Component.Search(),
 | 
				
			||||||
    Component.Darkmode(),
 | 
					    Component.Darkmode(),
 | 
				
			||||||
    Component.DesktopOnly(Component.TableOfContents()),
 | 
					    Component.DesktopOnly(Component.TableOfContents()),
 | 
				
			||||||
@@ -38,6 +39,7 @@ const listPageLayout: PageLayout = {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  left: [
 | 
					  left: [
 | 
				
			||||||
    Component.PageTitle(),
 | 
					    Component.PageTitle(),
 | 
				
			||||||
 | 
					    Component.MobileOnly(Component.Spacer()),
 | 
				
			||||||
    Component.Search(),
 | 
					    Component.Search(),
 | 
				
			||||||
    Component.Darkmode()
 | 
					    Component.Darkmode()
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
@@ -63,8 +65,8 @@ const config: QuartzConfig = {
 | 
				
			|||||||
      colors: {
 | 
					      colors: {
 | 
				
			||||||
        lightMode: {
 | 
					        lightMode: {
 | 
				
			||||||
          light: '#faf8f8',
 | 
					          light: '#faf8f8',
 | 
				
			||||||
          lightgray: '#e8e8e8',
 | 
					          lightgray: '#e5e5e5',
 | 
				
			||||||
          gray: '#dadada',
 | 
					          gray: '#b8b8b8',
 | 
				
			||||||
          darkgray: '#4e4e4e',
 | 
					          darkgray: '#4e4e4e',
 | 
				
			||||||
          dark: '#141021',
 | 
					          dark: '#141021',
 | 
				
			||||||
          secondary: '#284b63',
 | 
					          secondary: '#284b63',
 | 
				
			||||||
@@ -73,8 +75,8 @@ const config: QuartzConfig = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        darkMode: {
 | 
					        darkMode: {
 | 
				
			||||||
          light: '#161618',
 | 
					          light: '#161618',
 | 
				
			||||||
          lightgray: '#292629',
 | 
					          lightgray: '#393639',
 | 
				
			||||||
          gray: '#343434',
 | 
					          gray: '#646464',
 | 
				
			||||||
          darkgray: '#d4d4d4',
 | 
					          darkgray: '#d4d4d4',
 | 
				
			||||||
          dark: '#fbfffe',
 | 
					          dark: '#fbfffe',
 | 
				
			||||||
          secondary: '#7b97aa',
 | 
					          secondary: '#7b97aa',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ function Backlinks({ fileData, allFiles }: QuartzComponentProps) {
 | 
				
			|||||||
  const backlinkFiles = allFiles.filter(file => file.links?.includes(slug))
 | 
					  const backlinkFiles = allFiles.filter(file => file.links?.includes(slug))
 | 
				
			||||||
  return <div class="backlinks">
 | 
					  return <div class="backlinks">
 | 
				
			||||||
    <h3>Backlinks</h3>
 | 
					    <h3>Backlinks</h3>
 | 
				
			||||||
    <ul>
 | 
					    <ul class="overflow">
 | 
				
			||||||
      {backlinkFiles.length > 0 ?
 | 
					      {backlinkFiles.length > 0 ?
 | 
				
			||||||
        backlinkFiles.map(f => <li><a href={stripIndex(relativeToRoot(slug, f.slug!))} class="internal">{f.frontmatter?.title}</a></li>)
 | 
					        backlinkFiles.map(f => <li><a href={stripIndex(relativeToRoot(slug, f.slug!))} class="internal">{f.frontmatter?.title}</a></li>)
 | 
				
			||||||
        : <li>No backlinks found</li>}
 | 
					        : <li>No backlinks found</li>}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,7 @@ export default ((component?: QuartzComponent) => {
 | 
				
			|||||||
  if (component) {
 | 
					  if (component) {
 | 
				
			||||||
    const Component = component
 | 
					    const Component = component
 | 
				
			||||||
    function DesktopOnly(props: QuartzComponentProps) {
 | 
					    function DesktopOnly(props: QuartzComponentProps) {
 | 
				
			||||||
      return <div class="desktop-only">
 | 
					      return <Component displayClass="desktop-only" {...props} />
 | 
				
			||||||
        <Component {...props} />
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DesktopOnly.displayName = component.displayName
 | 
					    DesktopOnly.displayName = component.displayName
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,15 +11,13 @@ export default ((opts?: Options) => {
 | 
				
			|||||||
    const year = new Date().getFullYear()
 | 
					    const year = new Date().getFullYear()
 | 
				
			||||||
    const name = opts?.authorName ?? "someone"
 | 
					    const name = opts?.authorName ?? "someone"
 | 
				
			||||||
    const links = opts?.links ?? []
 | 
					    const links = opts?.links ?? []
 | 
				
			||||||
    return <>
 | 
					    return <footer>
 | 
				
			||||||
      <hr />
 | 
					      <hr />
 | 
				
			||||||
      <footer>
 | 
					      <p>Made by {name} using <a href="https://quartz.jzhao.xyz/">Quartz</a>, © {year}</p>
 | 
				
			||||||
        <p>Made by {name} using <a href="https://quartz.jzhao.xyz/">Quartz</a>, © {year}</p>
 | 
					      <ul>{Object.entries(links).map(([text, link]) => <li>
 | 
				
			||||||
        <ul>{Object.entries(links).map(([text, link]) => <li>
 | 
					        <a href={link}>{text}</a>
 | 
				
			||||||
          <a href={link}>{text}</a>
 | 
					      </li>)}</ul>
 | 
				
			||||||
        </li>)}</ul>
 | 
					    </footer>
 | 
				
			||||||
      </footer>
 | 
					 | 
				
			||||||
    </>
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Footer.css = style
 | 
					  Footer.css = style
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ export default ((opts?: GraphOptions) => {
 | 
				
			|||||||
    const localGraph = { ...opts?.localGraph, ...defaultOptions.localGraph }
 | 
					    const localGraph = { ...opts?.localGraph, ...defaultOptions.localGraph }
 | 
				
			||||||
    const globalGraph = { ...opts?.globalGraph, ...defaultOptions.globalGraph }
 | 
					    const globalGraph = { ...opts?.globalGraph, ...defaultOptions.globalGraph }
 | 
				
			||||||
    return <div class="graph">
 | 
					    return <div class="graph">
 | 
				
			||||||
      <h3>Interactive Graph</h3>
 | 
					      <h3>Site Graph</h3>
 | 
				
			||||||
      <div class="graph-outer">
 | 
					      <div class="graph-outer">
 | 
				
			||||||
        <div id="graph-container" data-cfg={JSON.stringify(localGraph)}></div>
 | 
					        <div id="graph-container" data-cfg={JSON.stringify(localGraph)}></div>
 | 
				
			||||||
        <svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
					        <svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,7 @@ export default ((component?: QuartzComponent) => {
 | 
				
			|||||||
  if (component) {
 | 
					  if (component) {
 | 
				
			||||||
    const Component = component
 | 
					    const Component = component
 | 
				
			||||||
    function MobileOnly(props: QuartzComponentProps) {
 | 
					    function MobileOnly(props: QuartzComponentProps) {
 | 
				
			||||||
      return <div class="mobile-only">
 | 
					      return <Component displayClass="mobile-only" {...props} />
 | 
				
			||||||
        <Component {...props} />
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MobileOnly.displayName = component.displayName
 | 
					    MobileOnly.displayName = component.displayName
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ function ReadingTime({ fileData }: QuartzComponentProps) {
 | 
				
			|||||||
ReadingTime.css = `
 | 
					ReadingTime.css = `
 | 
				
			||||||
.reading-time {
 | 
					.reading-time {
 | 
				
			||||||
  margin-top: 0;
 | 
					  margin-top: 0;
 | 
				
			||||||
  opacity: 0.5;
 | 
					  color: var(--gray);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
import { QuartzComponentConstructor } from "./types"
 | 
					import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Spacer() {
 | 
					function Spacer({ displayClass }: QuartzComponentProps) {
 | 
				
			||||||
  return <div class="spacer"></div>
 | 
					  const className = displayClass ? `spacer ${displayClass}` : "spacer"
 | 
				
			||||||
 | 
					  return <div class={className}></div>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default (() => Spacer) satisfies QuartzComponentConstructor
 | 
					export default (() => Spacer) satisfies QuartzComponentConstructor
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ function TableOfContents({ fileData }: QuartzComponentProps) {
 | 
				
			|||||||
      </svg>
 | 
					      </svg>
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
    <div id="toc-content">
 | 
					    <div id="toc-content">
 | 
				
			||||||
      <ul>
 | 
					      <ul class="overflow">
 | 
				
			||||||
        {fileData.toc.map(tocEntry => <li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
 | 
					        {fileData.toc.map(tocEntry => <li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
 | 
				
			||||||
          <a href={`#${tocEntry.slug}`} data-for={tocEntry.slug}>{tocEntry.text}</a>
 | 
					          <a href={`#${tocEntry.slug}`} data-for={tocEntry.slug}>{tocEntry.text}</a>
 | 
				
			||||||
        </li>)}
 | 
					        </li>)}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ function FolderContent(props: QuartzComponentProps) {
 | 
				
			|||||||
  const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
 | 
					  const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
 | 
				
			||||||
  return <div class="popover-hint">
 | 
					  return <div class="popover-hint">
 | 
				
			||||||
    <article>{content}</article>
 | 
					    <article>{content}</article>
 | 
				
			||||||
    <hr/>
 | 
					 | 
				
			||||||
    <p>{allPagesInFolder.length} items under this folder.</p>
 | 
					    <p>{allPagesInFolder.length} items under this folder.</p>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <PageList {...listProps} /> 
 | 
					      <PageList {...listProps} /> 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ function TagContent(props: QuartzComponentProps) {
 | 
				
			|||||||
    const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
 | 
					    const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
 | 
				
			||||||
    return <div class="popover-hint">
 | 
					    return <div class="popover-hint">
 | 
				
			||||||
      <article>{content}</article>
 | 
					      <article>{content}</article>
 | 
				
			||||||
      <hr/>
 | 
					 | 
				
			||||||
      <p>{allPagesWithTag.length} items with this tag.</p>
 | 
					      <p>{allPagesWithTag.length} items with this tag.</p>
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
        <PageList {...listProps} />
 | 
					        <PageList {...listProps} />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,22 +55,22 @@ export function renderPage(slug: string, componentData: QuartzComponentProps, co
 | 
				
			|||||||
    <Head {...componentData} />
 | 
					    <Head {...componentData} />
 | 
				
			||||||
    <body data-slug={slug}>
 | 
					    <body data-slug={slug}>
 | 
				
			||||||
      <div id="quartz-root" class="page">
 | 
					      <div id="quartz-root" class="page">
 | 
				
			||||||
        <div class="page-header">
 | 
					 | 
				
			||||||
          <Header {...componentData} >
 | 
					 | 
				
			||||||
            {header.map(HeaderComponent => <HeaderComponent {...componentData} />)}
 | 
					 | 
				
			||||||
          </Header>
 | 
					 | 
				
			||||||
          <div class="popover-hint">
 | 
					 | 
				
			||||||
            {beforeBody.map(BodyComponent => <BodyComponent {...componentData} />)}
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <Body {...componentData}>
 | 
					        <Body {...componentData}>
 | 
				
			||||||
          {LeftComponent}
 | 
					          {LeftComponent}
 | 
				
			||||||
          <div class="center">
 | 
					          <div class="center">
 | 
				
			||||||
 | 
					            <div class="page-header">
 | 
				
			||||||
 | 
					              <Header {...componentData} >
 | 
				
			||||||
 | 
					                {header.map(HeaderComponent => <HeaderComponent {...componentData} />)}
 | 
				
			||||||
 | 
					              </Header>
 | 
				
			||||||
 | 
					              <div class="popover-hint">
 | 
				
			||||||
 | 
					                {beforeBody.map(BodyComponent => <BodyComponent {...componentData} />)}
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
            <Content {...componentData} />
 | 
					            <Content {...componentData} />
 | 
				
			||||||
            <Footer {...componentData} />
 | 
					 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          {RightComponent}
 | 
					          {RightComponent}
 | 
				
			||||||
        </Body>
 | 
					        </Body>
 | 
				
			||||||
 | 
					        <Footer {...componentData} />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </body>
 | 
					    </body>
 | 
				
			||||||
    {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))}
 | 
					    {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -225,7 +225,7 @@ async function renderGraph(container: string, slug: string) {
 | 
				
			|||||||
  const labels = graphNode
 | 
					  const labels = graphNode
 | 
				
			||||||
    .append("text")
 | 
					    .append("text")
 | 
				
			||||||
    .attr("dx", 0)
 | 
					    .attr("dx", 0)
 | 
				
			||||||
    .attr("dy", (d) => nodeRadius(d) - 8 + "px")
 | 
					    .attr("dy", (d) => -nodeRadius(d) + "px")
 | 
				
			||||||
    .attr("text-anchor", "middle")
 | 
					    .attr("text-anchor", "middle")
 | 
				
			||||||
    .text((d) => data[d.id]?.title || (d.id.charAt(1).toUpperCase() + d.id.slice(2)).replace("-", " "))
 | 
					    .text((d) => data[d.id]?.title || (d.id.charAt(1).toUpperCase() + d.id.slice(2)).replace("-", " "))
 | 
				
			||||||
    .style('opacity', (opacityScale - 1) / 3.75)
 | 
					    .style('opacity', (opacityScale - 1) / 3.75)
 | 
				
			||||||
@@ -297,14 +297,3 @@ document.addEventListener("nav", async (e: unknown) => {
 | 
				
			|||||||
  containerIcon?.addEventListener("click", renderGlobalGraph)
 | 
					  containerIcon?.addEventListener("click", renderGlobalGraph)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let resizeEventDebounce: number | undefined = undefined
 | 
					 | 
				
			||||||
window.addEventListener('resize', () => {
 | 
					 | 
				
			||||||
  if (resizeEventDebounce) {
 | 
					 | 
				
			||||||
    clearTimeout(resizeEventDebounce)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  resizeEventDebounce = window.setTimeout(async () => {
 | 
					 | 
				
			||||||
    const slug = document.body.dataset["slug"]!
 | 
					 | 
				
			||||||
    await renderGraph("graph-container", slug)
 | 
					 | 
				
			||||||
  }, 50)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,38 +58,7 @@ const encoder = (str: string) => str.toLowerCase().split(/([^a-z]|[^\x00-\x7F])/
 | 
				
			|||||||
document.addEventListener("nav", async (e: unknown) => {
 | 
					document.addEventListener("nav", async (e: unknown) => {
 | 
				
			||||||
  const currentSlug = (e as CustomEventMap["nav"]).detail.url
 | 
					  const currentSlug = (e as CustomEventMap["nav"]).detail.url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // setup index if it hasn't been already
 | 
					 | 
				
			||||||
  const data = await fetchData
 | 
					  const data = await fetchData
 | 
				
			||||||
  if (!index) {
 | 
					 | 
				
			||||||
    index = new Document({
 | 
					 | 
				
			||||||
      cache: true,
 | 
					 | 
				
			||||||
      charset: 'latin:extra',
 | 
					 | 
				
			||||||
      optimize: true,
 | 
					 | 
				
			||||||
      encode: encoder,
 | 
					 | 
				
			||||||
      document: {
 | 
					 | 
				
			||||||
        id: "slug",
 | 
					 | 
				
			||||||
        index: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            field: "title",
 | 
					 | 
				
			||||||
            tokenize: "forward",
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            field: "content",
 | 
					 | 
				
			||||||
            tokenize: "reverse",
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (const [slug, fileData] of Object.entries<ContentDetails>(data)) {
 | 
					 | 
				
			||||||
      await index.addAsync(slug, {
 | 
					 | 
				
			||||||
        slug,
 | 
					 | 
				
			||||||
        title: fileData.title,
 | 
					 | 
				
			||||||
        content: fileData.content
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const container = document.getElementById("search-container")
 | 
					  const container = document.getElementById("search-container")
 | 
				
			||||||
  const searchIcon = document.getElementById("search-icon")
 | 
					  const searchIcon = document.getElementById("search-icon")
 | 
				
			||||||
  const searchBar = document.getElementById("search-bar") as HTMLInputElement | null
 | 
					  const searchBar = document.getElementById("search-bar") as HTMLInputElement | null
 | 
				
			||||||
@@ -176,6 +145,37 @@ document.addEventListener("nav", async (e: unknown) => {
 | 
				
			|||||||
  searchIcon?.addEventListener("click", showSearch)
 | 
					  searchIcon?.addEventListener("click", showSearch)
 | 
				
			||||||
  searchBar?.removeEventListener("input", onType)
 | 
					  searchBar?.removeEventListener("input", onType)
 | 
				
			||||||
  searchBar?.addEventListener("input", onType)
 | 
					  searchBar?.addEventListener("input", onType)
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // setup index if it hasn't been already
 | 
				
			||||||
 | 
					  if (!index) {
 | 
				
			||||||
 | 
					    index = new Document({
 | 
				
			||||||
 | 
					      cache: true,
 | 
				
			||||||
 | 
					      charset: 'latin:extra',
 | 
				
			||||||
 | 
					      optimize: true,
 | 
				
			||||||
 | 
					      encode: encoder,
 | 
				
			||||||
 | 
					      document: {
 | 
				
			||||||
 | 
					        id: "slug",
 | 
				
			||||||
 | 
					        index: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            field: "title",
 | 
				
			||||||
 | 
					            tokenize: "forward",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            field: "content",
 | 
				
			||||||
 | 
					            tokenize: "reverse",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const [slug, fileData] of Object.entries<ContentDetails>(data)) {
 | 
				
			||||||
 | 
					      await index.addAsync(slug, {
 | 
				
			||||||
 | 
					        slug,
 | 
				
			||||||
 | 
					        title: fileData.title,
 | 
				
			||||||
 | 
					        content: fileData.content
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // register handlers
 | 
					  // register handlers
 | 
				
			||||||
  registerEscapeHandler(container, hideSearch)
 | 
					  registerEscapeHandler(container, hideSearch)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  width: 20px;
 | 
					  width: 20px;
 | 
				
			||||||
  height: 20px;
 | 
					  height: 20px;
 | 
				
			||||||
  margin: 1rem;
 | 
					  margin: 0 10px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & > .toggle {
 | 
					  & > .toggle {
 | 
				
			||||||
    display: none;
 | 
					    display: none;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
footer {
 | 
					footer {
 | 
				
			||||||
  text-align: left;
 | 
					  text-align: left;
 | 
				
			||||||
  opacity: 0.8;
 | 
					 | 
				
			||||||
  margin-bottom: 4rem;
 | 
					  margin-bottom: 4rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & ul {
 | 
					  & ul {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,11 +29,11 @@
 | 
				
			|||||||
    line-height: normal;
 | 
					    line-height: normal;
 | 
				
			||||||
    font-size: initial;
 | 
					    font-size: initial;
 | 
				
			||||||
    font-family: var(--bodyFont);
 | 
					    font-family: var(--bodyFont);
 | 
				
			||||||
    border: 1px solid var(--gray);
 | 
					    border: 1px solid var(--lightgray);
 | 
				
			||||||
    background-color: var(--light);
 | 
					    background-color: var(--light);
 | 
				
			||||||
    border-radius: 5px;
 | 
					    border-radius: 5px;
 | 
				
			||||||
    box-shadow: 6px 6px 36px 0 rgba(0,0,0,0.25);
 | 
					    box-shadow: 6px 6px 36px 0 rgba(0,0,0,0.25);
 | 
				
			||||||
    overflow: scroll;
 | 
					    overflow: auto;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  h1 {
 | 
					  h1 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    & > div {
 | 
					    & > div {
 | 
				
			||||||
      flex-grow: 1;
 | 
					      flex-grow: 1;
 | 
				
			||||||
@@ -38,12 +39,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  & > #search-container {
 | 
					  & > #search-container {
 | 
				
			||||||
    position: fixed;
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    contain: layout;
 | 
				
			||||||
    z-index: 999;
 | 
					    z-index: 999;
 | 
				
			||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
    top: 0;
 | 
					    top: 0;
 | 
				
			||||||
    width: 100vw;
 | 
					    width: 100vw;
 | 
				
			||||||
    height: 100vh;
 | 
					    height: 100vh;
 | 
				
			||||||
    overflow: scroll;
 | 
					    overflow-y: auto;
 | 
				
			||||||
    display: none;
 | 
					    display: none;
 | 
				
			||||||
    backdrop-filter: blur(4px);
 | 
					    backdrop-filter: blur(4px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,7 +59,7 @@
 | 
				
			|||||||
      margin-left: auto;
 | 
					      margin-left: auto;
 | 
				
			||||||
      margin-right: auto;
 | 
					      margin-right: auto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @media all and (max-width: $tabletBreakpoint) {
 | 
					      @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
        width: 90%;
 | 
					        width: 90%;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ button#toc {
 | 
				
			|||||||
  list-style: none;
 | 
					  list-style: none;
 | 
				
			||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
  max-height: none;
 | 
					  max-height: none;
 | 
				
			||||||
  transition: max-height 0.3s ease;
 | 
					  transition: max-height 0.5s ease;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & ul {
 | 
					  & ul {
 | 
				
			||||||
    list-style: none;
 | 
					    list-style: none;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,9 @@ export type QuartzComponentProps = {
 | 
				
			|||||||
  children: (QuartzComponent | JSX.Element)[]
 | 
					  children: (QuartzComponent | JSX.Element)[]
 | 
				
			||||||
  tree: Node<QuartzPluginData>
 | 
					  tree: Node<QuartzPluginData>
 | 
				
			||||||
  allFiles: QuartzPluginData[]
 | 
					  allFiles: QuartzPluginData[]
 | 
				
			||||||
 | 
					  displayClass?: 'mobile-only' | 'desktop-only'
 | 
				
			||||||
 | 
					} & JSX.IntrinsicAttributes & {
 | 
				
			||||||
 | 
					  [key: string]: any
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type QuartzComponent = ComponentType<QuartzComponentProps> & {
 | 
					export type QuartzComponent = ComponentType<QuartzComponentProps> & {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,71 +43,23 @@ a {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.page {
 | 
					 | 
				
			||||||
  & > .page-header {
 | 
					 | 
				
			||||||
    max-width: $pageWidth;
 | 
					 | 
				
			||||||
    margin: $topSpacing auto 0 auto;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  & > #quartz-body {
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    & .left, & .right {
 | 
					 | 
				
			||||||
      flex: 1;
 | 
					 | 
				
			||||||
      width: calc(calc(100vw - $pageWidth) / 2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    & .left-inner, & .right-inner {
 | 
					 | 
				
			||||||
      display: flex;
 | 
					 | 
				
			||||||
      flex-direction: column;
 | 
					 | 
				
			||||||
      gap: 2rem;
 | 
					 | 
				
			||||||
      top: 0;
 | 
					 | 
				
			||||||
      width: $sidePanelWidth;
 | 
					 | 
				
			||||||
      margin-top: $topSpacing;
 | 
					 | 
				
			||||||
      box-sizing: border-box;
 | 
					 | 
				
			||||||
      padding: 0 4rem;
 | 
					 | 
				
			||||||
      position: fixed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    & .left-inner {
 | 
					 | 
				
			||||||
      left: calc(calc(100vw - $pageWidth) / 2 - $sidePanelWidth);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    & .right-inner {
 | 
					 | 
				
			||||||
      right: calc(calc(100vw - $pageWidth) / 2 - $sidePanelWidth);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    & .center {
 | 
					 | 
				
			||||||
      width: $pageWidth;
 | 
					 | 
				
			||||||
      margin: 0 auto;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.desktop-only {
 | 
					.desktop-only {
 | 
				
			||||||
  display: initial;
 | 
					  display: initial;
 | 
				
			||||||
  @media all and (max-width: ($pageWidth + 2 * $sidePanelWidth)) {
 | 
					  @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
    display: none;
 | 
					    display: none;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mobile-only {
 | 
					.mobile-only {
 | 
				
			||||||
  display: none;
 | 
					  display: none;
 | 
				
			||||||
  @media all and (max-width: ($pageWidth + 2 * $sidePanelWidth)) {
 | 
					  @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
    display: initial;
 | 
					    display: initial;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.page {
 | 
					.page {
 | 
				
			||||||
  @media all and (max-width: $tabletBreakpoint) {
 | 
					  @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
    margin: 25px 5vw;
 | 
					    margin: 0 5vw;
 | 
				
			||||||
    & .left, & .right {
 | 
					 | 
				
			||||||
      padding: 0;
 | 
					 | 
				
			||||||
      height: initial;
 | 
					 | 
				
			||||||
      max-width: none;
 | 
					 | 
				
			||||||
      position: initial;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & p {
 | 
					  & p {
 | 
				
			||||||
@@ -129,6 +81,78 @@ a {
 | 
				
			|||||||
      padding-left: 0;
 | 
					      padding-left: 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & > #quartz-body {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    & .left, & .right {
 | 
				
			||||||
 | 
					      flex: 1;
 | 
				
			||||||
 | 
					      width: calc(calc(100vw - $pageWidth) / 2);
 | 
				
			||||||
 | 
					      @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					        width: initial;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    & .left-inner, & .right-inner {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      gap: 2rem;
 | 
				
			||||||
 | 
					      top: 0;
 | 
				
			||||||
 | 
					      width: $sidePanelWidth;
 | 
				
			||||||
 | 
					      margin-top: $topSpacing;
 | 
				
			||||||
 | 
					      box-sizing: border-box;
 | 
				
			||||||
 | 
					      padding: 0 4rem;
 | 
				
			||||||
 | 
					      position: fixed;
 | 
				
			||||||
 | 
					      @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					        position: initial;
 | 
				
			||||||
 | 
					        flex-direction: row;
 | 
				
			||||||
 | 
					        padding: 0;
 | 
				
			||||||
 | 
					        width: initial;
 | 
				
			||||||
 | 
					        margin-top: 4rem;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    & .left-inner {
 | 
				
			||||||
 | 
					      left: calc(calc(100vw - $pageWidth) / 2 - $sidePanelWidth);
 | 
				
			||||||
 | 
					      @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					        gap: 1rem;
 | 
				
			||||||
 | 
					        align-items: center;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    & .right-inner {
 | 
				
			||||||
 | 
					      right: calc(calc(100vw - $pageWidth) / 2 - $sidePanelWidth);
 | 
				
			||||||
 | 
					      & > * {
 | 
				
			||||||
 | 
					        @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					          flex: 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & .page-header {
 | 
				
			||||||
 | 
					    width: $pageWidth;
 | 
				
			||||||
 | 
					    margin: $topSpacing auto 0 auto;
 | 
				
			||||||
 | 
					    @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					      width: initial;
 | 
				
			||||||
 | 
					      margin-top: 2rem;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & .center, & footer {
 | 
				
			||||||
 | 
					    width: $pageWidth;
 | 
				
			||||||
 | 
					    margin-left: auto;
 | 
				
			||||||
 | 
					    margin-right: auto;
 | 
				
			||||||
 | 
					    @media all and (max-width: $fullPageWidth) {
 | 
				
			||||||
 | 
					      width: initial;
 | 
				
			||||||
 | 
					      margin-left: 0;
 | 
				
			||||||
 | 
					      margin-right: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input[type="checkbox"] {
 | 
					input[type="checkbox"] {
 | 
				
			||||||
@@ -200,7 +224,7 @@ pre {
 | 
				
			|||||||
  font-family: var(--codeFont);
 | 
					  font-family: var(--codeFont);
 | 
				
			||||||
  padding: 0.5rem;
 | 
					  padding: 0.5rem;
 | 
				
			||||||
  border-radius: 5px;
 | 
					  border-radius: 5px;
 | 
				
			||||||
  overflow-x: scroll;
 | 
					  overflow-x: auto;
 | 
				
			||||||
  border: 1px solid var(--lightgray);
 | 
					  border: 1px solid var(--lightgray);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & > code {
 | 
					  & > code {
 | 
				
			||||||
@@ -301,3 +325,23 @@ audio, video {
 | 
				
			|||||||
.spacer {
 | 
					.spacer {
 | 
				
			||||||
  flex: 1 1 auto;
 | 
					  flex: 1 1 auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ul.overflow, ol.overflow {
 | 
				
			||||||
 | 
					  height: 400px;
 | 
				
			||||||
 | 
					  overflow-y: scroll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & > li:last-of-type {
 | 
				
			||||||
 | 
					    margin-bottom: 50px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &:after {
 | 
				
			||||||
 | 
					    pointer-events: none;
 | 
				
			||||||
 | 
					    content: '';
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 50px;    
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					    background: linear-gradient(transparent 0px, var(--light));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
$pageWidth: 800px;
 | 
					$pageWidth: 750px;
 | 
				
			||||||
$mobileBreakpoint: 600px;
 | 
					$mobileBreakpoint: 600px;
 | 
				
			||||||
$tabletBreakpoint: 1200px;
 | 
					$tabletBreakpoint: 1200px;
 | 
				
			||||||
$sidePanelWidth: 400px;
 | 
					$sidePanelWidth: 400px;
 | 
				
			||||||
$topSpacing: 6rem;
 | 
					$topSpacing: 6rem;
 | 
				
			||||||
 | 
					$fullPageWidth: $pageWidth + 2 * $sidePanelWidth
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user