:root {
  --font-heading: "Marcellus", serif;
  --font-sign: "Merienda", cursive;
  --font-body: "Merriweather", serif;
  --ink: #22140a;
  --ink-soft: #4a3520;
  --accent: #573515;
  --gold: #f3d9a4;
}

* {
  box-sizing: border-box;
}

/* Keeps the page from jumping sideways when the lightbox hides the scrollbar */
html {
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(to right, rgba(15, 8, 3, 0.55), transparent 25%, transparent 75%, rgba(15, 8, 3, 0.55)) fixed,
    linear-gradient(to bottom, rgba(15, 8, 3, 0.75) 10vh, transparent 60vh, transparent calc(100% - 10vh), rgba(15, 8, 3, 0.9)) scroll,
    #2b1a10 url("assets/background.webp") center top / 50% scroll;
  color: var(--ink);
  font-family: var(--font-body);
  /* Shrinks smoothly with the screen width, between a phone size and the full desktop size */
  font-size: clamp(1.05rem, 0.8rem + 0.9vw, 1.6rem);
  line-height: 1.6;
}

img {
  max-width: 100%;
  display: block;
}

.site-header {
  width: 100%;
  max-width: 1740px;
  margin: 0 auto;
  overflow-x: clip;
}

/* Between 1500px and 1000px the art stays 1500px wide and is cropped equally on both sides; below 1000px it shrinks again with the same crop */
.header-art,
.site-footer img {
  width: max(100%, min(1500px, 150%));
  max-width: none;
  margin-left: 50%;
  translate: -50%;
}

.header-art {
  position: relative;
  container-type: inline-size;
}

.header-art img {
  width: 100%;
}

.header-art img,
.site-footer img {
  user-select: none;
  -webkit-user-drag: none;
}

/* Sits on the empty wooden sign right of the griffin; percentages match header.webp */
.site-title {
  position: absolute;
  left: 59.7%;
  top: 27.6%;
  width: 12.85%;
  height: 18.8%;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: var(--font-sign);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 1.35cqw;
  line-height: 1.1;
  color: var(--gold);
  text-shadow: 0 2px 3px rgba(0, 0, 0, 0.8);
}

/* On narrow screens the text on the sign gets too small, so it moves under the header art */
@media (max-width: 700px) {
  .site-title {
    position: static;
    width: auto;
    height: auto;
    margin-top: 8px;
    font-size: 1.8rem;
  }
}

.site-content {
  flex: 1;
  width: 100%;
  max-width: 1550px;
  margin: 0 auto;
  padding: 24px 12px;
}

/* The parchment frame is sliced so it stretches to any article height */
.article {
  --paper-border: 50px;
  margin-bottom: 72px;
  --padding-inline: clamp(16px, 4vw, 72px);
  --padding-block: calc(clamp(8px, 2vw, 32px) * var(--padding-block-scale, 1));
  --border-block: var(--paper-border);
  padding: var(--padding-block) var(--padding-inline);
  border-style: solid;
  border-width: var(--border-block) var(--paper-border);
  border-image: url("assets/content.webp") 100 fill / var(--paper-border) stretch;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.6));
  isolation: isolate;
  position: relative;
}

/* Lightens the stained parchment behind the text; z-index -1 paints it above the border-image but below the text */
.article::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(250, 240, 215, 0.6);
  border-radius: 24px;
  filter: blur(20px);
}

/* The intro uses a golden-tinted copy of the paper so it does not look like a regular post */
.article-intro {
  --padding-block-scale: 0.1;
  width: 80%;
  margin-inline: auto;
  padding-inline: calc(var(--padding-inline) / 2);
  border-image-source: url("assets/content-intro.webp");
}

.article-intro .article-body > :first-child {
  margin-top: 0;
}

.article-intro .article-body > :last-child {
  margin-bottom: 0;
}

