/* The blog, in the clothes of the rest of the site: the same dark ground,
   the same paper and ink, the same EB Garamond. Each post is one long sheet.

   What is inside the sheet keeps Paragraph's layout: the column is 704px as
   it was, so every picture shows at the size it did (its own size, or the
   column's if it is wider); a picture floated right takes half the column
   and drops under the text on a phone; captions sit centred under their
   picture; and the gaps between paragraphs, headings, lists and pictures
   are Paragraph's, only set in rem. */

@font-face{font-family:"EB Garamond";font-style:normal;font-weight:400 800;font-display:swap;
  src:local("EB Garamond"),url(fonts/eb-garamond.woff2) format("woff2")}
@font-face{font-family:"EB Garamond";font-style:italic;font-weight:400 800;font-display:swap;
  src:local("EB Garamond Italic"),url(fonts/eb-garamond-italic.woff2) format("woff2")}

:root{
  --dark:#333331;
  --paper:#f4f1e4;
  --ink:#262420;
  --ghost:#8c8674;
  --quiet:#6c6656;      /* captions and dates: the ghost, dark enough to read on paper */
  --rule:#d4cdb8;
  --light:#e6e2d2;      /* type on the dark ground, as on the index */
  --column:44rem;       /* 704px: Paragraph's column */
  --gutter:clamp(1.25rem, 6vw, 4.5rem);
  color-scheme:dark;
  box-sizing:border-box;
}
*,*::before,*::after{box-sizing:inherit}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{margin:0;background:var(--dark);color:var(--light);
  font-family:"EB Garamond","Iowan Old Style","Hoefler Text",Garamond,Georgia,serif;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  font-feature-settings:"kern","liga","onum";overflow-x:hidden}
a{color:inherit}

/* ---------- the dark around the paper ---------- */
/* The blog's name, over every page but the index, which it heads itself:
   his name goes back to the site, the wandering about to the index */
.top{max-width:calc(var(--column) + 2 * var(--gutter));margin:0 auto;padding:1.6rem var(--gutter) 1.4rem;
  font-size:1.15rem;letter-spacing:.01em;color:rgba(230,226,210,.85)}
.top a,.bar a,.index>h1 a{text-decoration:none;text-underline-offset:.18em;text-decoration-thickness:1px}
.top a:hover,.bar a:hover,.index>h1 a:hover{text-decoration:underline;color:var(--light)}
/* on a post, a ← before the name: back to the index, at this post's card;
   as quiet as the arrows beside the post, and lit the same way */
.top .back,.bar .back{display:inline-block;margin-right:.55em;opacity:.6;transition:opacity .2s}
.top .back:hover,.bar .back:hover{opacity:1;text-decoration:none}
/* where there is room it hangs in the margin, so the name stays in line
   with the text of the sheet under it */
@media (min-width:40rem){.top .back,.bar .back{width:1.6em;margin-left:-1.6em;margin-right:0}}
.foot{display:flex;gap:.7em;justify-content:center;padding:3rem 1rem 3.5rem;
  font-size:1rem;color:var(--light);opacity:.7}
.foot a{text-decoration:none}
.foot a:hover{text-decoration:underline;text-underline-offset:.2em}

/* ---------- going back up ----------
   The grey bar comes down as you scroll back up and goes again as you read
   on. At the top, pulling on zooms out of the post: it draws back, smaller,
   and far enough it goes back where it came from. */
.bar{position:fixed;top:0;left:0;right:0;z-index:50;background:rgba(72,72,69,.92);
  -webkit-backdrop-filter:blur(10px) saturate(1.1);backdrop-filter:blur(10px) saturate(1.1);
  box-shadow:0 1px 0 rgba(255,255,255,.05),0 6px 24px -10px rgba(0,0,0,.6);
  transform:translateY(-105%);transition:transform .32s cubic-bezier(.2,.7,.2,1)}
.bar.on{transform:none}
.bar p{max-width:calc(var(--column) + 2 * var(--gutter));margin:0 auto;
  padding:.8rem var(--gutter) .75rem;padding-top:max(.8rem,env(safe-area-inset-top));
  color:var(--light);font-size:1.15rem;letter-spacing:.01em}
