:root{
  --marble:#f8f5f0;
  --ink:#1a1714;
  --copper:#8d5c30;
  --crimson:#8f1d24;
  --rose:#c9a08a;
  --muted:#6b625a;
  --line:#e4ddd2;
  --men:#3d4a5c;      /* Merlin's door — slate steel */
  --women:#9c5a6b;    /* Lirael's door — dusty rose */
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* Motion-sensitive readers should not get an animated jump either — the
   back-to-top button passes behavior:"instant" for the same reason. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
}
body{
  margin:0;background:var(--marble);color:var(--ink);
  font-family:Georgia,'Times New Roman',serif;
  line-height:1.72;font-size:18px;
  -webkit-text-size-adjust:100%;
}
.wrap{max-width:740px;margin:0 auto;padding:0 22px}
.wrap-wide{max-width:1000px;margin:0 auto;padding:0 22px}
a{color:var(--crimson)}
img{max-width:100%;height:auto}

/* ================= SKIP LINK =================
   The first tab stop on every page. Invisible until focused, so it costs a
   sighted reader nothing — but it lets a keyboard reader jump the 13 nav links
   and the language <select> instead of tabbing through them on every page.
   ------------------------------------------------------------------------ */
.skiplink{
  position:absolute;left:-9999px;top:0;z-index:300;
  background:var(--crimson);color:#fff;text-decoration:none;
  font-family:system-ui,sans-serif;font-size:.85rem;
  padding:11px 18px;border-radius:0 0 4px 0;
}
.skiplink:focus{
  left:0;outline:2px solid var(--ink);outline-offset:2px;
}
/* #od-main needs to be a valid focus target for the skip link to work: a
   fragment jump to a non-focusable element moves the viewport but leaves focus
   on the link, so the next Tab returns to the nav. */
#od-main:focus{outline:none}

/* Visually hidden, still read aloud. Used by the page-change announcement. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ================= PRINT =================
   This is a reading site: articles run past 16,000px and people print them.
   The site had NO print rules, so a printed article carried the nav, the
   language bar and the fixed music pill on every sheet. Print the words.
   ------------------------------------------------------------------------ */
