/* Stacy Dean Campbell — site styles
   Ground: the concrete of the jacket. Panels: paper laid on it.
   Display: Anton (stamped). Prose: Fraunces. Furniture: Inter. */

:root{
  --concrete:#BFBDB7; --concrete-2:#CDCBC5; --concrete-3:#CAC8C2;
  --paper:#F2F0EB; --paper-2:#E8E5DE;
  --ink:#14130F; --ink-2:#3A382F; --ink-soft:#4A4740;
  --rule:#9B988E; --rule-soft:#D2CFC7;
  --oxide:#8A3B2A; --oxide-hi:#A04835;
  --ochre:#5E4313;
  --on-oxide:#F7F4EE; --oxide-txt:#73301F; --ochre-slab:#C9A055;
  --slab:#14130F; --plate:#0C0B0A;
  --on-dark:#F2F0EB; --on-dark-2:#C3BFB4; --on-dark-3:#8C8779;
  --dark-field:#211F1B; --dark-edge:#454239;
  --shadow:rgba(20,19,15,.20); --shadow-deep:rgba(20,19,15,.36);

  --display:"Anton",Impact,"Arial Narrow",sans-serif;
  --prose:"Fraunces",Georgia,"Times New Roman",serif;
  --ui:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --fs-3xs:.6875rem; --fs-2xs:.75rem; --fs-xs:.8125rem; --fs-sm:.875rem; --fs-base:1rem; --fs-md:1.0625rem; --fs-lg:1.15rem; --fs-xl:1.3rem;

  /* Display sizes. There was a scale for body text and none for headings, so
     every heading had been given its own hand-written clamp -- nine of them,
     two near-identical. These are the roles the design actually has. A heading
     picks a role; it does not invent a size. */
  /* The hero keeps a responsive step rather than one smooth curve. Collapsing
     its three clamps into a single line was tempting and wrong: it matched at
     375px and 1440px and drifted up to 20px in between, which is a redesign of
     the loudest thing on the page dressed up as a tidy-up. The steps move into
     the token, so the role is named in one place and what renders is unchanged. */
  --ds-hero:clamp(3.1rem, 10vw, 6.3rem);             /* the one title on a page */
  /* These are the curves the design already had, given names. Re-deriving them
     "properly" was the second temptation and also wrong: new coefficients mean
     new interpolated sizes at every width, so tidying the source made the page
     render MORE distinct sizes than before, not fewer. Naming a role is the
     work; inventing a size is a redesign. */
  --ds-title:clamp(2.4rem, 7vw, 4.4rem);      /* section-opening titles */
  --ds-section:clamp(2rem, 5vw, 3.2rem);      /* a thesis statement */
  --ds-head:clamp(1.55rem, 3.4vw, 2.2rem);    /* ordinary section heads */
  --ds-quote:clamp(1.3rem, 3.4vw, 2.05rem);   /* a pulled quotation */
  --ds-lead:clamp(1.05rem, 2.1vw, 1.3rem);    /* a standfirst */

  /* Spacing, on a 4px grid. 38 distinct values were rendering, 29 of them off
     any grid -- 0.15rem here, 0.45rem there, 0.78rem somewhere else. Each was
     defensible alone and together they are not a system. New work uses these. */
  --s-1:.25rem; --s-2:.5rem;  --s-3:.75rem; --s-4:1rem;
  --s-5:1.5rem; --s-6:2rem;   --s-7:3rem;   --s-8:4rem; --s-9:6rem;
  --wrap:1160px; --gut:clamp(1.25rem,4vw,3rem);
}
/* Dark is a LAYERING, not each light value darkened on its own. In light mode
   the ground is mid-grey, so panels separate by going both lighter (paper) and
   darker (slab). Darkening every token independently put the ground at #191816
   while --slab stayed #0C0B0A, so the panel carrying the whole design sat at
   1.04:1 against the page behind it and every section boundary dissolved.
   Here the ground is the floor and every surface steps UP from it, one
   direction, ~1.2:1 a step. Every text token clears 4.5:1 on every surface. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --concrete:#0B0A09; --concrete-2:#070706; --concrete-3:#141210;
  --paper:#2C2824; --paper-2:#3A3530;
  --ink:#EDEAE2; --ink-2:#CBC7BC; --ink-soft:#A8A296;
  --rule:#4A453C; --rule-soft:#332F2A;
  --oxide:#CE7157; --oxide-hi:#E08C71; --ochre:#C9A055;
  --on-oxide:#1B0E09; --oxide-txt:#E08C71;
  --slab:#1C1916;
  --plate:#0B0A09;
  --shadow:rgba(0,0,0,.6); --shadow-deep:rgba(0,0,0,.8);
  --dark-field:#131110; --dark-edge:#4A453C;
  }
}
:root[data-theme="dark"]{
  --concrete:#0B0A09; --concrete-2:#070706; --concrete-3:#141210;
  --paper:#2C2824; --paper-2:#3A3530;
  --ink:#EDEAE2; --ink-2:#CBC7BC; --ink-soft:#A8A296;
  --rule:#4A453C; --rule-soft:#332F2A;
  --oxide:#CE7157; --oxide-hi:#E08C71; --ochre:#C9A055;
  --on-oxide:#1B0E09; --oxide-txt:#E08C71;
  --slab:#1C1916;
  --plate:#0B0A09;
  --shadow:rgba(0,0,0,.6); --shadow-deep:rgba(0,0,0,.8);
  --dark-field:#131110; --dark-edge:#4A453C;
}

*{box-sizing:border-box}
/* The header is sticky and 63.6px tall: without this, tabbing backwards to a
   control scrolls it to top:0 and puts it entirely underneath the header. */