/* Evens out the stains under the text but fades out about halfway to the dark inner frame line, so the paper stays dirty there */
.article-intro::before {
  inset: calc(var(--paper-border) * -0.25) calc(var(--paper-border) * -0.15);
  background: rgba(238, 215, 166, 0.78);
  border-radius: 12px;
  filter: blur(10px);
}

/* A weaker wash up to the dark inner frame line (at ~36% of the top/bottom and ~56% of the side border) keeps the dirt there but brightens it */
.article-intro::after {
  content: "";
  position: absolute;
  inset: calc(var(--paper-border) * -0.6) calc(var(--paper-border) * -0.4);
  z-index: -1;
  background: rgba(238, 215, 166, 0.3);
  border-radius: 4px;
  filter: blur(2px);
}

.article-intro .article-body strong {
  color: var(--accent);
}

.article-header {
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(59, 38, 20, 0.3);
}

.article-title,
.article-body h2,
.article-body h3,
.article-body h4 {
  font-family: var(--font-heading);
  color: var(--accent);
  line-height: 1.2;
}

.article-title {
  margin: 0 0 12px;
  font-size: clamp(1.6rem, 1rem + 1.8vw, 3rem);
}

.article-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  font-size: clamp(1rem, 0.85rem + 0.4vw, 1.3rem);
  color: var(--ink-soft);
  font-style: italic;
}

.author::before {
  content: "✒ ";
}

.tag {
  font-style: normal;
  font-size: clamp(0.85rem, 0.7rem + 0.3vw, 1rem);
  line-height: 1;
  padding: 6px 12px;
  border: 1px solid var(--ink-soft);
  border-radius: 14px;
}

.article-body {
  overflow-wrap: break-word;
}

/* Registered so the fade at the bottom of a collapsed article can dissolve in place while it opens */
@property --fold-reveal {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

/* Long articles start collapsed to this height; main.js decides which ones are long enough */
.article {
  --fold-height: 450px;
}

/* flow-root keeps the first and last child's margins inside in both states; otherwise they collapse outward once overflow: hidden goes away and the text jumps at the end of the opening */
.article-fold {
  display: flow-root;
  /* The box spans the side padding and 24px below the content too, so the clip and mask of a collapsed or opening article do not cut off the frame shadows */
  margin: 0 calc(-1 * var(--padding-inline)) -24px;
  padding: 0 var(--padding-inline) 24px;
}

/* The header's own bottom margin already spaces the text, as it did before flow-root stopped the two margins from merging */
.article-fold > .article-body > :first-child {
  margin-top: 0;
}

/* The mask is only on while collapsed, since it would also clip the frame shadows below the fold */
/* Its bottom 176px is an uneven, blotchy fade down to a faint level that ends exactly on the sheet edge drawn by .fold-end (both made from the same path) */
.article.is-collapsed .article-fold {
  --fold-fade: 176px;
  --fold-reveal: 0;
  max-height: var(--fold-height);
  overflow: hidden;
  mask:
    /* Placed from the bottom, so while the article opens the fade moves down together with the sheet edge */
    linear-gradient(#000, #000) top / 100% calc(100% - var(--fold-fade)) no-repeat,
    url("assets/fold-mask.webp") bottom / 100% var(--fold-fade) no-repeat,
    /* Raised to 1 at the end of the opening, which dissolves the fade together with the sheet */
    linear-gradient(rgb(0 0 0 / var(--fold-reveal)), rgb(0 0 0 / var(--fold-reveal)));
}

/* The edge of another sheet lying over the end of the text, running from top right down to bottom left; it covers the last 104px of the collapsed article */
/* Positioned absolutely so it never changes the article's height; it lines up with the fold's bottom (24px below the text, see .article-fold) and spans the whole paper */
.fold-end {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--padding-block) - 24px);
  height: 104px;
  background: url("assets/fold-line.webp") top / 100% 104px no-repeat;
}

/* Sits on the sheet in the bottom right corner, inside the text area */
.fold-end .read-more {
  position: absolute;
  top: 116px;
  translate: 0 -100%;
  right: var(--padding-inline);
  margin: 0;
}

