/* =========================================================================
   jonasleddington.com

   Palette and typefaces are shared with schooloftheway.org; the structure is
   not. No hero, no reveal-on-scroll, no dark full-bleed sections, no uppercase
   letterspaced kickers. The elegance is meant to come from the palette, the
   typography, and the images -- never from ornament.

   LAYOUT: one column, one width, on every page. There is no side rail. Search
   and topics sit in a band across the top, under the masthead. The links out
   live in the footer and on /about/, nowhere else.

   NOTHING HERE LOADS FROM A THIRD PARTY. Fonts are self-hosted in /fonts/.
   No analytics, no trackers, no cookies. Adding a CDN or an embed breaks the
   CSP in netlify.toml, which is deliberate.
   ========================================================================= */

/* ---------- fonts (self-hosted, subset by unicode-range) ----------
   Six files, 420K on disk, but a page only fetches what it needs: a plain
   English page pulls EB Garamond latin (44K) + Fraunces latin (67K). The
   latin-ext files exist for Soto, mudita, and other diacritics in the writing.
   Both faces are SIL OFL 1.1 -- licences sit beside them in /fonts/. */
@font-face{
  font-family:'EB Garamond';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/fonts/ebgaramond-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'EB Garamond';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/fonts/ebgaramond-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C4,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'EB Garamond';font-style:italic;font-weight:400 500;font-display:swap;
  src:url('/fonts/ebgaramond-italic-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'EB Garamond';font-style:italic;font-weight:400 500;font-display:swap;
  src:url('/fonts/ebgaramond-italic-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C4,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Fraunces';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/fonts/fraunces-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Fraunces';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/fonts/fraunces-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C4,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ---------- tokens ---------- */
:root{
  --paper:#EAE5D9;        /* unbleached kozo */
  --ink:#20262E;          /* sumi */
  --ash:#665E52;          /* secondary text, 5.08:1 on paper */
  --line:#D3CCBC;         /* hairline */
  --panel:#E2DCCD;        /* inset panel */
  --seal:#AF3327;         /* vermilion -- rules, borders, link text on paper */
  --link:var(--seal);     /* 5.02:1 on paper */
  --code-bg:#E2DCCD;

  --display:'Fraunces', Georgia, 'Times New Roman', serif;
  --body:'EB Garamond', Georgia, 'Times New Roman', serif;
  --util:ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono:ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', monospace;

  --shell:62rem;          /* ONE width, every page */
  --cap:1.3rem;           /* THE CEILING. Nothing on the site is larger than
                             the wordmark; hierarchy comes from weight,
                             colour and space instead of scale. */
  --measure:34em;         /* prose measure */
}

/* Dark mode is free and respectful: no toggle, no cookie, no stored preference.
   THE CONTRAST TRAP CARRIED OVER FROM THE OTHER TWO REPOS: --seal on --ink is
   2.41:1, far below the floor for text. So on dark, seal keeps its job as a RULE
   or BORDER only, and link text becomes a lighter tint of it (#DD7A66, 5.12:1).
   Never set link text to --seal inside this block. */
@media (prefers-color-scheme:dark){
  :root{
    --paper:#20262E;
    --ink:#E7DCC6;        /* 11.21:1 */
    --ash:#AC9C82;        /* 5.68:1 */
    --line:#38404C;
    --panel:#2C3440;
    --seal:#AF3327;       /* rules and borders only */
    --link:#DD7A66;       /* 5.12:1 on ink */
    --code-bg:#2C3440;
  }
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--paper);color:var(--ink);
  font-family:var(--body);
  font-size:clamp(1.125rem,1.05rem + 0.3vw,1.25rem);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  font-variant-numeric:oldstyle-nums;
}
h1,h2,h3,h4{
  font-family:var(--display);font-weight:500;line-height:1.14;
  letter-spacing:-.012em;font-optical-sizing:auto;text-wrap:balance;
}
a{color:var(--link);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}
a:hover{text-decoration-thickness:2px}
em{font-style:italic}
strong{font-weight:600}
img{max-width:100%;height:auto;display:block}
hr{border:none;border-top:1px solid var(--line);margin:2.4rem 0}

a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible{
  outline:2px solid var(--link);outline-offset:3px;border-radius:1px;
}
.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;z-index:10;background:var(--paper);color:var(--ink);
  padding:.6rem .9rem;border:1px solid var(--line);font-family:var(--util);font-size:.9rem}

/* ---------- the one shell ---------- */
.shell{max-width:var(--shell);margin:0 auto;padding:0 1.25rem}

/* ---------- masthead ---------- */
.masthead{padding:2rem 0 0}
.masthead-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem 1.6rem;
  padding-bottom:.9rem;border-bottom:1px solid var(--line)}