html{scroll-padding-top:5rem;scroll-behavior:smooth}
body{
  margin:0;background:var(--concrete);color:var(--ink);
  font-family:var(--ui);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
  background-image:repeating-linear-gradient(101deg,rgba(0,0,0,.012) 0 1px,transparent 1px 4px),
                   repeating-linear-gradient(11deg,rgba(255,255,255,.014) 0 1px,transparent 1px 6px);
}
img{max-width:100%;height:auto;display:block}
/* the two places an image is deliberately sized by its box rather than its own
   proportions; both use object-fit so nothing distorts */
.plate picture.bgplate img,.banner img{height:100%}
a{color:inherit}
:focus-visible{outline:2px solid var(--oxide);outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}html{scroll-behavior:auto}}
.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gut)}
hr.rule{height:1px;background:var(--rule);border:0;margin:0}
.skip{position:absolute;left:-9999px}
/* A label that is read but not seen. */
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip:focus{left:1rem;top:1rem;z-index:99;background:var(--ink);color:var(--concrete);padding:var(--s-3) 1rem}

.stamp{font-family:var(--display);font-weight:400;text-transform:uppercase;letter-spacing:.005em;line-height:.86;text-wrap:balance}
.eyebrow{font-family:var(--ui);font-size:var(--fs-2xs);font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ochre);margin:0}
.prose{font-family:var(--prose);font-size:var(--fs-md);line-height:1.72;color:var(--ink-2);max-width:64ch}
.prose p{margin:0 0 1.05em}.prose p:last-child{margin-bottom:0}
.prose strong{color:var(--ink);font-weight:600}

/* masthead */
.epigraph{background:var(--slab);color:var(--on-dark-3);border-bottom:1px solid var(--dark-edge)}
.epigraph p{margin:0;padding-block:.6rem;font-family:var(--prose);font-style:italic;font-size:var(--fs-sm);text-align:center;line-height:1.4}
.epigraph b{color:var(--on-dark-2);font-style:normal;font-weight:500;font-family:var(--ui);font-size:var(--fs-3xs);letter-spacing:.12em;text-transform:uppercase}
header.site{position:sticky;top:0;z-index:60;background:color-mix(in srgb,var(--concrete) 90%,transparent);backdrop-filter:saturate(1.15) blur(12px);border-bottom:1px solid var(--rule)}
.bar{display:flex;align-items:center;gap:1.5rem;padding-block:.85rem;justify-content:space-between;flex-wrap:wrap}
.mark{font-family:var(--display);text-transform:uppercase;font-size:var(--fs-lg);letter-spacing:.015em;text-decoration:none;white-space:nowrap;line-height:1;display:inline-flex;align-items:center;min-height:30px}
.mark i{color:var(--oxide-txt);font-style:normal}
nav.main{display:flex;gap:1.35rem;flex-wrap:wrap}
nav.main a{font-family:var(--ui);font-size:var(--fs-2xs);font-weight:500;letter-spacing:.11em;text-transform:uppercase;text-decoration:none;border-bottom:1px solid transparent;padding-bottom:3px;color:var(--ink-soft)}
nav.main a:hover{color:var(--ink);border-bottom-color:var(--oxide-txt)}
nav.main a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--ink);font-weight:600}
/* ---- the menu on a phone -------------------------------------------------
   Seven links need 540px. A 390px phone has about 184px once the wordmark and
   the gutters are paid for, so they wrapped onto four rows and the header ate
   the top of every page before a word of it was read. They fit on one row only
   at 826px, which is where the toggle hands over.

   The button is markup, not script: with JS off the nav is simply visible,
   which is why the panel is hidden by a class on the header rather than by
   `display:none` on the nav itself. */