.fold-end[hidden] {
  display: none;
}

/* A sealed book icon followed by the label; both are sized from the article text size, so the button scales with it */
.read-more {
  display: flex;
  align-items: center;
  gap: 0.55em;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: inherit;
  white-space: nowrap;
  cursor: pointer;
  transition: scale 0.15s;
}

.read-more::before {
  content: "";
  width: 3.6em;
  aspect-ratio: 206 / 161;
  background: url("assets/read-more-book.webp") center / contain no-repeat;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.45));
}

/* The title of a collapsed article opens it too */
.article.is-collapsed:not(.is-expanded) .article-title {
  cursor: pointer;
}

.read-more:hover {
  scale: 1.06;
}


.article-body a {
  color: var(--accent);
}

.article-body h4 {
  margin: 20px 0 8px;
  font-size: 1.15em;
}

.article-body code {
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(87, 53, 21, 0.1);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.9em;
}

.article-body pre {
  margin: 16px 0;
  padding: 12px 16px 12px 40px;
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  background: rgba(87, 53, 21, 0.1);
  overflow-x: auto;
}

.article-body pre code {
  padding: 0;
  background: none;
}

.article-body li::marker {
  color: var(--accent);
}

/* Task list items show their checkbox instead of a bullet */
.article-body li:has(> input[type="checkbox"]) {
  list-style: none;
  margin-left: -1.4em;
}

/* Drawn by hand, since the browser's disabled checkbox is tiny and grey */
.article-body li > input[type="checkbox"] {
  appearance: none;
  font: inherit;
  display: inline-grid;
  place-content: center;
  width: 0.9em;
  height: 0.9em;
  margin: 0 0.45em 0 0;
  /* middle centres on the x-height; the small lift centres it on capitals too, and it works the same with or without the ✓ inside */
  vertical-align: middle;
  position: relative;
  top: -0.08em;
  border: 2px solid var(--accent);
  border-radius: 3px;
}

.article-body li > input[type="checkbox"]:checked::after {
  content: "✓";
  color: var(--accent);
  font-size: 0.8em;
  font-weight: bold;
  line-height: 1;
}

/* A line fading out at both ends with a small ornament in a gap in the middle */
.article-body hr {
  position: relative;
  width: 70%;
  height: 1px;
  margin: 36px auto;
  border: 0;
  overflow: visible;
  background: linear-gradient(to right, transparent, var(--accent) 30%, transparent 46%, transparent 54%, var(--accent) 70%, transparent);
}

.article-body hr::after {
  content: "✦";
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  color: var(--accent);
  font-size: 1.1em;
  line-height: 1;
}

.article-photo {
  display: block;
  width: fit-content;
  max-width: min(100%, 720px);
  margin: 20px auto;
  cursor: zoom-in;
}

.article-photo img {
  display: block;
  max-width: 100%;
  height: auto;
}

.article-body blockquote {
  margin: 16px 0;
  padding: 4px 16px 4px 40px;
  border-left: 3px solid var(--accent);
  font-style: italic;
}

/* The table reaches out by half its edge padding, so the fading line ends spill a little into the paper margin */
.table-wrap {
  --table-edge: clamp(24px, 5vw, 80px);
  margin: 24px calc(-0.5 * var(--table-edge));
  overflow-x: auto;
}

/* Lines between cells are hand-drawn SVGs painted as cell backgrounds, since real borders can only be straight */
.article-body table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

/* Each cell paints its bottom line (--line-h) and right line (--line-v); cells on the table edge use fading versions */
.article-body th,
.article-body td {
  --line-h: url("assets/line-h.svg") left bottom / 320px 8px repeat-x;
  --line-v: url("assets/line-v.svg") right top / 8px 320px repeat-y;
  padding: 16px 24px;
  background: var(--line-h), var(--line-v);
}

.article-body th {
  --line-h: url("assets/line-h-accent.svg") left bottom / 320px 8px repeat-x;
  --line-v: url("assets/line-v-fade-start.svg") right top / 8px 100% no-repeat;
  color: var(--accent);
  font-weight: bold;
  white-space: nowrap;
}