.mark{font-family:var(--display);font-weight:600;font-size:var(--cap);letter-spacing:-.015em;
  color:var(--ink);text-decoration:none;margin-right:auto}
.mark:hover{color:var(--link)}
.menu{display:flex;flex-wrap:wrap;gap:.3rem 1.1rem;font-family:var(--util);font-size:.875rem}
.menu a{color:var(--ash);text-decoration:none;white-space:nowrap}
.menu a:hover,.menu a[aria-current="page"]{color:var(--link);text-decoration:underline;text-underline-offset:3px}

/* ---------- find band (search + topics), across the top ----------
   The form is `hidden` in the markup and search.js reveals it, so a reader
   without JavaScript sees the full list below rather than a dead input. */
.find{padding:.85rem 0;border-bottom:1px solid var(--line)}
.find-search{max-width:24rem}
.find input[type=search]{width:100%;font-family:var(--util);font-size:.9rem;color:var(--ink);
  background:var(--panel);border:1px solid var(--line);border-radius:2px;padding:.45rem .6rem;
  -webkit-appearance:none;appearance:none}
.find input[type=search]:focus{outline:none;border-color:var(--link);box-shadow:0 0 0 2px rgba(175,51,39,.3)}
.find-count{font-family:var(--util);font-size:.74rem;color:var(--ash);margin-top:.35rem}
.find .chips{margin-top:.7rem}

/* ---------- letter toggle (sub-nav in the find band) ----------
   Real links, not JavaScript state. Sits above the chips because it decides
   which chips are listed. The current view is ink and underlined; the others
   are ash. */
.subnav{display:flex;flex-wrap:wrap;gap:.2rem .9rem;margin-top:.7rem;
  font-family:var(--util);font-size:.82rem}
.subnav a{color:var(--ash);text-decoration:none;white-space:nowrap}
/* The two letters are the choice worth making; All and Archive are the quiet
   way out of it. Hierarchy by weight and colour, never by size. */
.subnav a.subnav-letter{color:var(--ink);font-weight:600}
.subnav a:hover{color:var(--link)}
.subnav a[aria-current="page"]{color:var(--ink);font-weight:600;
  text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--seal);
  text-decoration-thickness:2px}

/* ---------- topic chips ---------- */
.chips{list-style:none;display:flex;flex-wrap:wrap;gap:.35rem}
.chip{display:inline-block;font-family:var(--util);font-size:.75rem;line-height:1.2;
  text-decoration:none;color:var(--ash);border:1px solid var(--line);border-radius:2px;
  padding:.28rem .5rem}
.chip:hover,.chip[aria-current="page"]{color:var(--link);border-color:var(--link)}
.chip-n{opacity:.6;font-size:.7rem;margin-left:.15rem}

/* ---------- page furniture ---------- */
main{padding:clamp(2rem,5vw,3.25rem) 0 clamp(3rem,7vw,4.5rem)}
.page-title{font-size:var(--cap);font-weight:600;margin-bottom:.45rem}
.page-lede{color:var(--ash);max-width:var(--measure);margin-bottom:2rem;line-height:1.5}
/* A page whose title is hidden opens on a line of furniture, and that line
   should pair with the rule above it rather than float under it: the space over
   it matches the space under it. `main` carries a clamped top padding, so each
   rule pulls back exactly the difference and the gap resolves to the margin
   below -- 1.4rem for a note, 2rem for a lede, at every width. A visible
   `.page-title` gives its own structure and is deliberately not included. */