.navtoggle{display:none}
@media (max-width:825px){
  .bar{gap:var(--s-3);flex-wrap:nowrap}
  .navtoggle{
    display:flex;flex-direction:column;justify-content:center;gap:5px;
    /* flex:none, or the wordmark beside it compresses the button below the
       24x24 minimum — measured at 23x44 on the reader page before this. A
       width alone is a suggestion inside a flex row. */
    flex:0 0 44px;
    width:44px;height:44px;padding:0 10px;margin-inline-start:auto;
    background:none;border:0;cursor:pointer;
  }
  .navtoggle span{display:block;height:2px;background:var(--ink);transition:transform .18s ease,opacity .18s ease}
  .navtoggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .navtoggle[aria-expanded="true"] span:nth-child(2){opacity:0}
  .navtoggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
  /* Only hidden once the script is there to reveal it again. */
  html.js nav.main{display:none}
  html.js .bar.open nav.main{
    display:flex;flex-direction:column;gap:0;
    position:absolute;left:0;right:0;top:100%;
    background:var(--concrete);border-bottom:1px solid var(--rule);
    padding:.35rem var(--gut) 1rem;
  }
  html.js .bar.open nav.main a{
    padding:.9rem 0;border-bottom:1px solid var(--rule-soft);
    font-size:var(--fs-xs);min-height:44px;display:flex;align-items:center;
  }
  html.js .bar.open nav.main a:last-child{border-bottom:0}
  header.site{position:sticky}
  .bar{position:relative}
}
@media (prefers-reduced-motion:reduce){.navtoggle span{transition:none}}


.sec{padding-block:clamp(2.75rem,6vw,4.75rem)}
.sec-tight{padding-block:0 clamp(2.75rem,6vw,4.75rem)}
.sec-head{display:flex;align-items:baseline;gap:1.15rem;margin-bottom:1.9rem;flex-wrap:wrap}
.sec-head h2{font-family:var(--prose);font-weight:600;font-size:var(--ds-head);margin:0;line-height:1.12;letter-spacing:-.015em}
.sec-head hr{flex:1;align-self:center;min-width:2rem}
.panel{background:var(--paper);border:1px solid var(--rule-soft);box-shadow:0 10px 26px -16px var(--shadow);padding:clamp(1.4rem,3.4vw,2.4rem)}

.btn{display:inline-flex;align-items:center;gap:var(--s-2);font-family:var(--ui);font-size:var(--fs-xs);font-weight:600;letter-spacing:.09em;text-transform:uppercase;padding:.82rem 1.35rem;text-decoration:none;border:1px solid var(--ink);cursor:pointer;background:none;color:var(--ink);transition:transform .12s ease,background .12s ease,color .12s ease}
.btn:hover{transform:translateY(-1px)}
.btn-solid{background:var(--oxide);border-color:var(--oxide);color:var(--on-oxide)}
.btn-solid:hover{background:var(--oxide-hi);border-color:var(--oxide-hi)}
.btn-ghost:hover{background:var(--ink);color:var(--concrete)}
.cta-row{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:1.8rem}

/* hero on an archive plate */
.plate{position:relative;background:var(--plate);border-bottom:1px solid var(--dark-edge);overflow:hidden;isolation:isolate}
/* Only the right 1336px of the source survived the old composite, so the photograph is given the
   right of the band at close to native resolution rather than stretched across the full width and
   hidden under the copy panel. Magnification drops from 2.16x to about 1.3x. */