.article-body th:first-child {
  --line-h: url("assets/line-h-accent-fade-start.svg") left bottom / 100% 8px no-repeat;
}

.article-body th:last-child {
  --line-h: url("assets/line-h-accent-fade-end.svg") left bottom / 100% 8px no-repeat;
  --line-v: none;
}

.article-body td:first-child {
  --line-h: url("assets/line-h-fade-start.svg") left bottom / 100% 8px no-repeat;
}

.article-body td:last-child {
  --line-h: url("assets/line-h-fade-end.svg") left bottom / 100% 8px no-repeat;
  --line-v: none;
}

.article-body tr:last-child td {
  --line-h: none;
  --line-v: url("assets/line-v-fade-end.svg") right top / 8px 100% no-repeat;
}

.article-body tr:last-child td:last-child {
  --line-v: none;
}

/* Extra room on the outer side of edge cells, so the fading line ends have space to fade */
.article-body thead th {
  padding-top: 56px;
}

.article-body tr:last-child td {
  padding-bottom: 64px;
}

.article-body th:first-child,
.article-body td:first-child {
  padding-left: var(--table-edge);
}

.article-body th:last-child,
.article-body td:last-child {
  padding-right: var(--table-edge);
}

/* Markdown column alignment (|---:|) comes as an align attribute, so only unaligned headers get forced left */
.article-body th:not([align]) {
  text-align: left;
}

.article-body td:first-child,
.article-body td[align="right"] {
  white-space: nowrap;
}

.article-body td:first-child {
  font-weight: bold;
}

/* On narrow screens rows stay one line tall and the table scrolls sideways instead */
@media (max-width: 700px) {
  .article-body td {
    white-space: nowrap;
  }
}

.gallery {
  container-type: inline-size;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
  margin-top: 20px;
}

.gallery-item {
  display: block;
  width: calc((100% - 32px) / 3);
  cursor: zoom-in;
}

@container (max-width: 700px) {
  .gallery-item {
    width: calc((100% - 16px) / 2);
  }
}

@container (max-width: 420px) {
  .gallery-item {
    width: 100%;
  }
}

.gallery-item img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Hides the zoomed photo's edges, so only transform animates on hover; animating a clip-path together with it made Chrome drop the photo for a frame */
.photo-crop {
  display: block;
  overflow: hidden;
}

.photo-crop img {
  transition: transform 0.25s;
}

.gallery-item:hover img,
.article-photo:hover img {
  transform: scale(1.1);
}

/* A smaller copy of the lightbox caption scroll, unrolled at the bottom of the thumbnail on hover, overlapping the bottom plank like in the lightbox */
/* Centred with margin: auto instead of translate and drawn at exactly 0.4 scale, so the scroll pieces land on whole pixels without light seams */
.gallery-caption {
  position: absolute;
  inset: auto 0 calc(0.25 * var(--frame));
  margin-inline: auto;
  width: max-content;
  max-width: calc(100% - 1.3 * var(--frame));
  z-index: 1;
  overflow: hidden;
  padding: 10px 16px 0;
  border-style: solid;
  border-width: 12px 36px 18px 32px;
  border-image: url("assets/caption-scroll.webp") 30 90 45 80 fill round stretch;
  color: var(--ink);
  font-size: 1.15rem;
  line-height: 1.3;
  text-align: center;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.6));
  opacity: 0;
  pointer-events: none;
  /* Long captions are cut so the scroll stays inside the thumbnail; the full text is in the lightbox */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 5;
}

/* Small thumbnails in the three- and two-column layouts only have room for three lines */
@container (min-width: 701px) and (max-width: 850px) {
  .gallery-caption {
    -webkit-line-clamp: 3;
  }
}

@container (min-width: 421px) and (max-width: 560px) {
  .gallery-caption {
    -webkit-line-clamp: 3;
  }
}