/* the browser's own pull at the top of a post or the index (to refresh, on
   a phone) is off: pulling there is the way back, to the index or the site */
html:has(>body.post),body.post,html:has(>body.front),body.front{overscroll-behavior-y:none}
/* the index going back to the site: it sinks into the dark */
.leaving main,.leaving .pullnote,.leaving .foot{transition:transform .38s cubic-bezier(.4,0,.6,1),opacity .38s}
.leaving main{transform:translateY(4rem) scale(.8)!important;transform-origin:50% var(--pull-oy,0px);opacity:0!important}
.leaving .pullnote,.leaving .foot{opacity:0!important}
.pulling main{transform:translateY(calc(var(--pullk,0) * 3rem)) scale(calc(1 - var(--pullk,0) * .12));
  transform-origin:50% var(--pull-oy,0px);opacity:calc(1 - var(--pullk,0) * .25)}
.pulling .top{opacity:clamp(0,calc(1 - var(--pullk,0) * 3),1)}
.letgo main,.letgo .top,.letgo .pullnote{transition:transform .3s cubic-bezier(.2,.7,.2,1),opacity .3s}
/* where the pull goes, coming down above the post as it draws back */
.pullnote{position:fixed;top:0;left:0;right:0;z-index:40;margin:0;pointer-events:none;
  padding:max(1.2rem,env(safe-area-inset-top)) var(--gutter) 0;text-align:center;
  font-size:1.15rem;letter-spacing:.01em;color:var(--light);
  opacity:0;transform:translateY(-100%)}
.pullnote::before{content:"↑";display:block;margin-bottom:.1rem;opacity:.6}
.pulling .pullnote{opacity:clamp(0,calc((var(--pullk,0) - .3) / .6),1);transform:translateY(calc((var(--pullk,0) - 1) * 1.5rem))}
::view-transition-group(site-title){animation-duration:.55s}

/* ---------- beside the post, on a big screen ----------
   Where there is room either side of the sheet, a column to its left keeps
   the post's year and title, and the posts either side, once its own title
   has gone off the top (blog.js puts it on). Ranged right, against the
   sheet, like the years beside the index. */
.aside-nav{display:none}
@media (min-width:88rem){
  .aside-nav{display:block;position:fixed;z-index:20;top:6.5rem;width:15rem;
    right:calc(50% + (var(--column) + 2 * var(--gutter)) / 2 + 3rem);
    text-align:right;color:var(--light);opacity:0;transform:translateY(.5rem);pointer-events:none;
    transition:opacity .35s,transform .35s cubic-bezier(.2,.7,.2,1)}
  .aside-nav.on{opacity:1;transform:none;pointer-events:auto}
  .aside-nav p{margin:0}
  .an-year{font-size:1rem;letter-spacing:.08em;opacity:.55;font-variant-numeric:lining-nums}
  .an-title{margin-top:.35rem!important;font-size:1.45rem;line-height:1.2;text-wrap:balance;
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:5;overflow:hidden}
  .aside-nav nav{display:flex;flex-direction:column;gap:1.1rem;margin-top:2.4rem;padding-top:1.4rem;
    border-top:1px solid rgba(230,226,210,.14)}
  .aside-nav nav a{display:block;text-decoration:none;opacity:.6;transition:opacity .2s}
  .aside-nav nav a:hover{opacity:1}
  .aside-nav nav a[hidden]{display:none}
  .aside-nav small{display:block;font-size:.85rem;letter-spacing:.08em;font-variant:small-caps;opacity:.75}
  .aside-nav nav span{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;
    font-size:1.05rem;line-height:1.3;text-wrap:balance}
  .an-prev small::before{content:"↑ "}
  .an-next small::before{content:"↓ "}
  .an-back small::before{content:"← "}
}
@media (prefers-reduced-motion:reduce){.aside-nav{transition:none}}

/* ---------- the sheet ---------- */
/* The paper is its own layer under the words, in the sheet and in a card
   alike, so that opening a post can grow the card's paper into the sheet's
   without stretching the type on it. */
.sheet{position:relative;isolation:isolate;max-width:calc(var(--column) + 2 * var(--gutter));margin:0 auto;color:var(--ink)}
.paper{position:absolute;inset:0;z-index:-1;background:var(--paper);
  box-shadow:0 1px 2px rgba(0,0,0,.25),0 18px 50px -10px rgba(0,0,0,.55)}