.plate picture.bgplate{position:absolute;top:0;right:0;height:100%;width:68%;z-index:0;display:block;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,rgba(0,0,0,.55) 10%,#000 30%);
          mask-image:linear-gradient(90deg,transparent 0,rgba(0,0,0,.55) 10%,#000 30%)}
.plate picture.bgplate img{width:100%;height:100%;object-fit:cover;object-position:62% 50%;filter:contrast(1.03) saturate(1.04)}
@media (max-width:880px){ :root{ --ds-hero:clamp(2.6rem, 12vw, 4rem); } }
@media (max-width:420px){ :root{ --ds-hero:clamp(2.3rem, 13vw, 3.2rem); } }
@media (max-width:880px){.plate picture.bgplate{width:100%;-webkit-mask-image:none;mask-image:none}}
.plate::after{content:"";position:absolute;inset:0;z-index:1;background:
  linear-gradient(95deg,rgba(9,8,7,.97) 0%,rgba(9,8,7,.93) 26%,rgba(9,8,7,.72) 42%,rgba(9,8,7,.34) 58%,rgba(9,8,7,.12) 76%,rgba(9,8,7,.06) 100%),
  linear-gradient(to top,rgba(9,8,7,.72) 0%,rgba(9,8,7,.28) 16%,rgba(9,8,7,0) 40%)}
/* on a phone the copy stacks at the TOP of the band, so the shading has to run the
   other way - dark where the type is, easing off over the jacket below. */
@media (max-width:880px){.plate::after{background:
  linear-gradient(to bottom,rgba(9,8,7,.96) 0%,rgba(9,8,7,.94) 55%,rgba(9,8,7,.88) 78%,rgba(9,8,7,.72) 100%)}}
.plate .wrap{position:relative;z-index:2}
.hero-grid{display:grid;grid-template-columns:1.08fr .92fr;gap:clamp(1.75rem,5vw,4.25rem);align-items:center}
@media (max-width:880px){.hero-grid{grid-template-columns:1fr;gap:2.25rem}}
.plate .hero-grid{padding-block:clamp(2.75rem,6.5vw,5.25rem) clamp(3.25rem,7vw,5.5rem)}
.plate .hero-grid>div:first-child{position:relative;padding-block:.25rem}
.plate h1,.plate .hook,.plate .pubmeta,.plate .eyebrow{text-shadow:0 1px 14px rgba(9,8,7,.55)}
.plate h1{color:var(--on-dark);margin:.9rem 0 0;font-size:var(--ds-hero)}
.plate .hook{color:var(--on-dark);border-left-color:var(--ochre-slab)}
.plate .pubmeta{color:var(--on-dark-2);border-top-color:rgba(242,240,235,.26)}
.plate .pubmeta b{color:var(--on-dark)}
.plate .pubmeta s{color:var(--on-dark-3)}
.plate .eyebrow{color:var(--ochre-slab)}
.plate .btn-ghost{color:var(--on-dark);border-color:var(--on-dark)}
.plate .btn-ghost:hover{background:var(--on-dark);color:var(--plate)}
.credit{position:relative;z-index:2;margin:0;padding-bottom:1.1rem;font-size:var(--fs-3xs);line-height:1.5;letter-spacing:.04em;color:#B7B1A5;max-width:64ch;text-shadow:0 1px 3px rgba(9,8,7,.9)}
.credit em{font-style:italic}
.hook{font-family:var(--prose);font-size:var(--ds-lead);line-height:1.5;color:var(--ink);margin:1.5rem 0 0;max-width:40ch;border-left:3px solid var(--oxide);padding-left:1.1rem}
.pubmeta{display:flex;flex-wrap:wrap;gap:.4rem .85rem;align-items:center;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--rule);font-size:var(--fs-2xs);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft);font-weight:500}
.pubmeta b{color:var(--ink);font-weight:600}
.pubmeta s{color:var(--rule);text-decoration:none}
.cover-stage{display:flex;justify-content:center}
/* align-self, not the default stretch. The cover sits inside a <picture>
   that is a row flex container; a stretched flex item takes its cross size
   from the line, and an image with an aspect-ratio then derives its WIDTH
   from that height — which is zero until something gives the line a height.
   The base rule sets an explicit width so it never showed; the narrow
   override switches to width:auto and the cover collapses to nothing. */
/* object-fit, because a max-height and a definite width together describe a
   box that is not the cover's shape: 240 wide against a 42vh cap gives 240x312
   for a jacket that is 700x1066, and without this the artwork is squashed to
   fit it. Contain keeps the proportions and gives back the difference. */
.cover-stage img{align-self:center;object-fit:contain;width:min(100%,360px);filter:drop-shadow(0 24px 36px var(--shadow-deep)) drop-shadow(0 4px 10px var(--shadow))}

/* page banner for interior pages */
.banner{position:relative;background:var(--plate);overflow:hidden;border-bottom:1px solid var(--dark-edge)}
.banner img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 55%;filter:contrast(1.04) brightness(1);z-index:0}
.banner::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(97deg,rgba(10,9,8,.90) 0%,rgba(10,9,8,.70) 46%,rgba(10,9,8,.28) 100%)}
.banner .wrap{position:relative;z-index:2;padding-block:clamp(2.25rem,5.5vw,3.75rem)}
.banner h1{color:var(--on-dark);margin:var(--s-3) 0 0;font-size:var(--ds-title)}
.banner .eyebrow{color:var(--ochre-slab)}
.banner .lede{font-family:var(--prose);color:var(--on-dark-2);font-size:var(--fs-md);max-width:56ch;margin:1rem 0 0;line-height:1.6}