h1.skip + .page-note{margin-top:calc(1.4rem - clamp(2rem,5vw,3.25rem))}
h1.skip + .page-lede{margin-top:calc(2rem - clamp(2rem,5vw,3.25rem))}

/* INSTRUCTIONAL TEXT -- how to use a page, not what the page says. The utility
   face at the size figure captions already use, with less air under it, so it
   reads as furniture beside the writing rather than as part of it. The author's
   own voice stays in the body face above: .page-lede. */
.page-note{font-family:var(--util);font-size:.8rem;color:var(--ash);
  max-width:var(--measure);margin-bottom:1.4rem;line-height:1.5}
.label{font-family:var(--util);font-size:.72rem;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ash);margin-bottom:.6rem}
.label a{color:var(--ash);text-decoration:none}
.label a:hover{color:var(--link);text-decoration:underline;text-underline-offset:3px}
.section{margin-top:clamp(2.8rem,6vw,4rem)}
.more{font-family:var(--util);font-size:.875rem;margin-top:1.1rem}
.empty{color:var(--ash);font-style:italic}

/* ---------- the two letters, side by side (home) ----------
   Half the width each, of the full shell. There is no rail to leave room for. */
.pair{display:grid;grid-template-columns:1fr;gap:2.2rem}
@media (min-width:44rem){
  .pair{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(2rem,5vw,3.25rem)}
  .pair-col + .pair-col{padding-left:clamp(2rem,5vw,3.25rem);border-left:1px solid var(--line)}
}
.pair-title{font-size:var(--cap);font-weight:600;line-height:1.2;margin-bottom:.35rem}
.pair-title a{color:inherit;text-decoration:none}
.pair-title a:hover{color:var(--link)}
.pair-meta{font-family:var(--util);font-size:.74rem;letter-spacing:.04em;color:var(--ash)}
.pair-dek{font-size:1rem;line-height:1.5;color:var(--ash);margin-top:.55rem}
.pair-more{font-family:var(--util);font-size:.8rem;margin-top:1rem}

/* ---------- the featured image (home), full width ---------- */
.feature{margin-top:clamp(2.8rem,6vw,4rem)}
.feature-shot{display:block;background:var(--panel)}
.feature-shot img{width:100%}

/* ---------- "Start here" (curated, on a letter's page) ----------
   Numbered, because the order is the point. */
.picks-block{margin-bottom:clamp(2rem,5vw,2.8rem);padding-bottom:1.3rem;border-bottom:1px solid var(--line)}
.picks{counter-reset:pick;list-style:none;max-width:var(--measure)}
.picks li{counter-increment:pick;display:flex;gap:.6rem;margin-bottom:.5rem;line-height:1.3}
.picks li::before{content:counter(pick);font-family:var(--display);font-style:italic;
  color:var(--seal);flex:0 0 auto}
.picks a{font-family:var(--display);font-size:1.05rem;text-decoration:none}
.picks a:hover{text-decoration:underline;text-underline-offset:3px}

/* ---------- entry lists ---------- */
.entries{list-style:none;border-top:1px solid var(--line)}
.entries li{border-bottom:1px solid var(--line)}
.entries a.entry{display:block;padding:1.1rem 0;text-decoration:none;color:inherit}
.entry-title{font-family:var(--display);font-weight:500;font-size:var(--cap);line-height:1.2;
  display:block;margin-bottom:.25rem}
.entries a.entry:hover .entry-title{color:var(--link)}
.entry-meta{font-family:var(--util);font-size:.76rem;letter-spacing:.04em;color:var(--ash);
  display:flex;flex-wrap:wrap;gap:.5rem;align-items:baseline}
.entry-meta time{font-variant-numeric:normal}
.stream-tag{text-transform:uppercase;letter-spacing:.08em;font-weight:600;font-size:.7rem;
  padding-left:.5rem;border-left:2px solid var(--seal)}