.cover{overflow:hidden}
.cover img{display:block;width:100%;height:auto;max-height:422px;object-fit:cover;object-position:center}
.text{padding:clamp(2rem,6vw,4rem) var(--gutter) clamp(3rem,8vw,5.5rem)}
.text>h1{margin:0;font-weight:500;font-size:clamp(2.1rem,1.5rem + 2.6vw,3.1rem);line-height:1.08;
  letter-spacing:-.01em;text-wrap:balance}
.text>.sub{margin:.7rem 0 0;font-size:clamp(1.25rem,1.1rem + .6vw,1.5rem);line-height:1.3;color:var(--quiet);
  font-style:italic;text-wrap:balance}
.when{margin:1.3rem 0 0;font-size:1rem;color:var(--quiet);letter-spacing:.04em;font-variant:small-caps}
.when a{text-decoration:none;border-bottom:1px solid var(--rule)}
/* "Originally published on …": the rest of the line is small capitals, this
   is a sentence */
.when .first{font-variant:normal;letter-spacing:0;font-style:italic}
.text>.when{margin-bottom:clamp(2.2rem,5vw,3.2rem)}

/* ---------- the body of a post: Paragraph's layout ---------- */
.body{font-size:1.25rem;line-height:1.6}
.body::after{content:"";display:table;clear:both}
.body>*{margin-top:0;margin-bottom:0}
.body p{hyphens:auto;-webkit-hyphens:auto;overflow-wrap:break-word}
.body p:empty{height:1em}
.body a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.18em;
  text-decoration-color:var(--ghost);transition:text-decoration-color .15s}
.body a:hover{text-decoration-color:var(--ink)}
.body strong{font-weight:650}
.body h1,.body h2,.body h3,.body h4,.body h5,.body h6{font-weight:600;line-height:1.25;margin-top:2.5rem;
  text-wrap:balance;scroll-margin-top:1.5rem}
.body h1{font-size:1.9rem}.body h2{font-size:1.7rem}.body h3{font-size:1.55rem}
.body h4,.body h5,.body h6{font-size:1.3rem}
.body h3 strong,.body h2 strong{font-weight:inherit}
.body>:first-child{margin-top:0!important}
.body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6){margin-top:2rem}
.body p+:is(h1,h2,h3,h4,h5,h6){margin-top:2.5rem}
.body :is(h1,h2,h3,h4,h5,h6)+p{margin-top:1.5rem}
.body p+p{margin-top:1.375rem}
.body :is(h1,h2,h3,h4,h5,h6,p)+:is(ul,ol){margin-top:1.5rem}
.body :is(ul,ol)+p{margin-top:1.25rem}
.body :is(figure,pre,table)+:is(p,ul,ol,pre){margin-top:2rem}

.body ul,.body ol{padding-left:1.5rem;clear:both}
.body li::marker{color:var(--ink)}
.body li>p{margin:0}
.body li+li{margin-top:.35rem}

.body blockquote{clear:both;position:relative;margin:2rem 0 1.5rem -1rem;padding-left:1.25rem;font-style:italic}
.body blockquote::before{content:"";position:absolute;inset-block:0;left:0;width:.2rem;border-radius:9999px;
  background:var(--ghost);opacity:.8}
.body blockquote p+p{margin-top:.8rem}

.body hr{clear:both;border:0;border-top:1px solid var(--rule);margin:2.5rem 0}
.body pre{overflow-x:auto;padding:1rem 1.2rem;border-radius:6px;background:#e9e5d4;font-size:.9rem;line-height:1.5}
.body code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.85em}
.body math{font-size:1.08em;font-family:"STIX Two Math","Cambria Math","Latin Modern Math",math}

/* pictures: their own size, or the column's if they are wider */
.body figure{margin:0}
.body figure img{display:block;max-width:100%;height:auto;margin:1.25rem auto;border-radius:6px}
.body :is(p,ul,ol,pre,blockquote)+figure>img{margin-top:2rem}
.body figure+figure>img{margin-top:2.5rem}
.body figcaption{text-align:center;font-size:1.02rem;line-height:1.4;color:var(--quiet);text-wrap:balance}
.body figcaption:not(:empty){margin:.75rem 0 1rem}
.body figcaption a{text-decoration-color:var(--rule)}