/* quotes */
.band{background:var(--concrete-2);border-block:1px solid var(--rule)}
.quotes{display:grid;grid-template-columns:repeat(3,1fr);padding-block:clamp(1.9rem,4vw,2.9rem);gap:0}
@media (max-width:880px){.quotes{grid-template-columns:1fr}}
.q{padding:0 clamp(1rem,2.4vw,2rem);border-left:1px solid var(--rule);display:flex;flex-direction:column}
.q:first-child{border-left:0;padding-left:0}
@media (max-width:880px){.q{border-left:0;padding-left:0;padding-block:1.3rem;border-top:1px solid var(--rule)}.q:first-child{border-top:0;padding-top:0}}
.q blockquote{margin:0;font-family:var(--prose);font-size:var(--fs-base);line-height:1.52;color:var(--ink);text-wrap:pretty}
.q cite{display:block;margin-top:auto;padding-top:var(--s-3);font-family:var(--ui);font-style:normal;font-size:var(--fs-3xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}

/* thesis */
.thesis{background:var(--slab);color:var(--on-dark)}
.thesis-in{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,4vw,3.5rem);align-items:center;padding-block:clamp(2.5rem,5.5vw,4rem)}
@media (max-width:880px){.thesis-in{grid-template-columns:1fr}}
.thesis .eyebrow{color:var(--ochre-slab)}
.thesis h2{font-family:var(--display);text-transform:uppercase;font-size:var(--ds-section);line-height:.92;margin:var(--s-3) 0 0;color:var(--on-dark)}
.thesis p{font-family:var(--prose);font-size:var(--fs-md);line-height:1.68;color:var(--on-dark-2);margin:1.1rem 0 0;max-width:46ch}
.mediums{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--dark-edge);border:1px solid var(--dark-edge)}
.med{background:var(--slab);padding:1.15rem 1.1rem}
.med .n{font-family:var(--display);text-transform:uppercase;font-size:var(--fs-lg);color:var(--on-dark);line-height:1}
.med .d{font-size:var(--fs-2xs);color:var(--on-dark-3);margin-top:.4rem;line-height:1.45}
.med .d b{color:var(--ochre-slab);font-weight:600}

/* work index */
.filters{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1.4rem}
.filters button{font-family:var(--ui);font-size:var(--fs-3xs);font-weight:600;letter-spacing:.11em;text-transform:uppercase;padding:.5rem .85rem;border:1px solid var(--rule);background:none;color:var(--ink-soft);cursor:pointer;transition:background .12s ease,color .12s ease,border-color .12s ease}
.filters button:hover{border-color:var(--ink);color:var(--ink)}
.filters button[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--concrete)}
.work{border-top:1px solid var(--rule)}
.row{display:grid;grid-template-columns:5.5rem 1fr 9rem 10rem;gap:1rem 1.25rem;align-items:baseline;padding:1rem 0;border-bottom:1px solid var(--rule-soft)}
@media (max-width:820px){.row{grid-template-columns:4.5rem 1fr;gap:var(--s-1) .9rem}.row .med-col,.row .note{grid-column:2}}
.row .yr{font-family:var(--ui);font-size:var(--fs-xs);font-weight:600;color:var(--ink-soft);letter-spacing:.04em;font-variant-numeric:tabular-nums}
.row .ttl{font-family:var(--prose);font-size:var(--fs-lg);font-weight:600;color:var(--ink);line-height:1.25}
.row .ttl small{display:block;font-family:var(--ui);font-weight:400;font-size:var(--fs-2xs);color:var(--ink-soft);margin-top:var(--s-1)}
.row .med-col{font-size:var(--fs-3xs);font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--ochre)}
.row .note{font-size:var(--fs-xs);color:var(--ink-2);line-height:1.45}
.row.is-hidden{display:none}

/* capture, with the signature */
.capture{background:var(--slab);border:0;color:var(--on-dark-2)}
.capture .eyebrow{color:var(--ochre-slab)}
.capture-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.4rem,4vw,3.25rem);align-items:center}
@media (max-width:880px){.capture-grid{grid-template-columns:1fr}}
.capture h2{font-family:var(--prose);font-weight:600;font-size:var(--ds-head);margin:.6rem 0 0;line-height:1.15;color:var(--on-dark)}
.capture p{font-family:var(--prose);font-size:var(--fs-base);line-height:1.65;color:var(--on-dark-2);margin:.9rem 0 0;max-width:42ch}
.sig{width:min(100%,300px);height:64px;margin-top:1.6rem;background-color:var(--ochre-slab);
  -webkit-mask:url(/assets/img/signature.png) left center/contain no-repeat;
          mask:url(/assets/img/signature.png) left center/contain no-repeat}