.stream-tag a{color:inherit;text-decoration:none}
.stream-tag a:hover{color:var(--link)}
.entry-excerpt{display:block;margin-top:.45rem;color:var(--ash);font-size:.98em;line-height:1.5}

/* Daily notes. Printed in full on /notes/ rather than linked to, because a
   note is three lines and a click to read three lines is a worse page. The
   date is the only chrome: a note has no title. */
.notes{list-style:none;border-top:1px solid var(--line)}
.note{padding:1.3rem 0;border-bottom:1px solid var(--line)}
.note-date{font-family:var(--util);font-size:.76rem;letter-spacing:.04em;color:var(--ash);
  margin-bottom:.5rem}
.note-date a{color:inherit;text-decoration:none}
.note-date a:hover{color:var(--link)}
.results{margin-bottom:1.6rem}

/* ---------- prose ---------- */
.prose{max-width:var(--measure)}
.prose > * + *{margin-top:1.1rem}
.prose h2{font-size:var(--cap);font-weight:600;margin-top:2.2rem}
.prose h3{font-size:1.1rem;font-weight:600;color:var(--ash);margin-top:1.7rem}
.prose ul,.prose ol{padding-left:1.4rem}
.prose li + li{margin-top:.35rem}
.prose blockquote{border-left:2px solid var(--seal);padding-left:1.1rem;font-style:italic;color:var(--ash)}
/* Stanzas. `.prose > * + *` reaches only direct children, so paragraphs
   INSIDE a blockquote had no space between them at all and the four stanzas
   of the Rilke ran together. Lines within a stanza break on <br>; the gap
   between stanzas is this. */
.prose blockquote p + p{margin-top:1.1rem}
.prose code{font-family:var(--mono);font-size:.86em;background:var(--code-bg);
  padding:.12em .35em;border-radius:2px;font-variant-numeric:normal}
.prose pre{background:var(--code-bg);padding:1rem 1.1rem;border-radius:2px;overflow-x:auto;
  font-size:.82rem;line-height:1.5}
.prose pre code{background:none;padding:0;font-size:inherit}
.prose figure{margin-top:1.8rem}
.prose figcaption{font-family:var(--util);font-size:.8rem;color:var(--ash);margin-top:.5rem;line-height:1.45}

/* ---------- a single piece ---------- */
/* Authorship disclosure, above the prose on any piece that carries
   `withClaude: true`. Set in the utility face so it reads as a note about the
   piece rather than part of it, but in --ink, not grey: it is a statement, not
   a footnote. */
.disclosure{font-family:var(--util);font-size:.8rem;line-height:1.5;color:var(--ink);
  max-width:var(--measure);margin-bottom:1.8rem;padding-left:.9rem;
  border-left:2px solid var(--seal)}
.post-head{margin-bottom:1.8rem}
.post-head h1{font-size:var(--cap);font-weight:600;margin-bottom:.5rem}
.post-meta{font-family:var(--util);font-size:.8rem;color:var(--ash);display:flex;
  flex-wrap:wrap;gap:.6rem;align-items:baseline}
.post-meta time{font-variant-numeric:normal}
.post-topics{margin-top:2.2rem}
.post-foot{margin-top:2.4rem;padding-top:1.3rem;border-top:1px solid var(--line);
  font-family:var(--util);font-size:.875rem}

/* ---------- images ----------
   Their own body of work. The grid is deliberately quiet: no hover effects,
   nothing between the reader and the picture. Every frame declares its aspect
   ratio so the page never jumps while loading. */
.frames{list-style:none;display:grid;gap:1.6rem;grid-template-columns:1fr}
@media (min-width:38rem){.frames{grid-template-columns:repeat(2,1fr);gap:1.8rem}}
@media (min-width:62rem){.frames{grid-template-columns:repeat(3,1fr)}}
.frames a{display:block;text-decoration:none;color:inherit}
.frame-shell{background:var(--panel);overflow:hidden}
.frames img{width:100%;height:100%;object-fit:cover}
.frame-meta{font-family:var(--util);font-size:.74rem;letter-spacing:.04em;color:var(--ash);margin-top:.5rem}
.frame-single figure{margin:0}
.frame-single img{width:100%;background:var(--panel)}
.frame-single figcaption{font-family:var(--util);font-size:.85rem;color:var(--ash);
  margin-top:.9rem;line-height:1.5;max-width:var(--measure)}