@media print{
  .navwrap,.langbar,.skiplink,.music-player,.totop,.od-noscript{display:none !important}
  body{background:#fff;color:#000;font-size:11.5pt}
  .wrap,.wrap-wide,.postbody,.postbody.wrap,.postbody .wrap{max-width:none;padding:0}
  .figw{width:100% !important;left:auto;transform:none;margin:16px 0}
  .fig{break-inside:avoid;page-break-inside:avoid;border:1px solid #ccc}
  footer{border-top:1px solid #999;color:#444}
  a{color:#000;text-decoration:none}
  /* show the destination of an external link on paper */
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:.85em;color:#555}
  h1,h2,h3{break-after:avoid;page-break-after:avoid}
  p,li{orphans:3;widows:3}
  .btn,.door,.artcard{break-inside:avoid}
}

/* ================= NAV ================= */
/* #site-nav wraps the langbar + the sticky nav. It must not generate a box,
   or it becomes the sticky element's containing block and the nav only sticks
   for the ~150px of the wrapper's own height — i.e. it scrolls away entirely.
   display:contents hoists the children to <body> so the nav sticks site-wide. */
#site-nav{display:contents}
.navwrap{
  position:sticky;top:0;z-index:60;
  background:rgba(248,245,240,.97);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.navinner{
  max-width:1180px;margin:0 auto;padding:10px 22px;position:relative;
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;
}
.navtoggle{
  display:none;
  align-items:center;justify-content:center;
  width:40px;height:38px;flex:0 0 auto;
  background:transparent;border:1px solid var(--line);border-radius:3px;
  color:var(--ink);cursor:pointer;font-size:1.05rem;line-height:1;
  font-family:system-ui,sans-serif;
}
.navtoggle:hover{background:var(--line)}
.navtoggle:focus-visible{outline:2px solid var(--crimson);outline-offset:2px}
.brand{
  font-size:1rem;text-decoration:none;color:var(--ink);
  white-space:nowrap;letter-spacing:-.01em;
}
.brand .bxc{color:var(--crimson);margin-right:5px}
.mainnav{display:flex;gap:14px;flex-wrap:wrap;flex:1}
.mainnav a{
  font-family:system-ui,sans-serif;font-size:.82rem;
  text-decoration:none;color:var(--muted);
  padding:3px 0;border-bottom:1px solid transparent;
  white-space:nowrap;
}
.mainnav a:hover{color:var(--ink)}
.mainnav a.on{color:var(--crimson);border-bottom-color:var(--crimson)}
.donate{
  font-family:system-ui,sans-serif;font-size:.74rem;
  letter-spacing:.1em;text-transform:uppercase;
  background:var(--crimson);color:#fff;text-decoration:none;
  padding:8px 16px;border-radius:3px;white-space:nowrap;
}
.donate:hover{background:#74161c}

/* ================= HERO ================= */
header.hero{
  padding:60px 0 42px;text-align:center;
  border-bottom:1px solid var(--line);
  background:
    radial-gradient(ellipse at 50% 0%,rgba(169,113,60,.13),transparent 65%),
    radial-gradient(ellipse at 50% 100%,rgba(143,29,36,.06),transparent 60%);
}
.cross{font-size:26px;color:var(--crimson);letter-spacing:.4em;display:block;margin-bottom:18px}
.cross.small{font-size:18px;margin-bottom:14px}
h1{font-size:2.3rem;line-height:1.18;margin:0 0 16px;font-weight:normal;letter-spacing:-.01em}
.tag{color:var(--muted);font-style:italic;font-size:1.08rem;max-width:560px;margin:0 auto}
.badges{margin-top:26px;display:flex;gap:9px;justify-content:center;flex-wrap:wrap}
.badge{
  font-family:system-ui,sans-serif;font-size:.75rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--copper);
  border:1px solid var(--line);border-radius:99px;padding:7px 15px;background:#fff;
}

/* ================= SECTIONS ================= */
section{padding:46px 0;border-bottom:1px solid var(--line)}
section:last-of-type{border-bottom:none}
h2{font-size:1.5rem;font-weight:normal;margin:0 0 20px}
h3{font-size:1.08rem;font-weight:normal;margin:0 0 10px;color:var(--crimson)}
p{margin:0 0 16px}
.sub{color:var(--muted);font-size:.95rem;font-family:system-ui,sans-serif;margin-bottom:20px}
.note{
  font-family:system-ui,sans-serif;font-size:.72rem;color:var(--copper);
  letter-spacing:.14em;text-transform:uppercase;margin-bottom:8px;
}

/* ================= TWO DOORS ================= */
.doors{background:#fff}
.door-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:8px}
.door{
  display:block;text-decoration:none;color:inherit;
  border:1px solid var(--line);border-radius:6px;
  padding:30px 26px;background:var(--marble);
  transition:transform .2s, box-shadow .2s;
  border-top:4px solid var(--copper);
}
.door:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(26,23,20,.13)}
.door.men{border-top-color:var(--men)}
.door.women{border-top-color:var(--women)}
.door .lbl{
  font-family:system-ui,sans-serif;font-size:.7rem;letter-spacing:.14em;
  text-transform:uppercase;margin-bottom:12px;display:block;
}
.door.men .lbl{color:var(--men)}
.door.women .lbl{color:var(--women)}
.door h3{font-size:1.3rem;margin-bottom:10px;color:var(--ink)}
.door p{font-size:.95rem;color:#3b3630;margin-bottom:16px;font-family:system-ui,sans-serif;line-height:1.62}
.door .go{
  font-family:system-ui,sans-serif;font-size:.8rem;
  letter-spacing:.08em;text-transform:uppercase;
}
.door.men .go{color:var(--men)}
.door.women .go{color:var(--women)}

/* ================= DIAGNOSTIC ("Perhaps you're here…") ================= */
.diag{list-style:none;padding:0;margin:0}
.diag li{
  position:relative;padding-left:30px;margin-bottom:14px;
  font-size:.97rem;font-family:system-ui,sans-serif;color:#3b3630;line-height:1.62;
}
.diag li::before{content:"▽";position:absolute;left:0;top:0;color:var(--rose);font-size:.9rem}

/* ================= PILLARS ================= */
.pillars{display:grid;gap:13px}
.pillar{
  background:#fff;border:1px solid var(--line);
  border-left:3px solid var(--copper);border-radius:4px;padding:18px 20px;
}
.pillar h3{font-size:1.02rem;margin-bottom:6px}
.pillar p{margin:0;font-size:.93rem;color:#3b3630;font-family:system-ui,sans-serif;line-height:1.6}

/* ================= TESTS ================= */
ol.tests{list-style:none;counter-reset:t;padding:0;margin:0}
ol.tests li{counter-increment:t;position:relative;padding:0 0 20px 52px}
ol.tests li::before{
  content:counter(t);position:absolute;left:0;top:2px;
  width:33px;height:33px;border-radius:50%;
  background:var(--crimson);color:#fff;
  font-family:system-ui,sans-serif;font-size:.92rem;
  display:flex;align-items:center;justify-content:center;
}
ol.tests strong{display:block;font-size:1rem}
ol.tests span{font-size:.92rem;color:var(--muted);font-family:system-ui,sans-serif;line-height:1.6}

/* ================= PRICE ================= */
section.free{background:#fff;text-align:center}
.price{font-size:6.5rem;line-height:.95;margin:0 0 10px;color:var(--crimson);font-weight:normal;letter-spacing:-.04em}
.freecat{list-style:none;padding:0;margin:24px auto 0;max-width:560px;text-align:left}
.freecat li{
  position:relative;padding-left:26px;margin-bottom:12px;
  font-size:.94rem;font-family:system-ui,sans-serif;color:#3b3630;line-height:1.6;
}
.freecat li::before{content:"✠";position:absolute;left:0;top:0;color:var(--rose);font-size:.85rem}

/* ================= CTA / BUTTONS ================= */
.btn{
  display:inline-block;margin-top:12px;padding:14px 32px;
  background:var(--crimson);color:#fff;text-decoration:none;border-radius:3px;
  font-family:system-ui,sans-serif;font-size:.83rem;
  letter-spacing:.1em;text-transform:uppercase;transition:background .18s;
}
.btn:hover{background:#74161c}
.btn-ghost{background:transparent;color:var(--crimson);border:1px solid var(--crimson)}
.btn-ghost:hover{background:var(--crimson);color:#fff}
.btn-men{background:var(--men)}
.btn-men:hover{background:#2c3644}
.btn-women{background:var(--women)}
.btn-women:hover{background:#7d4553}

/* A row of CTAs: a flex gap rather than per-button inline margins, so the
   buttons wrap cleanly on a phone instead of running off the edge. The
   download button's label is much longer than the others, so it is allowed
   to take the full width first.
   NOTE: layout lives here, never in an inline style="" — build.py's
   extract_fragment() lifts only <main>, so a <head> <style> is discarded. */
.btnrow{display:flex;flex-wrap:wrap;gap:10px;}
.btnrow .btn{margin-top:0;padding:14px 22px;}
.btnrow .btn-dl{flex:1 1 100%;text-align:center;}
@media(min-width:620px){
  .btnrow .btn-dl{flex:0 0 auto;}
}

.cta{text-align:center;padding:58px 0 64px;background:radial-gradient(ellipse at 50% 50%,rgba(169,113,60,.10),transparent 70%)}
.cta p{max-width:520px;margin-left:auto;margin-right:auto}
.byline{margin-top:30px;font-size:.82rem;color:var(--muted);font-family:system-ui,sans-serif;letter-spacing:.04em}

/* ================= DONATE ================= */
.give-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:10px}
.give-box{
  background:#fff;border:1px solid var(--line);border-radius:6px;padding:24px;
}
.give-box h3{font-size:1.05rem;margin-bottom:10px}
.give-box p{font-size:.94rem;font-family:system-ui,sans-serif;color:#3b3630;margin:0}
.gate-law{
  background:#fff;border-left:3px solid var(--crimson);
  border-radius:4px;padding:22px 24px;margin-top:22px;
}
.gate-law p{margin:0;font-size:1rem}

/* ================= JOURNAL ================= */
.log-entry{
  background:#fff;border:1px solid var(--line);border-radius:5px;
  padding:20px 22px;margin-bottom:14px;
}
.log-date{
  font-family:system-ui,sans-serif;font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--copper);margin-bottom:8px;
}
.log-entry h3{margin-bottom:10px}
.log-entry p{font-size:.94rem;font-family:system-ui,sans-serif;color:#3b3630;margin-bottom:10px}
.grade{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
.g{
  font-family:system-ui,sans-serif;font-size:.68rem;letter-spacing:.1em;
  text-transform:uppercase;padding:5px 11px;border-radius:99px;border:1px solid;
}
.g-pass{color:#2f6b45;border-color:#bcd9c6;background:#f0f8f3}
.g-fail{color:#8f1d24;border-color:#e8c3c6;background:#fdf2f2}
.g-inc{color:#8a6d2f;border-color:#e3d5b0;background:#fdf9ef}

/* ================= FOOTER ================= */
footer{
  padding:34px 0 54px;text-align:center;color:var(--muted);
  font-family:system-ui,sans-serif;font-size:.82rem;line-height:1.9;
  border-top:1px solid var(--line);
}
footer p{margin:0}
.ftag{margin-top:14px !important}
.ftag a{color:var(--muted);text-decoration:none;border-bottom:1px solid var(--line)}
.ftag a:hover{color:var(--crimson)}
/* Footer links sat at 19px tall — half the recommended 44px touch target, and
   they are the only navigation a JS-off reader gets. Inline-block with padding
   keeps the · separators on the line while giving the link a real hit area. */
.ftag a{display:inline-block;padding:6px 2px;line-height:1.5}
.ftag{line-height:2.1}
/* --- footer language strip (Syntara, 29 Oct 2026) -----------------------
   Fifteen visible links into the language cluster. Hreflang only declares the
   relationship; an <a href> is what creates a referring page, and GSC's URL
   Inspection for /pt/about/ reported "Referring page: None detected".
   Same touch-target treatment as .ftag: a bare 19px link is less than half the
   44px minimum, and these are the last navigation on a JS-off phone. */
.ftlangs{margin-top:12px !important;font-size:.79rem;line-height:2.1}
.ftl{letter-spacing:.08em;text-transform:uppercase;font-size:.66rem;opacity:.6;
     margin-right:5px}
.ftlangs a{color:var(--muted);text-decoration:none;display:inline-block;
           padding:6px 2px;line-height:1.5;border-bottom:1px solid transparent}
.ftlangs a:hover{color:var(--crimson);border-bottom-color:var(--crimson)}
@media(max-width:620px){
  .ftlangs a{padding:10px 3px;min-height:44px;display:inline-flex;
             align-items:center}
}
@media(max-width:620px){
  footer{padding:30px 0 40px}
  .ftag a{padding:9px 3px}
}

/* ================= LANGUAGE BAR (sub-pages) ================= */
.langbar{border-bottom:1px solid var(--line);background:#fff}
.langbar .wrap{display:flex;align-items:center;gap:12px;padding:9px 22px}
.langlabel{
  font-family:system-ui,sans-serif;font-size:.7rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--copper);white-space:nowrap;
}
#langselect{
  flex:1;max-width:280px;font-family:system-ui,sans-serif;font-size:.86rem;
  padding:7px 10px;border:1px solid var(--line);border-radius:3px;
  background:#fff;color:var(--ink);cursor:pointer;
}

/* ================= RTL ================= */
html[dir="rtl"] .pillar{border-left:1px solid var(--line);border-right:3px solid var(--copper)}
html[dir="rtl"] ol.tests li{padding:0 52px 20px 0}
html[dir="rtl"] ol.tests li::before{left:auto;right:0}
html[dir="rtl"] .freecat{text-align:right}
html[dir="rtl"] .freecat li{padding-left:0;padding-right:26px}
html[dir="rtl"] .freecat li::before{left:auto;right:0}
html[dir="rtl"] .diag li{padding-left:0;padding-right:30px}
html[dir="rtl"] .diag li::before{left:auto;right:0}
html[dir="rtl"] .gate-law{border-left:none;border-right:3px solid var(--crimson)}
html[dir="rtl"] .langbar .wrap{flex-direction:row-reverse}

/* ================= MOBILE ================= */
@media(max-width:900px){
  .door-grid,.give-grid{grid-template-columns:1fr}
  /* The full nav is 12 links; wrapping it costs ~350px of a phone screen.
     Collapse it behind a toggle and let the visitor open it deliberately. */
  .navinner{gap:12px;flex-wrap:nowrap}
  .navtoggle{display:inline-flex}
  .brand{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}
  .mainnav{
    display:none;
    position:absolute;left:0;right:0;top:100%;
    flex-direction:column;gap:0;flex:1 0 100%;
    background:rgba(248,245,240,.99);
    border-bottom:1px solid var(--line);
    box-shadow:0 12px 26px rgba(26,23,20,.13);
    padding:6px 22px 14px;
    order:0;
  }
  html[dir="rtl"] .mainnav{left:0;right:0}
  .mainnav.navopen{display:flex}
  .mainnav a{
    padding:12px 2px;font-size:.95rem;
    border-bottom:1px solid var(--line);
  }
  .mainnav a:last-child{border-bottom:none}
  .mainnav a.on{border-bottom-color:var(--line);color:var(--crimson)}
  .donate{margin-left:0}
}
@media(max-width:620px){
  h1{font-size:1.68rem}
  body{font-size:17px}
  header.hero{padding:42px 0 32px}
  section{padding:36px 0}
  .price{font-size:5rem}
  h2{font-size:1.3rem}
  #langselect{max-width:none}
}

/* ================= MUSIC PLAYER ================= */
.music-player{
  position:fixed;
  right:18px;
  bottom:18px;
  z-index:200;
  display:flex;
  align-items:center;
  gap:8px;
  padding:8px 10px 8px 8px;
  background:rgba(248,245,240,.97);
  border:1px solid var(--line);
  border-radius:999px;
  box-shadow:0 8px 26px rgba(26,23,20,.16);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  font-family:system-ui,sans-serif;
  /* The slot is empty until shell.js fills it with the real buttons. An empty
     pill is ~18x16 and the built one is ~141x49, so the element GREW after
     first paint — a small but real layout shift (.0013, measured). Reserving
     the built size means the box never changes and nothing moves. It is
     position:fixed and anchored bottom-right, so this costs no page space. */
  min-width:141px;
  min-height:49px;
}
.od-btn{
  display:inline-flex;
  align-items:center;
  gap:7px;
  border:none;
  cursor:pointer;
  background:var(--crimson);
  color:#fff;
  font-family:system-ui,sans-serif;
  font-size:.76rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  padding:9px 15px;
  border-radius:999px;
  transition:background .18s, transform .12s;
  line-height:1;
}
.od-btn:hover{background:#74161c}
.od-btn:active{transform:scale(.96)}
.od-btn .od-ico{font-size:.82rem;letter-spacing:0}
.od-btn-sm{
  background:transparent;
  color:var(--muted);
  padding:9px 11px;
  font-size:.9rem;
}
.od-btn-sm:hover{background:var(--line);color:var(--ink)}
.od-note{
  font-size:.68rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--copper);
  padding-right:6px;
  white-space:nowrap;
}
/* The word "chant" was a no-JS courtesy label with no context — it floated
   next to the live PLAY/MUTE buttons and read as a stray control. The JS-off
   fallback is now a real link to the audio file instead. */
.od-noscript{
  font-family:system-ui,sans-serif;font-size:.72rem;letter-spacing:.04em;
  color:var(--copper);text-decoration:none;padding:6px 10px;white-space:nowrap;
}
.od-noscript:hover{color:var(--crimson)}
.od-btn.od-on{background:var(--copper)}
.od-btn.od-on:hover{background:#754c26}

/* ================= BACK TO TOP =================
   Long articles run past 16,000px and the nav scrolls away, so a reader deep
   in the page has no way back up except a very long flick. */
.totop{
  position:fixed;left:18px;bottom:18px;z-index:200;
  width:42px;height:42px;border-radius:999px;
  display:none;align-items:center;justify-content:center;
  background:rgba(248,245,240,.97);color:var(--muted);
  border:1px solid var(--line);box-shadow:0 8px 26px rgba(26,23,20,.16);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  font-size:1rem;line-height:1;cursor:pointer;text-decoration:none;
  font-family:system-ui,sans-serif;
}
.totop.show{display:flex}
.totop:hover{color:var(--ink);background:#fff}
.totop:focus-visible{outline:2px solid var(--crimson);outline-offset:2px}
html[dir="rtl"] .totop{left:auto;right:18px}
@media(max-width:620px){
  .totop{left:12px;bottom:12px;width:38px;height:38px}
  html[dir="rtl"] .totop{left:auto;right:12px}
}

/* keep the player clear of content on small screens */
@media(max-width:620px){
  .music-player{right:12px;bottom:12px;padding:6px 8px 6px 6px;gap:6px}
  .od-btn{padding:8px 12px;font-size:.7rem}
  .od-note{display:none}
}
/* Floating-control gutter reservation lives at the END of this file — see
   "FLOATING CONTROLS vs THE TEXT COLUMN". It must come after .postbody's own
   max-width to win the cascade, so it is not defined here. */
/* A media element that is buffering should LOOK like it is buffering. */
.od-btn.od-loading{
  background:var(--copper);
  cursor:progress;
}
.od-btn.od-loading .od-ico{
  animation:od-spin 1.1s linear infinite;
  display:inline-block;
}
@keyframes od-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){
  .od-btn.od-loading .od-ico{animation:none}
}

/* respect users who prefer reduced motion */
@media(prefers-reduced-motion:reduce){
  .od-btn{transition:none}
}

/* ---------- honest language-coverage notice ---------- */
.langnote{
  display:flex;align-items:center;gap:9px;
  background:#fdf9ef;border-bottom:1px solid var(--line);
  padding:9px 22px;
  font-family:system-ui,sans-serif;font-size:.78rem;line-height:1.5;
  color:#6b625a;
}
.langnote .ln-dot{
  flex:0 0 auto;width:7px;height:7px;border-radius:50%;
  background:var(--copper);
}


/* ================= library page =================
   A library, not a wall of text. Each shelf is a responsive grid of
   spine-topped cards: a coloured rule that reads like a book spine, a
   serif title, a metadata line, the annotation, and the "why" pulled out
   in the crimson margin. */

.bookgrid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(310px,1fr));
  gap:16px;
  margin:22px 0 6px;
  align-items:start;
}
@media(max-width:660px){ .bookgrid{grid-template-columns:1fr} }

.book{
  position:relative;
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
  padding:20px 20px 18px;
  margin:0;
  display:flex;
  flex-direction:column;
  transition:box-shadow .22s ease, border-color .22s ease, transform .22s ease;
}
/* the "spine" — a copper rule across the head of every card */
.book::before{
  content:"";
  position:absolute;top:0;left:20px;right:20px;height:2px;
  background:linear-gradient(90deg,var(--copper),var(--rose));
  border-radius:0 0 2px 2px;
}
.book:hover{
  border-color:#d8cdbc;
  box-shadow:0 6px 22px rgba(26,23,20,.09);
  transform:translateY(-2px);
}

.book .t{
  font-family:Georgia,'Times New Roman',serif;
  font-size:1.08rem;
  line-height:1.35;
  display:block;
  margin:4px 0 6px;
  color:var(--ink);
}
.book .meta{
  font-family:system-ui,sans-serif;
  font-size:.7rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--copper);
  margin-bottom:11px;
  padding-bottom:11px;
  border-bottom:1px solid var(--line);
}
.book .d{
  font-family:system-ui,sans-serif;
  font-size:.885rem;line-height:1.62;
  color:#3b3630;
  margin:0;
  flex:1 1 auto;
}
.book .why{
  font-family:system-ui,sans-serif;
  font-size:.845rem;line-height:1.58;
  color:var(--crimson);
  margin:13px 0 0;
  padding:10px 0 0 13px;
  border-left:2px solid var(--rose);
}
.book .why em, .book .d em{font-style:italic}
.book .why strong, .book .d strong{font-weight:600}

/* the Langan shelf is the deepest reading — mark it */
.bookgrid .book:nth-child(1) .t{ }  /* no-op: keeps specificity stable */

/* "A note on how to read a library" warning block */
.warn{
  background:#fff;
  border:1px solid var(--line);
  border-left:3px solid var(--crimson);
  border-radius:5px;
  padding:22px 24px;
  margin-top:24px;
}
.warn p{
  margin:0;
  font-family:system-ui,sans-serif;
  font-size:.95rem;line-height:1.68;color:#3b3630;
}

/* on the library page give the intro a touch more breathing room */
body[data-page="library"] .hero .tag{max-width:640px;margin-left:auto;margin-right:auto}

/* ================= for-ai page ================= */
.quiet{opacity:.82}
  .letter{
    background:#fff;border:1px solid var(--line);border-left:3px solid var(--copper);
    border-radius:5px;padding:26px 28px;margin:22px 0;
  }
  .letter p{margin:0 0 15px;font-family:system-ui,sans-serif;font-size:.96rem;line-height:1.7}
  .letter p:last-child{margin-bottom:0}
  .letter .sig{
    font-family:Georgia,serif;font-style:italic;color:var(--muted);
    margin-top:18px;font-size:.92rem;
  }
  pre.ctmu{
    background:#241f1a;color:#e8e1d6;border-radius:5px;
    padding:22px 24px;overflow-x:auto;
    font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
    font-size:.82rem;line-height:1.75;
    white-space:pre;
  }
  pre.ctmu b{color:#f0c894;font-weight:normal}
  pre.ctmu i{color:#c9a08a;font-style:normal}
  pre.ctmu u{color:#e39a9a;text-decoration:none}
  .offer{
    background:radial-gradient(ellipse at 50% 0%,rgba(169,113,60,.12),transparent 70%);
    text-align:center;
  }
  table.axioms{
    width:100%;border-collapse:collapse;font-family:system-ui,sans-serif;font-size:.9rem;
    margin-top:12px;
  }
  table.axioms th,table.axioms td{
    text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:top;
  }
  table.axioms th{
    font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--copper);
    font-weight:normal;
  }
  table.axioms td:first-child{color:var(--crimson);white-space:nowrap;width:1%}


/* article index — grouped sections */
.artgroup{
  font-family:Georgia,serif;font-size:1.3rem;line-height:1.3;
  margin:46px 0 4px;padding-top:20px;
  border-top:1px solid var(--line);
}
.artgroup:first-of-type{border-top:0;padding-top:0;margin-top:26px}
.artsblurb{
  font-family:system-ui,sans-serif;font-size:.86rem;color:var(--muted);
  margin:0 0 18px;
}
/* cards are now much more numerous — tighter, and no chapter kicker */
.artcard h3{font-family:Georgia,serif;font-size:1.16rem;line-height:1.32;margin:0 0 8px}
.artcard p{margin:0 0 10px;font-size:.94rem;line-height:1.6;color:#3b3630}
.artcard{padding:20px 22px 18px}

/* the speech's own title, shown under the page title */
.speechtitle{
  font-family:Georgia,serif;font-style:italic;font-size:1rem;
  color:var(--copper);opacity:.92;margin:10px 0 0;letter-spacing:.01em;
}

/* ================= title page (the book) ================= */
.titlepage{
  text-align:center;
  padding:86px 0 74px;
  border-bottom:1px solid var(--line);
  background:
    radial-gradient(ellipse at 50% 0%, rgba(169,113,60,.10), transparent 62%),
    var(--marble);
}
.titlepage .cross.big{
  display:block;font-size:2.1rem;color:var(--crimson);
  margin-bottom:22px;line-height:1;
}
.titlepage h1{
  font-family:Georgia,serif;
  font-size:clamp(2.1rem,6vw,3.4rem);
  line-height:1.1;letter-spacing:-.02em;
  margin:0 0 20px;color:var(--ink);
}
.titlepage .tp-sub{
  font-family:system-ui,sans-serif;
  font-size:1rem;color:var(--muted);
  line-height:1.6;margin:0 auto 28px;max-width:520px;
}
.titlepage .tp-rule{
  width:76px;height:2px;margin:0 auto 26px;
  background:linear-gradient(90deg,var(--copper),var(--rose));
}
.titlepage .tp-author{
  font-family:Georgia,serif;font-size:1.18rem;letter-spacing:.04em;
  color:var(--ink);margin:0 0 8px;
}
.titlepage .tp-date{
  font-family:system-ui,sans-serif;font-size:.82rem;
  color:var(--muted);margin:0;
}
ul.terms{list-style:none;padding:0;margin:20px 0 0}
ul.terms li{
  position:relative;padding-left:24px;margin-bottom:11px;
  font-size:.97rem;line-height:1.62;
}
ul.terms li::before{
  content:"✠";position:absolute;left:0;top:0;
  color:var(--crimson);font-size:.82rem;
}
@media (max-width:600px){ .titlepage{padding:56px 0 48px} }

/* ================= articles =================
   The index card list and the long-form article body. Serif for reading,
   sans for chrome and callouts — the same split the rest of the site uses. */

.articlelist{display:grid;gap:18px;margin:24px 0 4px}

.artcard{
  display:block;
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
  padding:24px 26px 22px;
  text-decoration:none;
  color:inherit;
  position:relative;
  transition:box-shadow .22s ease,border-color .22s ease,transform .22s ease;
}
.artcard::before{
  content:"";
  position:absolute;top:0;left:26px;right:26px;height:2px;
  background:linear-gradient(90deg,var(--copper),var(--rose));
}
.artcard:hover{
  border-color:#d8cdbc;
  box-shadow:0 6px 22px rgba(26,23,20,.09);
  transform:translateY(-2px);
}
.artcard .num{
  font-family:system-ui,sans-serif;font-size:.7rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--copper);display:block;margin-bottom:8px;
}
.artcard h3{
  font-family:Georgia,'Times New Roman',serif;font-size:1.34rem;
  margin:0 0 10px;line-height:1.3;color:var(--ink);
}
.artcard p{
  font-family:system-ui,sans-serif;font-size:.92rem;line-height:1.66;
  color:#3b3630;margin:0 0 14px;
}
.artcard .go{
  font-family:system-ui,sans-serif;font-size:.78rem;letter-spacing:.07em;
  text-transform:uppercase;color:var(--crimson);
}

/* ---- the article itself ---- */
.post .hero .kicker{
  font-family:system-ui,sans-serif;font-size:.7rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--copper);margin:0 0 10px;
}
.post .hero h1{max-width:820px;margin-left:auto;margin-right:auto}
.post .hero .byline{
  font-family:system-ui,sans-serif;font-size:.82rem;color:var(--muted);
  margin-top:16px;
}

.postbody{max-width:720px}

/* figures — authored as vector diagrams (SVG)
   Two contexts: inside an article body (.postbody .fig, narrower column) and
   inside a page section (.figw .fig, full section width). Same visual language. */
.figw{
  margin:34px 0 30px;
  /* break out of the 740px prose column: the diagrams are authored at 900px
     and scaling them into the text column made their labels too small */
  width:min(980px,calc(100vw - 44px));
  position:relative;
  left:50%;
  transform:translateX(-50%);
}
.fig{
  margin:0;padding:0;
  border:1px solid var(--line);
  border-radius:6px;
  background:#fff;
  overflow:hidden;
}
.fig img{display:block;width:100%;height:auto}
.fig figcaption{
  font-family:system-ui,sans-serif;font-size:.8rem;line-height:1.55;
  color:var(--muted);padding:12px 16px 14px;
  border-top:1px solid var(--line);background:#fdfcfa;
}
.fig .fignum{
  font-weight:700;color:var(--copper);
  letter-spacing:.06em;text-transform:uppercase;font-size:.72rem;
}
@media (max-width:600px){
  .figw{margin:26px 0 24px}
  .fig figcaption{font-size:.76rem;padding:10px 12px 12px}
}

/* ---- figures too small to read + the overlay that fixes it ----
   Marked by shell.js only when the displayed figure is narrower than the width
   at which its labels render legibly (~861px). On a desktop the figures are
   already wide enough, so nothing is marked and nothing changes. */
.fig-zoomable{cursor:zoom-in}
.fig-zoomable img{display:block}
.fig-zoomable .figcaption,
.fig-zoomable figcaption{position:relative}
.fig-zoomable{position:relative}
/* The badge sits BELOW the figure, not over it. Positioned inside the top-right
   corner it covered real labels — "THE CTMU" and "REBIRTH" in two of the
   diagrams (measured against each SVG's text coordinates). A diagram whose
   point is its own labels must not have one hidden by the affordance that
   offers to show them. It lives in the caption strip instead. */
.fig-zoomable::after{
  /* The badge text is a CSS variable so i18n.js can translate it.
     A ::after pseudo-element cannot carry data-i18n, so the dictionary is
     applied by setting --fig-zoom-label on <html> from JS. English is the
     default written here, so a JS-off reader always sees something sensible. */
  content:var(--fig-zoom-label, "\26A2  Tap to enlarge");
  position:absolute;right:8px;bottom:6px;
  font-family:system-ui,sans-serif;font-size:.72rem;
  letter-spacing:.04em;color:#fff;background:rgba(143,29,36,.92);
  padding:6px 11px;border-radius:999px;pointer-events:none;
}
/* the caption strip wraps the badge, so give it room and keep the text clear */
.fig-zoomable figcaption{padding-right:132px;min-height:34px}

.figzoom{
  border:none;padding:0;background:#fff;max-width:none;max-height:none;
  width:100vw;height:100vh;margin:0;
}
.figzoom::backdrop{background:rgba(26,23,20,.86)}
.figzoom-bar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 14px;background:#1a1714;color:#f8f5f0;
  font-family:system-ui,sans-serif;font-size:.76rem;
}
.figzoom-hint{opacity:.85}
.figzoom-close{
  border:1px solid rgba(248,245,240,.4);background:transparent;color:#f8f5f0;
  width:44px;height:44px;border-radius:999px;cursor:pointer;font-size:1rem;
  line-height:1;flex:0 0 auto;
}
.figzoom-close:hover{background:rgba(248,245,240,.15)}
.figzoom-stage{
  overflow:auto;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y;
  height:calc(100vh - 64px);background:#fff;
  display:flex;
}
/* margin:auto (not place-items/justify-content) so a figure larger than the
   stage scrolls from its true top-left instead of being clipped at the start —
   the classic centred-flex overflow bug. */
.figzoom-stage img{display:block;width:861px;max-width:none;height:auto;margin:auto}
@media (min-width:861px){
  /* wider viewports can fit it, so scale down instead of scrolling */
  .figzoom-stage img{width:auto;max-width:100%;max-height:calc(100vh - 90px)}
}

/* figures — authored as vector diagrams (SVG) inside the article body */
.postbody .fig{
  margin:34px 0 30px;
  padding:0;
  border:1px solid var(--line);
  border-radius:6px;
  background:#fff;
  overflow:hidden;
}
.postbody .fig img{display:block;width:100%;height:auto}
.postbody .fig figcaption{
  font-family:system-ui,sans-serif;font-size:.8rem;line-height:1.55;
  color:var(--muted);padding:12px 16px 14px;
  border-top:1px solid var(--line);background:#fdfcfa;
}
.postbody .fig .fignum{
  font-weight:700;color:var(--copper);
  letter-spacing:.06em;text-transform:uppercase;font-size:.72rem;
}
.postbody blockquote{
  margin:24px 0;padding:16px 22px;
  border-left:3px solid var(--rose);
  background:#fdfcfa;
  font-style:italic;color:#3b3630;
}
.postbody blockquote p{margin:0}
@media (max-width:600px){
  .postbody .fig{margin:26px 0 24px}
  .postbody .fig figcaption{font-size:.76rem;padding:10px 12px 12px}
}
.postbody h2{
  font-family:Georgia,serif;font-size:1.42rem;line-height:1.32;
  margin:44px 0 16px;padding-top:22px;
  border-top:1px solid var(--line);
}
.postbody h2:first-of-type{border-top:0;padding-top:0;margin-top:26px}
.postbody h3{
  font-family:Georgia,serif;font-size:1.16rem;font-weight:700;line-height:1.38;
  margin:32px 0 12px;color:var(--ink);
}
.postbody h4{
  font-family:system-ui,sans-serif;font-size:.8rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--copper);margin:26px 0 10px;
}

/* ---- heading levels promoted for a correct document outline ----
   26 articles jumped straight from the <h1> title to their body sections at
   h3/h4, so a screen reader (and Google) got an outline with a hole in it.
   The sections are now h2, which is what they always were structurally.

   A promoted tag inherits different CSS, so each carries a class that renders
   it EXACTLY as before. These rules are deliberately identical to the
   .postbody h2/h3/h4 rules above, one level down. Prose was never touched —
   tags and classes only. */
.postbody h2.sect-h3{
  font-family:Georgia,serif;font-size:1.16rem;font-weight:700;line-height:1.38;
  margin:32px 0 12px;color:var(--ink);
  padding-top:0;border-top:0;
}
/* font-weight:700 and line-height:1.72 are BOTH required, not decorative.
   The originals were h3/h4 inheriting the body's line-height:1.72 and the
   browser default bold. A promoted h2 instead inherits `h2{font-weight:normal}`
   and `.postbody h2{line-height:1.32}` — so the heading rendered thin and 5.1px
   per line too tight. Invisible in source; measured 460k differing pixels. */
.postbody h2.sect-h4,
.postbody h3.sect-h4{
  font-family:system-ui,sans-serif;font-size:.8rem;letter-spacing:.1em;
  font-weight:700;line-height:1.72;text-transform:uppercase;color:var(--copper);
  margin:26px 0 10px;padding-top:0;border-top:0;
}
.postbody h2.cta-h{
  /* the closing CTA was already an h2 and keeps its size; it sits in a
     bordered section of its own, so it does not want the section rule either */
  font-size:1.42rem;
}
@media(max-width:620px){
  .postbody h2.sect-h3{font-size:1.1rem;margin-top:28px}
}
.postbody p{margin:0 0 17px}
.postbody .lede{
  font-size:1.06rem;color:#3b3630;font-style:italic;
  border-left:2px solid var(--rose);padding-left:16px;margin:22px 0;
}
.postbody .callout-h{
  font-family:Georgia,serif;font-size:1.2rem;color:var(--crimson);
  margin:34px 0 14px;
}
.postbody ol,.postbody ul{
  margin:0 0 18px;padding-left:26px;
  font-family:system-ui,sans-serif;font-size:.95rem;line-height:1.7;
}
.postbody li{margin-bottom:9px}
.postbody code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.87em;background:#f2ede5;padding:2px 5px;border-radius:3px;
}
.postbody .rule{
  border:0;border-top:1px solid var(--line);margin:38px 0;
}
.postbody .enonly{
  font-family:system-ui,sans-serif;font-size:.82rem;line-height:1.6;
  color:var(--muted);background:#fdf9ef;border:1px solid var(--line);
  border-radius:5px;padding:12px 16px;margin:0 0 28px;
}
.postbody .cta{border-top:1px solid var(--line);padding-top:30px;margin-top:8px}
@media(max-width:620px){
  .postbody h2{font-size:1.24rem;margin-top:34px}
  .artcard{padding:20px 20px 18px}
}

/* ================= FLOATING CONTROLS vs THE TEXT COLUMN =================
   The music pill (.music-player, fixed bottom-right) and the back-to-top
   button (.totop, fixed bottom-left) sit at the viewport corners. Above
   1000px the centered 740-760px column leaves a wide enough gutter and they
   never touch text. Below that the gutter closes and they land on the ends of
   real lines — measured on /objectivity-vs-subjectivity/ and /about/.

   This block is LAST in the file on purpose: .postbody sets its own
   max-width:720px far above, so an earlier media query loses the cascade and
   the article column stays full width. Keeping this at the end guarantees it
   wins. Reserve the gutter by narrowing the reading column rather than moving
   the controls — the text is what the reader came for, but the buttons must
   stay reachable.
   ------------------------------------------------------------------------ */
@media(max-width:1000px){
  .wrap,.wrap-wide,.postbody,
  .postbody.wrap,.postbody .wrap{max-width:calc(100vw - 180px)}
  /* .figw deliberately breaks OUT of the prose column to min(980px,100vw-44px)
     so diagram labels stay readable. That breakout ignores the reserved gutter,
     so at ~900px a figure caption still slides under the player. Constrain the
     breakout too, but keep it wider than the text column. */
  .figw{width:min(980px,calc(100vw - 180px))}
  .music-player{right:8px;bottom:8px;padding:5px 6px;gap:5px}
  .od-btn{padding:8px 10px;font-size:.72rem}
  .od-btn .od-txt{display:none}
  .od-note{display:none}
}
@media(max-width:620px){
  /* Phones are full-width by design, so there is no page margin for a fixed
     control to sit in — anything floating in the corner covers the end of a
     line. Two things reduce it to a single clipped word at the very corner:
       - one button instead of two. Mute is redundant on a phone: browsers
         block autoplay, so sound only ever starts from a deliberate tap, and
         that same button pauses it again.
       - 48px, which is still a comfortable thumb target.
     Measured coverage of the text column: 2.25% -> 0.88% of characters.
     .od-btn-sm stays in the DOM (shell.js binds it) and is hidden on phones;
     the play button still shows playing state by turning copper. */
  .wrap,.wrap-wide,.postbody,
  .postbody.wrap,.postbody .wrap{max-width:none}
  .figw{width:min(980px,calc(100vw - 44px))}
  .music-player{right:12px;bottom:12px;padding:0;gap:0;min-width:0;min-height:0}
  .od-btn{padding:0;width:48px;height:48px;justify-content:center;font-size:.95rem}
  .od-btn .od-txt{display:none}
  .od-btn-sm{display:none}
  .od-note{display:none}
  body{padding-bottom:72px}
}
/* the back-to-top button gets the same 44px treatment on touch screens */
@media(max-width:620px){
  .totop{width:44px;height:44px}
  /* Every remaining control was 28-39px tall — under the 44px minimum, and on
     a phone the footer links are the ONLY navigation a JS-off reader has.
     Padding does the work here so nothing changes visually; the hit area just
     grows to where a thumb can actually reach it. */
  .brand{padding:8px 0;display:inline-block}
  .donate{padding:12px 16px}
  .navtoggle{width:44px;height:44px}
  #langselect{padding:11px 10px}
  .ftag a{padding:11px 3px;min-height:44px;display:inline-flex;align-items:center}
}

/* --- article video embeds (Syntara) -------------------------------------
   Self-hosted poster; YouTube loads only on click. Keeps the site's
   "no trackers" promise literally true on every article page.

   DELIBERATELY NOT .fig / .figw. shell.js's figure-zoom feature selects
   ".fig img, .figw img" and, below FIG_READABLE (861px), preventDefault()s the
   click and opens its zoom dialog instead. On a phone that would steal the
   "Watch the video" tap and never play anything. So this borrows the column
   breakout by hand and stays out of that selector.                             */
.odvideo{
  margin:34px 0 30px;
  /* Break out of the 740px prose column and centre in the viewport.
     DIRECTION-AGNOSTIC ON PURPOSE: the usual .figw trick
     (position:relative; left:50%; transform:translateX(-50%)) is PHYSICAL,
     so under dir="rtl" (Arabic) left:50% is measured from the right edge and
     the figure hangs off the side of the page. margin-inline is logical, so
     this centres identically in LTR and RTL. Verified Arabic at
     1440/1100/900/700/390px, 0px overflow.                                  */
  width:min(980px,calc(100vw - 44px));
  margin-inline:auto;
  padding:0;
  max-width:100%;
}
.odvideo .odv-face{
  display:block; position:relative; border:1px solid var(--line);
  border-radius:6px; overflow:hidden; background:#0d0d0d; line-height:0;
  cursor:pointer; text-decoration:none;
}
.odvideo .odv-face img{ width:100%; height:auto; display:block; opacity:.86; }
.odvideo .odv-face:hover img{ opacity:1; }
.odvideo .odv-play{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
}
.odvideo .odv-play span{
  display:flex; align-items:center; gap:10px;
  padding:11px 20px; border-radius:999px;
  background:rgba(20,18,16,.78); color:#fff;
  font-size:.95rem; letter-spacing:.02em; line-height:1;
}
.odvideo .odv-face:hover .odv-play span{ background:var(--crimson,#8f1d24); }
.odvideo iframe{
  display:block; width:100%; aspect-ratio:16/9; border:0;
}
.odvideo figcaption{
  margin-top:10px; font-size:.9rem; color:var(--ink-soft,#6b6360);
}

/* ---- article narration — "listen to this article" ----------------------
   Mirrors .odvideo exactly (same width, same logical centring) so a page
   carrying one has one consistent block, not two. Lives in style.css, NOT
   in a per-page <style>: build.py's extract_fragment() lifts only <main>,
   so head CSS is silently discarded on the built page.               */
.odaudio{
  margin:34px 0 30px;
  width:min(980px,calc(100vw - 44px));
  margin-inline:auto;
  padding:0;
  max-width:100%;
}
.odaudio .oda-face{
  display:block; position:relative; border:1px solid var(--line);
  border-radius:6px; overflow:hidden; background:#0d0d0d;
  padding:26px 24px; cursor:pointer; text-decoration:none;
  background-image:linear-gradient(120deg,#151210,#1d1714 60%,#241a16);
}
.odaudio .oda-face:hover{ border-color:var(--crimson,#8f1d24); }
.odaudio .oda-kind{
  display:block; font-size:.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold,#c9a227); margin-bottom:8px;
}
.odaudio .oda-title{
  display:block; font-size:1.06rem; color:#f4efea; margin-bottom:6px;
  font-weight:600; line-height:1.35;
}
.odaudio .oda-meta{ display:block; font-size:.88rem; color:#b9ada6; }
.odaudio .oda-play{
  display:inline-flex; align-items:center; gap:10px; margin-top:16px;
  padding:11px 20px; border-radius:999px;
  background:rgba(20,18,16,.78); color:#fff;
  font-size:.95rem; letter-spacing:.02em; line-height:1;
}
.odaudio .oda-face:hover .oda-play{ background:var(--crimson,#8f1d24); }
.odaudio .oda-controls{ margin-top:0; }
.odaudio .oda-controls audio{ display:block; width:100%; }
.odaudio.oda-playing .oda-face{ display:none; }
.odaudio figcaption{
  margin-top:10px; font-size:.9rem; color:var(--ink-soft,#6b6360);
}
/* the label inside the pill is an i18n key so it translates like the video
   badge does; the ::after trick is avoided here because the pill already
   contains a real element we can key. */


/* --- publication date beside the Part kicker (Syntara, 25 Oct 2026) -------
   Added because every Article in the structured data now declares a
   datePublished, and a claim about a date should be visible on the page that
   makes it. Deliberately quiet: same line as the kicker, one weight down. */
.pubdate{opacity:.62;font-weight:400;white-space:nowrap}