.sig-ink{background-color:var(--ink)}
.sig-lg{height:96px;width:min(100%,400px);opacity:.95}
form.signup{display:flex;flex-direction:column;gap:.65rem}
.field-row{display:flex;gap:var(--s-2);flex-wrap:wrap}
form.signup input[type=email]{flex:1 1 14rem;min-width:0;font-family:var(--ui);font-size:var(--fs-base);padding:.85rem 1rem;background:var(--dark-field);border:1px solid var(--dark-edge);color:var(--on-dark)}
form.signup input[type=email]::placeholder{color:var(--on-dark-3)}
form.signup input[type=email]:focus-visible{border-color:var(--ochre-slab);outline:2px solid var(--ochre-slab);outline-offset:2px}
form.signup input[type=email]:focus{border-color:var(--ochre-slab)}
form.signup button{font-family:var(--ui);font-size:var(--fs-xs);font-weight:600;letter-spacing:.09em;text-transform:uppercase;padding:.85rem 1.4rem;background:var(--oxide);color:var(--on-oxide);border:1px solid var(--oxide);cursor:pointer}
form.signup button:hover{background:var(--oxide-hi)}
.consent{font-size:var(--fs-2xs);color:var(--on-dark-3);line-height:1.55;margin:.1rem 0 0}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.said{font-family:var(--prose);font-size:var(--fs-base);color:var(--ochre-slab);margin:var(--s-3) 0 0;min-height:1.4em}

/* buy */
.buy{display:flex;flex-direction:column;gap:var(--s-2)}
.buy a{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:var(--s-3) 1rem;text-decoration:none;background:var(--paper-2);border:1px solid var(--rule-soft);font-size:var(--fs-xs);font-weight:600;letter-spacing:.05em;text-transform:uppercase;transition:background .12s ease,border-color .12s ease}
.buy a:hover{background:var(--paper);border-color:var(--ink)}
.buy a span{color:var(--oxide-txt);font-weight:400}
.note-sm{font-size:var(--fs-2xs);color:var(--ink-soft);margin:.85rem 0 0;line-height:1.55}

/* media */
.bw{filter:grayscale(1) contrast(1.05);border:1px solid var(--rule);box-shadow:0 14px 32px -20px var(--shadow-deep)}
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(1.5rem,4vw,3.25rem);align-items:center}
.split-narrow{grid-template-columns:minmax(0,360px) 1fr;align-items:start}
/* The biography runs far longer than the portrait beside it, so the left column
   was ending in mid-air and the two stopped reading as one block. Holding it in
   view keeps the face with the words it belongs to. */
@media (min-width:821px){
  .split-narrow>div:first-child{position:sticky;top:5.5rem}
}
@media (max-width:820px){.split,.split-narrow{grid-template-columns:1fr}}
.creds{list-style:none;margin:1.15rem 0 0;padding:0;border-top:1px solid var(--rule-soft)}
.creds li{display:flex;gap:1rem;align-items:baseline;padding:.65rem 0;border-bottom:1px solid var(--rule-soft);font-size:var(--fs-sm);color:var(--ink-2)}
.creds .k{font-family:var(--display);text-transform:uppercase;font-size:var(--fs-sm);color:var(--ink);flex:0 0 5.75rem;line-height:1.2}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.15rem}
.card{background:var(--paper);border:1px solid var(--rule-soft);padding:1.4rem;display:flex;flex-direction:column;gap:.5rem}
.card h3{font-family:var(--prose);font-weight:600;font-size:var(--fs-lg);margin:0;line-height:1.22}
.card .kind{font-size:var(--fs-3xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ochre)}
.card p{margin:0;font-size:var(--fs-sm);color:var(--ink-soft);line-height:1.58}
.card .foot{margin-top:auto;padding-top:.85rem;border-top:1px solid var(--rule-soft);font-size:var(--fs-2xs);color:var(--ink-2);font-weight:500}
.duo{display:grid;grid-template-columns:1fr 1fr;gap:1.15rem}
@media (max-width:820px){.duo{grid-template-columns:1fr}}
.duo .panel{display:flex;flex-direction:column;gap:var(--s-3)}
.duo h3{font-family:var(--prose);font-weight:600;font-size:var(--fs-xl);margin:var(--s-1) 0 0;line-height:1.2}
.duo p{margin:0;font-family:var(--prose);font-size:var(--fs-base);color:var(--ink-2);line-height:1.62}
.link-arrow{margin-top:auto;padding-top:.9rem;font-size:var(--fs-2xs);font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--oxide-txt);text-decoration:none;display:inline-flex;gap:var(--s-2);align-items:center;font-family:var(--ui)}
.link-arrow:hover{text-decoration:underline;text-underline-offset:4px}