/* ---------- attribution on a quoted image ----------
   Someone else's work is reproduced here only for criticism, and that only
   holds if the credit is unmissable. It is never smaller than the caption it
   sits beside, and never grey-on-grey. */
.credit{font-family:var(--util);font-size:.82rem;line-height:1.5;color:var(--ink);
  margin-top:.9rem;padding-left:.9rem;border-left:2px solid var(--seal);max-width:var(--measure)}
.credit-why{display:block;color:var(--ash);font-size:.76rem;margin-top:.25rem}
.shot{margin:0 0 1rem}
.shot img{width:100%;background:var(--panel)}
.frame-note{margin-top:1.6rem}

/* ---------- subscribe form (only on /subscribe/) ---------- */
.subscribe{border:1px solid var(--line);background:var(--panel);padding:1.3rem 1.35rem;
  max-width:var(--measure)}
.subscribe h2,.prose h2.as-subscribe{font-size:1.1rem;font-weight:600;margin-bottom:.4rem}
/* .subscribe-intro and .form-error appear in no template: subscribe.js creates
   them at runtime for the success and error messages. A dead-CSS sweep will
   flag them; they are not dead. */
.subscribe-intro{font-size:.96em;color:var(--ash);margin-bottom:1rem;line-height:1.5}
.pick{border:none;margin-bottom:1rem}
.pick legend{font-family:var(--util);font-size:.76rem;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ash);margin-bottom:.6rem}
.pick label{display:flex;gap:.6rem;align-items:flex-start;line-height:1.4;margin-bottom:.6rem;cursor:pointer}
.pick input{margin-top:.34rem;accent-color:var(--seal);flex:0 0 auto}
.row{display:flex;flex-wrap:wrap;gap:.6rem}
.row input[type=text],.row input[type=email]{flex:1 1 9rem;min-width:0;font-family:var(--body);
  font-size:1rem;color:var(--ink);background:var(--paper);border:1px solid var(--line);
  border-radius:2px;padding:.6rem .7rem}
.row input:focus{outline:none;border-color:var(--link);box-shadow:0 0 0 2px rgba(175,51,39,.3)}
button.btn{flex:0 0 auto;font-family:var(--util);font-size:.82rem;font-weight:600;letter-spacing:.04em;
  color:#EAE5D9;background:var(--seal);border:none;border-radius:2px;padding:.65rem 1.2rem;cursor:pointer}
button.btn:hover{background:#8F2A20}
button.btn[disabled]{opacity:.6;cursor:default}
.fine{font-family:var(--util);font-size:.76rem;color:var(--ash);margin-top:.8rem;line-height:1.5}
.form-error{font-family:var(--util);font-size:.82rem;color:var(--link);margin-top:.7rem}

/* ---------- footer: the links out, one feed link, subscribe, one promise ---------- */
.foot{border-top:1px solid var(--line);margin-top:clamp(2.5rem,6vw,4rem);
  padding:1.3rem 0 2.6rem;font-family:var(--util);font-size:.8rem;color:var(--ash);line-height:1.7}
.foot a{color:var(--ash)}
.foot a:hover{color:var(--link)}
.foot-row{display:flex;flex-wrap:wrap;gap:.3rem 1.1rem}
.foot-row + .foot-row{margin-top:.35rem}

/* ---------- print: a text site should print like one ---------- */
@media print{
  :root{--paper:#fff;--ink:#000;--ash:#444;--line:#bbb}
  .masthead,.find,.subscribe,.post-foot,.foot,.skip,.results{display:none}
  body{font-size:11pt}
  a{text-decoration:none;color:#000}
  .prose{max-width:none}
}
