diff --git a/src/assets/content/articles/prima-materia/john_martin_-_the_great_day_of_his_wrath_-_google_art_project.jpg b/src/assets/content/articles/prima-materia/john_martin_-_the_great_day_of_his_wrath_-_google_art_project.jpg new file mode 100644 index 0000000..03d0afc Binary files /dev/null and b/src/assets/content/articles/prima-materia/john_martin_-_the_great_day_of_his_wrath_-_google_art_project.jpg differ diff --git a/src/components/media/Figure.astro b/src/components/media/Figure.astro index 4dcb9cb..025b8ab 100644 --- a/src/components/media/Figure.astro +++ b/src/components/media/Figure.astro @@ -55,3 +55,24 @@ const resolved = resolveImage(image) )} + + diff --git a/src/components/post/ToC.astro b/src/components/post/ToC.astro index a5f28e1..58a6f95 100644 --- a/src/components/post/ToC.astro +++ b/src/components/post/ToC.astro @@ -4,7 +4,7 @@ import type { Heading } from '@/lib/markdoc/types' type Props = { headings: Heading[] min?: number - level: number + level?: number } const { headings, min = 3, level = 3 } = Astro.props @@ -19,9 +19,81 @@ const entries = headings.filter((heading) => heading.level <= level)
    {entries.map((heading) => (
  1. - {heading.text} + +
  2. ))}
)} + + diff --git a/src/content/general/articles/prima-materia.mdoc b/src/content/general/articles/prima-materia.mdoc index 0fa86b6..6aa2bb6 100644 --- a/src/content/general/articles/prima-materia.mdoc +++ b/src/content/general/articles/prima-materia.mdoc @@ -25,7 +25,7 @@ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliqu ## Heading two, long enough to wrap onto a second line -Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur{% footnote note="A footnote with *emphasis* and a [link](https://example.com)." /%}. Excepteur sint occaecat cupidatat non proident{% sidenote marker="†" note="A sidenote in the margin, beside the line it belongs to." /%}. +Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur{% footnote note="A footnote with *emphasis* and a [link](https://example.com)." /%}. Excepteur sint occaecat cupidatat non proident{% sidenote type="default" marker="†" note="A sidenote in the margin, beside the line it belongs to." /%}. ### Heading three @@ -45,18 +45,21 @@ At vero eos et accusamus et iusto odio dignissimos ducimus. - Third level 1. First step -2. Second step +1. Second step 1. Sub-step - 2. Another sub-step -3. Third step + 1. Another sub-step +1. Third step ## Quotes and rules > A plain blockquote, no attribution. -> +> > With a second paragraph. -{% quote cite="Paracelsus" source="Die dritte Defension" href="https://example.com" %} +{% quote + cite="Paracelsus" + source="Die dritte Defension" + href="https://example.com" %} All things are poison, and nothing is without poison; the dosage alone makes it so a thing is not a poison. {% /quote %} @@ -113,8 +116,15 @@ for (const [key, value] of Object.entries(crucible)) { ## Images -{% figure image="/src/assets/content/articles/type-specimen/example.png" alt="A placeholder image" caption="An inline figure with a caption" credit="Dave Damage" size="inline" ratio="16-9" effect="none" /%} +{% figure + image="/src/assets/content/articles/prima-materia/john_martin_-_the_great_day_of_his_wrath_-_google_art_project.jpg" + alt="A placeholder image" + caption="An inline figure with a caption" + credit="Dave Damage" + effect="none" + ratio="16-9" + size="inline" /%} -Aliquam erat volutpat. Fusce sed velit at arcu tincidunt vulputate{% sidenote marker="‡" type="example" note="A second sidenote, typed as an example." /%}. Nam vitae lacus a nisl ultrices dictum. +Aliquam erat volutpat. Fusce sed velit at arcu tincidunt vulputate{% sidenote type="example" marker="‡" note="A second sidenote, typed as an example." /%}. Nam vitae lacus a nisl ultrices dictum. Finally, a link to another article: {% xref reference="the-crucible" %}The Crucible{% /xref %}. diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 542975d..d3dad08 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -42,6 +42,9 @@ const previewUrl = preview ? new URL(preview.src, Astro.site) : undefined + diff --git a/src/layouts/general/ArticleLayout.astro b/src/layouts/general/ArticleLayout.astro index be291d6..24f5b25 100644 --- a/src/layouts/general/ArticleLayout.astro +++ b/src/layouts/general/ArticleLayout.astro @@ -1,9 +1,9 @@ --- import DevBanner from '@/components/dev/DevBanner.astro' import FootnoteList from '@/components/markdoc/blocks/general/FootnoteList.astro' -import SidenoteList from '@/components/markdoc/blocks/general/SidenoteList.astro' import Node from '@/components/markdoc/Node.astro' import ArticleHeader from '@/components/post/Header/ArticleHeader.astro' +import ToC from '@/components/post/ToC.astro' import BaseLayout from '@/layouts/BaseLayout.astro' import type { Rendered } from '@/lib/markdoc/types' import { metaOf } from '@/lib/site/meta' @@ -20,17 +20,21 @@ const meta = metaOf(article)
- +
+
+ +
+
+ +
-
.frame { @mixin layout-wrapper; + @mixin my var(--size-12); - position: relative; + display: flex; + flex-direction: column; + gap: var(--layout-gutter); @media (--bp-desktop) { display: grid; - grid-template-columns: var(--layout-content-width) var(--layout-margin-width); + grid-template-columns: + [rail-start] minmax(var(--layout-rail-width), 1fr) + [rail-end body-start] var(--layout-content-width) + [body-end margin-start] var(--layout-margin-width) [margin-end]; gap: var(--layout-gutter); align-items: start; } } + .body { + position: relative; + } + + .rail, .body, - .margin { + .margin, + .notes { min-width: 0; } + + @media (--bp-desktop) { + .rail { + grid-column: rail-start / rail-end; + grid-row: 1 / 3; + align-self: stretch; + } + + .body { + grid-column: body-start / body-end; + } + + .margin { + grid-column: margin-start / margin-end; + grid-row: 1 / 3; + } + + .notes { + grid-column: body-start / body-end; + } + } diff --git a/src/lib/markdoc/tags.ts b/src/lib/markdoc/tags.ts index e58218d..3d5ecc1 100644 --- a/src/lib/markdoc/tags.ts +++ b/src/lib/markdoc/tags.ts @@ -50,22 +50,16 @@ export function createTags(state: NodeState, resolveLink: ResolveLink): Record"; +} + +@layer components { + .prose { + @mixin typo_body; + + counter-reset: sec sub tbl fig; + + & > :first-child { + margin-block-start: var(--size-0); + } + + & > :last-child { + margin-block-end: var(--size-0); + } + + & ::selection { + color: var(--color-text-on-accent); + background-color: var(--color-primary); + } + + /* === Paragraphs === */ + & p { + @mixin my var(--space-6); + text-wrap: pretty; + } + + /* === HEADINGS === */ + & h2 { + @mixin typo_heading-2; + @mixin mt var(--space-11); + @mixin mb var(--space-8); + @mixin ps var(--size-9); + counter-set: sub 0 fig 0; + counter-increment: sec; + + clear: both; + display: flex; + flex-direction: column; + gap: var(--space-4); + + border-inline-start: var(--slot-prose-bar) solid var(--color-text-primary); + + text-wrap: balance; + + &::before { + @mixin pt var(--space-4); + content: "§ " counter(sec, upper-roman); + + font-family: var(--font-mono); + font-size: 0.8125rem; + font-weight: var(--font-weight-emphasis); + line-height: 1; + letter-spacing: var(--tracking-label); + } + } + + & h3 { + @mixin typo_heading-3; + @mixin mt var(--space-10); + @mixin mb var(--space-7); + @mixin py var(--size-3); + @mixin px var(--size-7); + counter-increment: sub; + + display: flex; + gap: var(--size-7); + align-items: baseline; + + color: var(--color-text-inverse); + + background-color: var(--color-surface-inverse); + + &::before { + content: counter(sec, upper-roman) "." counter(sub); + + font-family: var(--font-mono); + font-size: 0.8125rem; + font-weight: var(--font-weight-emphasis); + color: var(--color-primary); + } + } + + & h4 { + @mixin typo_heading-4; + @mixin mt var(--space-9); + @mixin mb var(--space-6); + @mixin py var(--size-2); + border-block: var(--border-shell) solid var(--color-text-primary); + } + + /* === LISTS === */ + + & ul, + & ol { + @mixin my var(--space-6); + @mixin pl var(--size-0); + + display: flex; + flex-direction: column; + gap: var(--space-4); + list-style: none; + + & li { + --prose-line: 1lh; + display: grid; + grid-template-columns: var(--slot-prose-marker) minmax(0, 1fr); + column-gap: var(--slot-prose-gap); + + & > * { + grid-column: 2; + } + + & > ul, + & > ol { + @mixin mt var(--space-3); + @mixin mb var(--size-0); + gap: var(--space-3); + } + } + } + + & ul { + & > li { + &::before { + content: ""; + + justify-self: center; + + width: 0.625rem; + height: 0.625rem; + margin-block-start: calc((var(--prose-line) - 0.625rem) / 2); + + background-color: var(--color-text-primary); + } + + & ul { + & > li { + &::before { + background-color: transparent; + box-shadow: inset 0 0 0 var(--border-card) var(--color-text-primary); + } + } + + & ul { + & > li { + &::before { + height: var(--size-2); + margin-block-start: calc((var(--prose-line) - var(--size-2)) / 2); + background-color: var(--color-text-primary); + box-shadow: none; + } + } + } + } + } + } + + & ol { + counter-reset: step; + + & > li { + counter-increment: step; + + &::before { + content: counter(step, decimal-leading-zero); + + display: grid; + place-items: center; + + height: 1.375rem; + margin-block-start: calc((var(--prose-line) - 1.375rem) / 2); + + font-family: var(--font-mono); + font-size: 0.75rem; + font-weight: var(--font-weight-emphasis); + line-height: 1; + color: var(--color-text-inverse); + + background-color: var(--color-surface-inverse); + } + + & ol { + & > li { + &::before { + content: counter(step, lower-alpha); + color: var(--color-text-primary); + background-color: transparent; + box-shadow: inset 0 0 0 var(--border-card) var(--color-text-primary); + } + } + } + } + } + + /* === QUOTES & RULES === */ + & blockquote { + @mixin my var(--space-6); + @mixin ps 3ch; + font-style: italic; + color: var(--color-text-secondary); + } + + & hr { + @mixin my var(--space-10); + @mixin border-t var(--border-hairline), solid, var(--color-border-strong); + border-block-end: none; + border-inline: none; + } + + /* === INLINE === */ + & :not(pre) { + & > code { + @mixin px var(--space-2); + @mixin py var(--space-px); + font-family: var(--font-mono); + font-size: 0.875em; + background-color: var(--color-surface-elevated-3); + } + } + + & sup { + font-family: var(--font-mono); + font-size: 0.7em; + } + + & pre { + @mixin typo_code; + @mixin my var(--space-9); + @mixin py var(--size-7); + @mixin px var(--size-8); + overflow: auto; + border: var(--border-card) solid var(--color-border-strong); + tab-size: 2; + background-color: var(--color-surface-elevated-1); + + & code { + @mixin pa var (--size-0); + font: inherit; + background-color: transparent; + } + } + + & a { + color: var(--color-text-link); + text-decoration: underline; + text-decoration-thickness: var(--size-1); + text-underline-offset: var(--size-2); + + transition: color var(--motion-fast) var(--ease-out); + + &:visited { + color: var(--color-text-link-visited); + } + + &:hover { + color: var(--color-text-link-hover); + } + + &:focus-visible { + @mixin focus-ring; + } + } + + & em { + font-style: italic; + } + + & b, + & strong { + font-weight: var(--font-weight-emphasis); + } + + & mark { + @mixin px var(--size-1); + color: var(--color-text-on-accent); + background-color: var(--color-tertiary); + } + + & del, + & s { + color: var(--color-text-tertiary); + text-decoration: line-through; + } + + /* === TABLES === */ + table { + @mixin typo_table-data; + @mixin my var(--space-10); + border-spacing: 0; + border-collapse: separate; + width: 100%; + + & th, + & td { + @mixin py var(--space-4); + @mixin px var(--space-6); + @mixin border-b var(--border-hairline), solid, var(--color-border-subtle); + } + + & thead { + & th { + @mixin typo_table-header; + @mixin border-b var(--border-card), solid, var(--color-border-strong); + } + } + + & tbody { + & tr { + &:last-child { + & :is(th, td) { + @mixin border-b var(--border-card), solid, var(--color-border-strong); + } + } + + &:hover { + background-color: var(--color-surface-hover); + } + } + + & th[scope="row"] { + font-family: var(--font-header); + font-weight: var(--font-weight-heading); + text-transform: uppercase; + } + } + } + + & :is(tfoot, tr.total) { + & :is(th, td) { + @mixin border-t var(--border-card), solid, var(--color-border-strong); + } + } + + & .num { + font-variant-numeric: tabular-nums; + text-align: right; + white-space: nowrap; + } + + & .key { + font-weight: var(--font-weight-emphasis); + } + + td.text { + font-family: var(--font-body); + font-size: 1.077em; + line-height: 1.55; + color: var(--color-text-secondary); + text-wrap: pretty; + } + } +} diff --git a/src/styles/global.css b/src/styles/global.css index ce88068..9faeea6 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,8 +1,5 @@ -@layer reset, tokens, base, components, utilities; - -@import url("base/foundation.css"); -@import url("base/colors.css"); -@import url("base/primitives.css"); +@import url("base/index.css"); +@import url("components/index.css"); @layer base { body { diff --git a/src/styles/mixins/helpers.css b/src/styles/mixins/helpers.css index 19e69f0..0b25cd8 100644 --- a/src/styles/mixins/helpers.css +++ b/src/styles/mixins/helpers.css @@ -3,7 +3,7 @@ @mixin px var(--layout-page-margin); width: 100%; - max-width: var(--layout-max-width); + max-width: var(--layout-wrapper-width); @media screen and (--bp-desktop) { @mixin px var(--space-0); diff --git a/src/styles/mixins/typography.css b/src/styles/mixins/typography.css index c02f236..0633688 100644 --- a/src/styles/mixins/typography.css +++ b/src/styles/mixins/typography.css @@ -8,29 +8,29 @@ @define-mixin typo_heading-2 { font-family: var(--font-header); - font-size: var(--type-7); + font-size: var(--type-4); font-weight: var(--font-weight-heading); - line-height: var(--leading-7); + line-height: var(--leading-4); text-transform: uppercase; - letter-spacing: var(--tracking-7); + letter-spacing: var(--tracking-4); } @define-mixin typo_heading-3 { font-family: var(--font-header); - font-size: var(--type-6); + font-size: var(--type-1); font-weight: var(--font-weight-heading); - line-height: var(--leading-6); + line-height: var(--leading-1); text-transform: uppercase; - letter-spacing: var(--tracking-6); + letter-spacing: var(--tracking-1); } @define-mixin typo_heading-4 { font-family: var(--font-header); - font-size: var(--type-5); - font-weight: var(--font-weight-emphasis); - line-height: var(--leading-5); + font-size: var(--type-0); + font-weight: var(--font-weight-label); + line-height: var(--leading--1); text-transform: uppercase; - letter-spacing: var(--tracking-5); + letter-spacing: var(--tracking-label); } @define-mixin typo_code { @@ -43,11 +43,11 @@ @define-mixin typo_table-header { font-family: var(--font-header); - font-size: var(--type--1); + font-size: var(--type--2); font-weight: var(--font-weight-emphasis); line-height: var(--leading-0); text-transform: uppercase; - letter-spacing: var(--tracking-0); + letter-spacing: var(--tracking-label); } @define-mixin typo_table-data { @@ -68,7 +68,7 @@ } @define-mixin typo_definition-data { - font-family: var(--font-mono); + font-family: var(--font-body); font-size: var(--type--1); font-weight: var(--font-weight-body); line-height: var(--leading--1);