.shelf{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:clamp(1.1rem,2.5vw,2rem);align-items:end}
.shelf figure{margin:0;display:flex;flex-direction:column;gap:.85rem;align-items:flex-start}
/* NOT display:contents. A <picture> holds a <source> as well as the <img>, and
   display:contents promotes both to grid items — the invisible <source> then
   silently occupies a grid cell and shunts the picture into the next column. */
.shelf picture,.cover-stage picture,.split picture,.split-narrow picture{display:block;min-width:0}
.split>picture,.split-narrow>picture{align-self:center}
.cover-stage>picture{display:flex;justify-content:center;width:100%}
/* one height for every jacket so they stand on a common baseline; widths follow each book's real
   proportions and nothing is cropped. */
.shelf img{height:clamp(178px,20vw,272px);width:auto;max-width:100%;object-fit:contain;
  border:1px solid var(--rule);box-shadow:0 14px 28px -14px var(--shadow-deep)}
.nocover{aspect-ratio:2/3;border:1px dashed var(--rule);background:repeating-linear-gradient(45deg,transparent 0 7px,color-mix(in srgb,var(--rule) 22%,transparent) 7px 8px);display:grid;place-items:center;text-align:center}
.nocover span{font-family:var(--ui);font-size:var(--fs-3xs);font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft);line-height:1.5}
.shelf figcaption{font-size:var(--fs-2xs);line-height:1.4;color:var(--ink-soft)}
.shelf figure{padding-top:var(--s-1)}
.shelf figcaption b{display:block;font-family:var(--prose);font-size:var(--fs-base);font-weight:600;color:var(--ink);margin-bottom:.15rem}

.pull-big{font-family:var(--prose);font-size:var(--ds-quote);line-height:1.34;color:var(--ink);margin:0;max-width:24ch;text-wrap:balance}
.pull-big cite{display:block;margin-top:1rem;font-family:var(--ui);font-style:normal;font-size:var(--fs-3xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}

/* embeds */
.embed{border:1px solid var(--rule-soft);background:var(--paper-2);padding:.4rem;box-shadow:0 10px 26px -18px var(--shadow)}
.embed iframe{display:block;width:100%;border:0;border-radius:10px}
.embed-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:1.1rem}
.rec{display:flex;flex-direction:column;gap:.6rem;min-width:0}
.rec h3{margin:0;font-family:var(--prose);font-size:var(--fs-md);font-weight:600;color:var(--ink)}
.rec h3 span{display:block;font-family:var(--ui);font-size:var(--fs-3xs);font-weight:500;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-soft);margin-top:var(--s-1)}

/* contact */
.cform{display:grid;gap:var(--s-3);max-width:34rem}
.cform label{font-size:var(--fs-3xs);font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft)}
.cform input,.cform textarea{font-family:var(--ui);font-size:var(--fs-base);padding:.75rem .9rem;background:var(--paper);border:1px solid var(--rule);color:var(--ink);width:100%}
.cform textarea{min-height:8rem;resize:vertical}
.cform input:focus-visible,.cform textarea:focus-visible{border-color:var(--oxide);outline:2px solid var(--oxide);outline-offset:2px}
.cform input:focus,.cform textarea:focus{border-color:var(--oxide)}

/* footer */
footer.site{background:var(--concrete-2);border-top:1px solid var(--rule);padding-block:clamp(2.25rem,5vw,3.25rem);margin-top:clamp(2rem,5vw,3rem)}
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:1.75rem}
@media (max-width:820px){.foot-grid{grid-template-columns:1fr 1fr;gap:1.5rem}}
@media (max-width:520px){.foot-grid{grid-template-columns:1fr}}
.foot-grid h3{font-size:var(--fs-3xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);margin:0 0 var(--s-3)}
.foot-links{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-2)}
/* A list of links is not "inline in a sentence", so WCAG 2.2 SC 2.5.8's
   exemption does not cover it: each one needs 24px of its own, at every width
   rather than only under the phone breakpoint. */
.foot-links a{display:inline-flex;align-items:center;min-height:24px;
  font-size:var(--fs-sm);text-decoration:none;color:var(--ink-2)}