/* Paper colour under the joins of the scroll pieces, so a partly covered pixel there shows paper instead of a light line */
.lightbox-caption,
.gallery-caption {
  background: linear-gradient(#e7d0a4, #e7d0a4) -6px 0 / calc(100% + 12px) 100% no-repeat padding-box border-box;
}

.gallery-item:hover .gallery-caption {
  opacity: 1;
}

/* Registered so the frame thickness can animate between the thumbnail and the full-size photo */
@property --frame {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

/* --frame is the size of a corner plate; the photo starts just under the inner edge of the planks (0.62 of a plate) */
.photo-frame {
  --frame: 56px;
  position: relative;
  padding: calc(var(--frame) * 0.58 - 1px);
}

/* Frames on the page are 81% of the lightbox frame; the opening animation grows them to full size */
.gallery-item,
.article-photo {
  --frame: 45.36px;
}

/* The corners stay as they are and the planks between them repeat to fit any photo size */
.photo-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--frame) solid transparent;
  border-image: url("assets/photo-frame.webp") 120 round;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.6));
  pointer-events: none;
}

/* While the copy fades in or out over the thumbnail only the thumbnail's shadow shows, so the two never stack */
.lightbox-flyer::after {
  transition: filter 0.15s;
}

.lightbox-flyer.is-on-thumb::after {
  filter: none;
}

.load-more {
  padding: 24px;
  text-align: center;
  color: var(--gold);
  font-family: var(--font-heading);
}

.site-footer {
  width: 100%;
  max-width: 1550px;
  margin: 0 auto;
  padding: 0 12px;
  position: relative;
  z-index: 2;
  overflow-x: clip;
}

.site-footer::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(15, 8, 3, 0.6), transparent 35%);
  pointer-events: none;
}

/* No dark overlay, only a soft blur of the page; the layer also catches clicks outside the photo */
.lightbox {
  --button: 88px;
  position: fixed;
  inset: 0;
  z-index: 101;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(6px);
  touch-action: none;
}

.lightbox[hidden] {
  display: none;
}

.lightbox-box {
  margin: 0;
}

/* The zoomed photo moves inside this box, so it never spills over the frame */
.lightbox-view {
  overflow: hidden;
}

/* object-fit keeps the photo from stretching while the size animates between two photos */
.lightbox-image {
  display: block;
  max-width: calc(100vw - 8px - 2 * var(--button) - 0.54 * var(--frame));
  max-height: calc(72vh - 1.16 * var(--frame));
  object-fit: cover;
  cursor: pointer;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: 0 0;
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Dragging and pinching follow the fingers directly */
.lightbox-image.is-dragging {
  transition: none;
}

.lightbox-image.is-over-middle {
  cursor: zoom-in;
}

.lightbox-view.is-zoomed .lightbox-image {
  cursor: grab;
}

.lightbox-view.is-zoomed .lightbox-image:active {
  cursor: grabbing;
}

@media (prefers-reduced-motion: reduce) {
  .lightbox-image {
    transition: none;
  }
}

/* Hangs below the photo outside the layout, so photos with and without a caption are centred the same way; it overlaps the bottom plank a little */
.lightbox-caption {
  position: absolute;
  top: 100%;
  left: 50%;
  translate: -50%;
  width: max-content;
  z-index: 1;
  max-width: min(640px, calc(100vw - 32px));
  margin-top: calc(-0.45 * var(--frame));
  overflow: hidden;
  /* The paper starts lower in the scroll image than it ends, so the extra top padding centres the text on the paper */
  padding: 12px 24px 0;
  border-style: solid;
  border-width: 15px 45px 22px 40px;
  border-image: url("assets/caption-scroll.webp") 30 90 45 80 fill round stretch;
  color: var(--ink);
  font-size: 1.2rem;
  line-height: 1.4;
  text-align: center;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.6));
}

.lightbox-caption:empty {
  display: none;
}

.lightbox button {
  position: absolute;
  z-index: 1;
  width: var(--button);
  height: var(--button);
  padding: 0;
  border: none;
  background: center / contain no-repeat;
  cursor: pointer;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.6));
  transition: scale 0.15s;
}

