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) => (
-
- {heading.text}
+
+
+ {heading.text}
+
))}
)}
+
+
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);