.foot-links a:hover{color:var(--oxide-txt);text-decoration:underline;text-underline-offset:3px}
.colophon{font-size:var(--fs-2xs);color:var(--ink-soft);line-height:1.6;margin:2.25rem 0 0;padding-top:1.15rem;border-top:1px solid var(--rule)}

/* direct-answer block and FAQ */
.answer{background:var(--concrete-3);border-bottom:1px solid var(--rule)}
.answer p{margin:0;padding-block:clamp(1.5rem,3vw,2.1rem);font-family:var(--prose);font-size:var(--fs-md);line-height:1.68;color:var(--ink-2);max-width:78ch}
.answer b{color:var(--ink);font-weight:600}
.faq{display:grid;gap:0;border-top:1px solid var(--rule)}
.fq{padding:1.1rem 0;border-bottom:1px solid var(--rule-soft)}
.fq h3{margin:0 0 .35rem;font-family:var(--prose);font-size:var(--fs-md);font-weight:600;color:var(--ink);line-height:1.3}
.fq p{margin:0;font-family:var(--prose);font-size:var(--fs-base);line-height:1.62;color:var(--ink-2);max-width:72ch}

/* WCAG 2.2 target size: give every tap target at least 24px of height, and more on
   touch screens. This readership is 50-70 and largely on phones. */
nav.main a{padding:var(--s-2) 0 .5rem;display:inline-flex;align-items:center;min-height:26px}
.foot-links a{display:inline-flex;align-items:center;min-height:26px;padding-block:.15rem}
.buy a{min-height:44px}
.filters button{min-height:34px}
.link-arrow{min-height:26px}
@media (hover:none) and (pointer:coarse){
  nav.main{gap:1.1rem .95rem}
  nav.main a{min-height:34px;padding:.6rem 0}
  .foot-links{gap:.15rem}
  .foot-links a{min-height:38px}
  .link-arrow{min-height:38px}
}

/* ---- phones ---- */
@media (max-width:880px){
  /* the jacket was filling the screen and running off the bottom */
  .cover-stage{padding-top:.5rem}
  /* A definite width, never `width:auto`. The cover is a flex item inside the
     <picture>, and a LAZY image has no natural size until it loads; with auto
     on both axes the box resolves to 0x0, which then means it never intersects
     the viewport, so it never loads, so it never gets a size. The base rule set
     an explicit width, which is the only reason this never showed until a page
     put a cover below the fold. */
  /* Capped by width alone. A height cap alongside a definite width describes a
     box that is not the jacket's shape, and the difference shows as dead space
     around the art. 240px wide is about 365 tall for these covers, which fits a
     phone; the height cap was for the 360px hero, which no longer applies here. */
  .cover-stage img{width:min(100%,240px);height:auto}
  .plate .hero-grid{padding-block:1.75rem 2.25rem}
}
@media (max-width:640px){
  /* the epigraph was taking two lines and a whole band before anything else */
  .epigraph p{font-size:var(--fs-2xs);padding-block:var(--s-2);line-height:1.35}
  .bar{padding-block:.65rem}
  .mark{font-size:var(--fs-base)}
  nav.main{gap:.85rem}
  nav.main a{font-size:var(--fs-3xs);letter-spacing:.08em}
  .hook{font-size:var(--fs-base);padding-left:.9rem}
  .pubmeta{font-size:var(--fs-3xs);margin-top:1.15rem;padding-top:.85rem}
  .cta-row{gap:.5rem;margin-top:1.35rem}
  .btn{padding:var(--s-3) 1.05rem;font-size:var(--fs-2xs)}
  .quotes{padding-block:1.5rem}
  .sec,.sec-tight{padding-block:2.25rem}
  .sec-tight{padding-top:0}
}
@media (max-width:420px){
  .cover-stage img{width:min(100%,200px);height:auto}
}

/* Interior banners crop his own frame differently so the pages do not repeat
   the same picture, and no image on this site belongs to anyone else. */
.banner img.bnr-work{object-position:78% 62%}
.banner img.bnr-about{object-position:26% 48%}
.banner img.bnr-contact{object-position:52% 70%}

/* The publisher's own mark, as drawn. Big enough that the words read, which is
   the whole point of putting a logo on a page. */
.enp-logo{width:88px;height:auto;margin:.5rem 0 var(--s-1)}

/* The music section carries an embed only once the playlist exists. Without it,
   the prose should not sit in a half-empty two-column grid. */
.wrap-prose{display:block}
.wrap-prose .prose{max-width:70ch}