/* half the column, floated right, the text running round it */
.body figure.float-right{float:right;margin:-.75rem 0 0 1rem}
.body figure.float-left{float:left;margin:-.75rem 1rem 0 0}
.body figure.float-right>figcaption,.body figure.float-left>figcaption{margin-bottom:.3em}
@media (max-width:480px){
  .body figure.float-right,.body figure.float-left{float:none;width:100%!important;margin:1rem auto}
}

.body figure.youtube{clear:both;margin:2rem 0}
.body figure.youtube iframe{display:block;width:100%;aspect-ratio:16/9;border:0;border-radius:6px;background:#000}
/* Someone's tweet, quoted (tweets.py): a card laid on the paper, upright,
   in the post's own type, who said it and when at its foot, linking to it.
   It is a quotation but not one of his, so not the rule and italic of his. */
.body figure.tweet{clear:both;margin:2rem 0}
.body figure.tweet blockquote{margin:0;padding:1.1rem 1.3rem 1rem;font-style:normal;background:#fbf9f1;
  border:1px solid var(--rule);border-radius:10px;box-shadow:0 1px 2px rgba(0,0,0,.06)}
.body figure.tweet blockquote::before{content:none}
.body figure.tweet blockquote p{margin:0}
.body figure.tweet blockquote p+p{margin-top:.6rem}
.body figure.tweet img{display:block;width:100%;height:auto;margin:.9rem 0 0;border-radius:6px}
.body figure.tweet footer{margin-top:.8rem;font-size:.9rem;color:var(--quiet)}
.body figure.tweet footer a{color:inherit;text-decoration:none;border-bottom:1px solid var(--rule)}

/* ---------- after the post: the next one, as a card ----------
   Scroll on past it and it opens where it is, and the one after it waits
   underneath. The room under the card is what there is to scroll into. */
.next{max-width:30rem;margin:0 auto;padding:4.5rem var(--gutter) 0}
.next .label{margin:0 0 .9rem;text-align:center;font-size:1rem;letter-spacing:.06em;font-variant:small-caps;opacity:.65}
.js .next.more{padding-bottom:62vh}
.next.end .card{opacity:.9}
.sheet+.sheet{margin-top:4.5rem}

/* ---------- the index: the posts as sheets on the dark ---------- */
.index{max-width:66rem;margin:0 auto;padding:1rem var(--gutter) 0}
.index>h1{margin:1.5rem 0 2.6rem;font-weight:400;font-size:clamp(1.9rem,1.2rem + 2.6vw,3rem);line-height:1.15;
  color:var(--light);text-wrap:balance}
.index .cat::before{content:"#";opacity:.5}

/* The index itself: a column beside the posts, with a line about them and
   the years they span. The line goes by with the page; the years stay, the
   one being read lit. On a phone the line sits under the title and the
   years run along the top of the screen. */
.front-index{max-width:78rem}
.side .about{margin:0 0 1.6rem;font-size:1.2rem;line-height:1.45;color:var(--light);opacity:.75;font-style:italic;
  text-wrap:pretty}
/* the year being read is large and the others fall away from it along a
   curve, both ways: --k is how near each is, 0 to 1, set by blog.js as
   the page scrolls, so the sizes glide rather than step */
.years{display:flex;flex-direction:column;align-items:flex-start;gap:0;
  font-feature-settings:"kern","lnum";font-variant-numeric:lining-nums tabular-nums}
.years a{padding:.08rem 0;color:var(--light);text-decoration:none;line-height:1.12;
  font-size:calc(.9rem + 1.5rem * var(--k,0) * var(--k,0));opacity:calc(.28 + .72 * var(--k,0))}
.years a:hover{opacity:.9}
.cards>.card[id]{scroll-margin-top:1.5rem}
@media (min-width:60rem){
  .spread{display:grid;grid-template-columns:13rem minmax(0,1fr);gap:clamp(2.5rem,4vw,4rem)}
  /* the column leans on the posts: ranged right, against them */
  .side{text-align:right}
  .years{position:sticky;top:1.5rem;align-items:flex-end}
}
@media (max-width:59.99rem){
  /* the column dissolves, so the years can stay at the top all the way down
     the posts rather than only as far as the end of the line above them */
  .side{display:contents}
  .side .about{margin:-1.6rem 0 1.4rem;font-size:1.1rem}
  .years{position:sticky;top:0;z-index:30;flex-direction:row;gap:0 1.1rem;overflow-x:auto;scrollbar-width:none;
    margin:0 calc(var(--gutter) * -1) 1.6rem;padding:.7rem var(--gutter);
    background:rgba(51,51,49,.94);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
    border-bottom:1px solid rgba(255,255,255,.07)}
  .years::-webkit-scrollbar{display:none}
  /* along the top the curve is gentler, so the bar keeps its height */
  .years{align-items:baseline}
  .years a{padding:.1rem 0;font-size:calc(1rem + .55rem * var(--k,0))}
  .cards>.card[id]{scroll-margin-top:4rem}
}
.lost{font-size:1.3rem}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,19rem),1fr));gap:clamp(1.5rem,3vw,2.4rem)}
/* A card is an A4 sheet, like the pages of the blog's poster on the site:
   the picture across its top, the title, the subtitle, as many of the first
   lines as fit (blog.js cuts them at the last whole line), and the date and
   categories at the foot. Set in container units, as the poster is, so it
   is the same page at any size. */