.lightbox button:hover {
  scale: 1.08;
}

.lightbox button[hidden] {
  display: none;
}

/* The arrows sit at the sides of the frame, reaching 12px past the middle of the side planks */
.lightbox .lightbox-prev {
  top: calc(50% - var(--button) / 2);
  left: calc(0.31 * var(--frame) - var(--button) + 12px);
  background-image: url("assets/button-prev.webp");
}

.lightbox .lightbox-next {
  top: calc(50% - var(--button) / 2);
  right: calc(0.31 * var(--frame) - var(--button) + 12px);
  background-image: url("assets/button-next.webp");
}

/* Centred where the middles of the top and right planks meet */
.lightbox .lightbox-close {
  top: calc(0.31 * var(--frame) - var(--button) / 2);
  right: calc(0.31 * var(--frame) - var(--button) / 2);
  background-image: url("assets/button-close.webp");
}

/* While the flying copy animates, the real photo and frame stay invisible; the buttons and caption animate on their own */
.lightbox.is-animating .lightbox-image,
.lightbox.is-animating .lightbox-box::after {
  visibility: hidden;
}

/* The photo is a background limited to the area inside the frame, cropped the same way as the thumbnail */
/* Lives inside the lightbox during the flight and carries the buttons and caption with it */
.lightbox-flyer {
  position: fixed;
  z-index: 100;
  background: center / cover no-repeat content-box;
  pointer-events: none;
}

/* Lives inside the lightbox before the frame, so it is not blurred and the new photo fades in over it */
.lightbox-previous {
  position: fixed;
  z-index: 0;
  background: center / cover no-repeat;
  pointer-events: none;
}

@media (max-width: 600px) {
  .photo-frame {
    --frame: 36px;
  }

  .lightbox {
    --button: 52px;
  }
}

/* On smaller screens the paper's left and right edges are pushed off-screen, so only its top and bottom edges show */
@media (max-width: 1500px) {
  .site-content {
    padding-inline: 0;
    overflow-x: clip;
  }

  /* The paper edge is still drawn at full size, but the text may start over its inner, plain part */
  .article {
    --border-block: calc(var(--paper-border) / 2);
    margin-bottom: 36px;
    margin-inline: calc(-1 * var(--paper-border));
    --padding-inline: clamp(11px, 2.8vw, 50px);
    --padding-block: calc(clamp(6px, 1.4vw, 22px) * var(--padding-block-scale, 1));
  }

  /* The narrower intro keeps its paper edges on-screen */
  .article-intro {
    margin-inline: auto;
    padding-inline: calc(var(--padding-inline) / 2);
  }

  .article-intro::before {
    inset: calc(var(--paper-border) * -0.12) calc(var(--paper-border) * -0.15);
  }

  .article-intro::after {
    inset: calc(var(--paper-border) * -0.3) calc(var(--paper-border) * -0.4);
  }

  /* The bottom padding is smaller here than the 24px the sheet reaches below the text, so the button is lifted to end with the text area */
  .fold-end .read-more {
    top: auto;
    bottom: max(0px, 24px - var(--padding-block));
    translate: none;
  }

  /* Thumbnail frames shrink with the window, from 45.36px at 1500px down to 29.16px (81% of 56px → 36px) */
  .gallery-item,
  .article-photo {
    --frame: clamp(29.16px, 3.024vw, 45.36px);
  }
}

@media (max-width: 600px) {
  .article {
    --paper-border: 30px;
  }

  /* The paper's bottom edge is thin on phones, so the button ends exactly with the text area (the sheet reaches 24px below it) */
  .fold-end .read-more {
    bottom: 24px;
  }
}

/* On phones 80% is too cramped, so the intro goes full width like the posts */
@media (max-width: 700px) {
  .article-intro {
    width: auto;
    margin-inline: calc(-1 * var(--paper-border));
    padding-inline: var(--padding-inline);
  }
}