.card{position:relative;isolation:isolate;display:flex;flex-direction:column;color:var(--ink);text-decoration:none;
  aspect-ratio:1 / 1.41;min-height:0;container-type:inline-size;
  transition:transform .35s cubic-bezier(.2,.7,.2,1)}
.card .paper{box-shadow:0 1px 2px rgba(0,0,0,.25),0 14px 36px -12px rgba(0,0,0,.6);transition:box-shadow .35s}
.card:hover{transform:translateY(-4px) rotate(-.25deg)}
.card:hover .paper{box-shadow:0 1px 2px rgba(0,0,0,.25),0 24px 46px -14px rgba(0,0,0,.7)}
.card .thumb{flex:none;aspect-ratio:2/1;overflow:hidden;background:#dcd7c6}
.card .thumb img{display:block;width:100%;height:100%;object-fit:cover}
.card .words{flex:1;min-height:0;display:flex;flex-direction:column;padding:8cqw 8.5cqw 7cqw;overflow:hidden}
.card h2{margin:0;font-weight:500;font-size:8cqw;line-height:1.1;text-wrap:balance}
.card .sub{margin:2.2cqw 0 0;font-size:5cqw;line-height:1.3;color:var(--quiet);font-style:italic;text-wrap:balance}
.card .lines{flex:1 1 0;min-height:0;margin:5cqw 0 0;font-size:4.3cqw;line-height:1.5;color:#3d3a33;
  hyphens:auto;-webkit-hyphens:auto;overflow:hidden;overflow-wrap:break-word}
.card .when{margin:auto 0 0;padding-top:4cqw;font-size:3.7cqw;
  display:flex;justify-content:space-between;align-items:baseline;gap:.4rem 3cqw}
.card .when time{flex:none}
/* the post's categories, to the right of its date, as quiet as the date */
.card .tags{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:0 .45em;text-align:right;min-width:0}
.card .tags span+span::before{content:"·";margin-right:.45em;opacity:.7}

/* ---------- the cards pile up at the top ----------
   As on the site, where the Mist screenshots come up one after another and
   pile up like windows: a card reaching the top of the screen stays there
   and is pushed back behind the one coming up after it, each a little
   higher, smaller and fainter, until it goes into the dark. Coming up from
   the foot of the screen, a card rises out of the dark. blog.js places them
   (--dim is how far one has gone back, 0 to 1); without it the cards just
   scroll. The lift on hover would fight it, so there is none. */
/* Side by side, the columns are staggered: each a part of a card lower than
   the one to its left (half, in two), so the rows never stand level. Each
   card spans as many rows of the grid as there are columns, and blog.js
   places them and sizes the rows (--row). */
.cards.stagger{grid-auto-rows:var(--row,auto)}
.cards.stagger>.card{align-self:start}
.piling .cards>.card{position:sticky;top:var(--line,0);align-self:start;transition:none;transform-origin:50% 0}
/* Side by side there is no pile: two piles going back side by side drew
   the eye more than the cards. The cards scroll, coming up out of the dark
   at the foot of the screen and going into it at the top. */
.piling .cards.stagger>.card{position:relative;top:auto}
.piling .cards>.card:hover{transform:none}
.piling .cards>.card::after{content:"";position:absolute;inset:0;background:var(--dark);
  opacity:var(--dim,0);pointer-events:none}
.piling .cards>.card.gone{visibility:hidden}
/* Where the browser can tie an animation to the scroll itself (Safari 26,
   Chrome 115), the whole pile is that: each card's own place in the page
   (its view timeline) runs it, off the page's thread, so nothing waits on a
   script and nothing trails the finger. It needs no sticking either: from
   the moment its top reaches the line (--line), the card is moved down by
   exactly as much as the page goes up, less the little it steps back into
   the pile, so it is held there. blog.js sets the lengths:
   --deep  the scroll over which it goes three rows back, and out
   --hold  where it is moved to by then
   --rise  how far up the screen a card comes before it is out of the dark */
@supports (animation-timeline: view()) {
  /* Two animations on the card itself and nothing else, each only while it
     is doing something: rising in from the foot of the screen, and going
     back into the pile. Outside those it is plain paper, with no layer of
     its own; kept on every card, the whole page (three layers a card) was
     over a gigabyte of pictures on a phone, and Safari closed it. */
  .pile-css .cards>.card{transition:none;transform-origin:50% 0}
  /* only the cards on or near the screen (blog.js marks them): a card with
     one of these on it is a layer of its own even while it waits */
  .pile-css .cards>.card.near{
    animation:pile-rise ease-in-out none,pile-back linear none;
    animation-timeline:view(),view();
    animation-range:entry 0% entry var(--rise,1px),
      contain calc(100% - var(--line,0px)) contain calc(100% - var(--line,0px) + var(--deep,1px))}
  .pile-css .cards.stagger>.card.near{
    animation:pile-rise ease-in-out none,pile-fade ease-in-out forwards;
    animation-timeline:view(),view();
    animation-range:entry 0% entry var(--rise,1px),exit 0% exit var(--rise,1px)}
}
/* the pile: held at the line, stepping back a little higher and smaller
   each row, darker, and gone by the third */
@keyframes pile-back{
  from{transform:none;filter:none;opacity:1}
  33.333%{filter:brightness(.72)}
  66.667%{filter:brightness(.5);opacity:1}
  to{transform:translate3d(0,var(--hold,0px),0) scale(.88);filter:brightness(.35);opacity:0}}
/* half into the dark at the top, side by side, and then off the screen: held there (forwards),
   or the card would come back as its last part leaves the screen */
@keyframes pile-fade{from{opacity:1;filter:none}to{opacity:.5;filter:brightness(.6)}}
/* up out of the dark */
@keyframes pile-rise{from{opacity:.25;filter:brightness(.5)}to{opacity:1;filter:none}}
/* arriving from the site part way down the posts, the years come down from
   the top once the page is there */
.arrive .years{animation:years-down .7s .2s cubic-bezier(.2,.7,.2,1) both}
@keyframes years-down{from{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.arrive .years{animation:none}}

@media (max-width:640px){
  .sheet>.paper{box-shadow:none}
  .top{padding-top:1.1rem;padding-bottom:1rem}
}

/* ---------- opening a post ----------
   Going from the index to a post, or from a post to the next, the card's
   paper and picture grow into the sheet's, and the words of the post come
   up once the paper is there. Pages that are not a post just cross-fade.
   Browsers without view transitions simply go to the page. */
@view-transition{navigation:auto}
::view-transition-group(*){animation-duration:.6s;animation-timing-function:cubic-bezier(.2,.75,.15,1)}
::view-transition-group(root){animation-duration:.35s}
/* the picture keeps its proportions, cropped, as it goes from 2:1 to the cover's */
::view-transition-old(*.cover),::view-transition-new(*.cover){height:100%;object-fit:cover}
::view-transition-image-pair(*.cover){overflow:hidden}
/* The words are never stretched: each is drawn at its own size, from the
   top left of the box going from the card's to the sheet's. The card's
   (its subtitle, its first lines, its date) go quickly, and the post's come
   up once the paper is there. (Only for the card that opens: the other
   cards on the index just fade.) A rule for one of a pair is written for
   both, and the one alone (:only-child) put back after it: Chrome does not
   match :not(:only-child) here, and the pairs' rules were never applied.
   The one alone fades as the browser would fade it (vt-out, vt-in). */
::view-transition-old(*.words),::view-transition-new(*.words){width:auto;height:auto}
::view-transition-old(*.words){animation:words-out .12s linear both}
::view-transition-old(*.words):only-child{animation:vt-out .6s both}
::view-transition-new(*.words){animation:words-in .45s .3s cubic-bezier(.2,.7,.2,1) both}
@keyframes words-out{to{opacity:0}}
@keyframes vt-out{from{opacity:1}to{opacity:0}}
@keyframes vt-in{from{opacity:0}to{opacity:1}}
@keyframes words-in{from{opacity:0;transform:translateY(.6rem)}to{opacity:1;transform:none}}
/* The title goes from the card's to the sheet's, and grows as it goes, as
   type rather than a picture of it blown up: each is drawn at its own size
   and scaled by as much as the sheet's is larger than the card's (--title-k,
   from blog.js, or the head of the page it arrives on), so the two are the
   same size all the way and only cross over from one to the other. Their
   lines may break in different places, so the crossing is quick, early,
   and the two are hardly ever there at once. Back to the index, it is the
   same the other way round. */
::view-transition-old(*.title),::view-transition-new(*.title){width:auto;height:auto;transform-origin:0 0}
::view-transition-old(*.title){animation:title-old .6s cubic-bezier(.2,.75,.15,1) both,title-out .6s linear both}
::view-transition-new(*.title){animation:title-new .6s cubic-bezier(.2,.75,.15,1) both,title-in .6s linear both}
::view-transition-old(*.title):only-child{animation:vt-out .6s both}
::view-transition-new(*.title):only-child{animation:vt-in .6s both}
@keyframes title-old{to{transform:scale(var(--title-k,1))}}
@keyframes title-new{from{transform:scale(calc(1 / var(--title-k,1)))}}
@keyframes title-out{0%,10%{opacity:1}30%,100%{opacity:0}}
@keyframes title-in{0%,18%{opacity:0}40%,100%{opacity:1}}
/* the paper is one sheet the whole way: no fading between two of them,
   which would let the dark through half way */
::view-transition-old(*.paper),::view-transition-new(*.paper){height:100%}
::view-transition-old(*.paper){animation:none;opacity:0}
::view-transition-new(*.paper){animation:none}
::view-transition-old(*.paper):only-child{animation:vt-out .6s both}
::view-transition-new(*.paper):only-child{animation:vt-in .6s both}

@media (prefers-reduced-motion:reduce){
  .card{transition:none}.card:hover{transform:none}
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
}

/* ---------- the archive: older writing, not on the blog ---------- */
.index .lead{max-width:40rem;margin:-1.4rem 0 2.6rem;font-size:1.2rem;line-height:1.45;color:var(--light);opacity:.75}
.shelf-of{margin-bottom:3.6rem}
.shelf-of>h2{margin:0 0 .3rem;font-weight:400;font-size:1.7rem;color:var(--light)}
.shelf-of .about{margin:0 0 1.4rem;font-size:1.05rem;color:var(--light);opacity:.65;font-style:italic}
/* picking what goes on the blog: a box under each card, and a bar that
   keeps count and copies the list out */
.picker{position:sticky;top:0;z-index:40;display:flex;flex-wrap:wrap;gap:.6rem 1.2rem;align-items:center;
  margin:0 calc(var(--gutter) * -1) 2.4rem;padding:.8rem var(--gutter);
  background:rgba(51,51,49,.94);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border-bottom:1px solid rgba(255,255,255,.08);color:var(--light);font-size:1.05rem}
.picker .count{opacity:.8}
.picker button,.shelf-of .all{font:inherit;font-size:.95rem;color:var(--ink);background:var(--paper);border:0;
  border-radius:999px;padding:.35rem 1rem;cursor:pointer}
.picker button:hover,.shelf-of .all:hover{background:#fff}
.picker .done{font-style:italic;opacity:0;transition:opacity .3s}
.picker .done.on{opacity:.8}
.shelf-of .all{background:transparent;color:var(--light);border:1px solid rgba(230,226,210,.35);margin-left:.6rem;font-size:.85rem;padding:.15rem .7rem}
.pick{display:flex;flex-direction:column}
.pick .card{flex:1}
.vis{display:flex;align-items:center;gap:.5rem;margin-top:.7rem;color:var(--light);font-size:1rem;cursor:pointer;user-select:none}
.vis input{width:1.15rem;height:1.15rem;accent-color:#e6c46a;margin:0}
.pick.in .card .paper{box-shadow:0 0 0 3px #e6c46a,0 14px 36px -12px rgba(0,0,0,.6)}
.pick.in .vis{color:#f0d68c}
.body figure video{display:block;max-width:100%;height:auto;margin:1.25rem auto;border-radius:6px;background:#000}
/* A carousel: pictures one after another in the Markdown, shown one at a
   time and swiped (or stepped with the arrows) from side to side. Without
   the script it still scrolls sideways; the arrows need it. */
.body figure.carousel{margin:1.25rem 0}
.carousel .slides{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior-x:contain;align-items:center;outline:none}
.carousel .slides::-webkit-scrollbar{display:none}
.carousel .slide{flex:0 0 100%;scroll-snap-align:center;scroll-snap-stop:always;display:flex;flex-direction:column;align-items:center}
.body .carousel .slide img,.body .carousel .slide video{margin:0 auto;width:auto;max-width:100%;height:auto;max-height:min(78vh,44rem)}
.carousel .steer{display:none;justify-content:center;align-items:center;gap:1.1rem;margin-top:.6rem;color:var(--quiet);font-size:.95rem;font-variant-numeric:tabular-nums}
html.steered .carousel .steer{display:flex}
.carousel .steer button{font:inherit;font-size:1.6rem;line-height:1;width:2.2rem;height:2.2rem;border:1px solid var(--rule);border-radius:50%;background:none;color:var(--ink);cursor:pointer;padding:0 0 .15em}
.carousel .steer button:hover:not(:disabled){background:var(--light)}
.carousel .steer button:disabled{opacity:.3;cursor:default}
/* A picture, full screen (blog.js): the ones with more to show than the page
   gives them have the magnifying cursor, and open over the dark, the caption
   quiet under them. The arrows beside a carousel's pages are for a mouse; a
   finger swipes. */
.sheet img.zooms{cursor:zoom-in}
.lightbox{position:fixed;inset:0;z-index:100;cursor:zoom-out;outline:none;overscroll-behavior:contain;
  -webkit-tap-highlight-color:transparent}
.lightbox[hidden]{display:none}
.lightbox .lb-ground{position:absolute;inset:0;background:rgba(24,24,23,.96)}
.lightbox>img{position:absolute;max-width:none;transform-origin:0 0;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}
.lightbox .lb-cap{position:absolute;left:0;right:0;bottom:0;max-width:40rem;margin:0 auto;
  padding:.7rem 1.25rem max(1rem,env(safe-area-inset-bottom));text-align:center;font-size:1.02rem;line-height:1.4;
  color:var(--light);opacity:.7;text-wrap:balance;cursor:auto}
.lightbox .lb-cap:empty{display:none}
.lightbox .lb-cap a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.18em;text-decoration-color:rgba(230,226,210,.4)}
.lightbox button{display:none;position:absolute;top:50%;margin-top:-1.3rem;width:2.6rem;height:2.6rem;padding:0 0 .15em;
  font:inherit;font-size:1.9rem;line-height:1;color:var(--light);background:none;border:1px solid rgba(230,226,210,.3);
  border-radius:50%;cursor:pointer;opacity:.7;transition:opacity .2s}
.lightbox button:hover:not(:disabled){opacity:1}
.lightbox button:disabled{opacity:.15;cursor:default}
.lightbox.closing button{opacity:0;transition-duration:.12s}
.lightbox .lb-prev{left:1.4rem}.lightbox .lb-next{right:1.4rem}
@media (hover:hover) and (pointer:fine){.lightbox.many button{display:block}}
