/* =========================================================================
   celestecurrie.com
   Light by default, dark by preference. Bronze is the only accent.
   No gradients as decoration, no card shadows, no scroll animation.
   ========================================================================= */

/* ------------------------------------------------------------------ fonts */

/* Roboto is a variable file here, so one download covers every weight the
   stylesheet asks for. */
@font-face {
  font-family: "Roboto";
  src: url("/assets/fonts/roboto-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Roboto";
  src: url("/assets/fonts/roboto-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
/* Two static cuts of Oswald, not a variable file. The ranges matter: with
   only the 600 loaded across 100-900, every font-weight: 700 in this
   stylesheet silently rendered at 600 and "bolder" did nothing at all. */
@font-face {
  font-family: "Oswald";
  src: url("/assets/fonts/oswald.woff2") format("woff2");
  font-weight: 100 650;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Oswald";
  src: url("/assets/fonts/oswald-700.woff2") format("woff2");
  font-weight: 651 900;
  font-style: normal;
  font-display: swap;
}

/* ----------------------------------------------------------------- tokens */

:root {
  /* Black, white and bronze. The page is a neutral grey so the white cards
     on it read as cards, the way the reference site's do. */
  --bg: #f0f0f0;
  --surface: #ffffff;
  --ink: #121212;
  --muted: #5a5a5a;
  --rule: #d8d8d8;
  --accent: #9c6b30;        /* the brand bronze - rules, seals, marks */
  --accent-text: #8a5a24;   /* darkened so link text clears 4.5:1 on --bg */
  --accent-soft: rgba(156, 107, 48, 0.1);
  --panel: #111111;          /* solid black block behind sidebar content */
  --panel-ink: #ffffff;
  --panel-muted: #b0b0b0;
  --panel-rule: #3a3a3a;
  --accent-lift: #c98f45;    /* bronze that carries on a black panel */

  --body: "Roboto", "Helvetica Neue", Arial, sans-serif;
  --display: "Oswald", "Helvetica Neue", Arial, sans-serif;

  --measure: 68ch;
  --gutter: 1.25rem;
  --sidebar: 17.5rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d0d0d;
    --surface: #171717;
    --ink: #f2f2f2;
    --muted: #9a9a9a;
    --rule: #2a2a2a;
    --accent: #9c6b30;
    --accent-text: #c98f45; /* lifted so link text clears 4.5:1 on black */
    --accent-soft: rgba(156, 107, 48, 0.16);
    --panel: #000000;
    --panel-ink: #ffffff;
    --panel-muted: #9a9a9a;
    --panel-rule: #333333;
    --accent-lift: #c98f45;
  }
}

/* ------------------------------------------------------------------ reset */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-synthesis-weight: none;
}

@media (min-width: 40em) {
  body { font-size: 1.125rem; }
}

img { max-width: 100%; height: auto; }

a { color: var(--accent-text); text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

h1, h2, h3, .kicker, .button, button {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.005em;
}

h1 { font-size: clamp(1.9rem, 1.4rem + 2.2vw, 2.75rem); margin: 0 0 0.4em; }
h2 { font-size: clamp(1.35rem, 1.15rem + 1vw, 1.7rem); margin: 2rem 0 0.5em; }
h3 { font-size: 1.2rem; margin: 1.75rem 0 0.4em; }

.muted { color: var(--muted); }

.kicker {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0 0 0.6rem;
}

.skip,
.visually-hidden {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.5rem;
  z-index: 10;
  background: var(--bg);
  padding: 0.5rem 0.75rem;
  border: 2px solid var(--accent);
}

/* --------------------------------------------------------------- masthead */

/* A black bar with a bronze rule under it. The nav was previously the same
   colour as the page, which is why it disappeared into it. */
.masthead {
  background: #111111;
  border-bottom: 4px solid var(--accent);
}

.masthead-inner {
  max-width: 68rem;
  margin: 0 auto;
  padding: 1rem var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.35rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #ffffff;
  text-decoration: none;
}
.wordmark img { width: 2.4rem; height: 2.4rem; }

.masthead nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
  margin: 0;
  padding: 0;
}

.masthead nav a {
  display: inline-block;
  color: #ffffff;
  text-decoration: none;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.92rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.35rem 0;
  border-bottom: 3px solid transparent;
}
.masthead nav a:hover { border-bottom-color: var(--accent); }
.masthead nav a[aria-current="page"] {
  border-bottom-color: var(--accent);
  color: var(--accent-lift);
}

.banner {
  height: 92px;
  background-image: url("/assets/img/banner.webp");
  background-size: cover;
  background-position: center;
  background-color: #111111;
}
@media (min-width: 48em) {
  .banner { height: 150px; }
}

/* ----------------------------------------------------------------- shell */

.shell {
  max-width: 68rem;
  margin: 0 auto;
  padding: 2rem var(--gutter) 3rem;
  display: grid;
  gap: 3rem;
}

/* Mobile reads content first; the sidebar follows it. */
.column { order: 1; min-width: 0; }
.sidebar { order: 2; }

@media (min-width: 60em) {
  .shell {
    grid-template-columns: var(--sidebar) minmax(0, 1fr);
    gap: 3.5rem;
    align-items: start;
  }
  .sidebar { order: 0; position: sticky; top: 1.5rem; }
  .column { order: 0; }
}

.page-head { margin-bottom: 2.5rem; }
.standfirst {
  color: var(--muted);
  font-size: 1.05em;
  max-width: var(--measure);
  margin: 0 0 1rem;
}

/* ----------------------------------------------------------------- prose */

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.15em; }
.prose p, .prose li { max-width: var(--measure); }
.prose blockquote {
  margin: 1.75em 0;
  padding-left: 1.1rem;
  border-left: 3px solid var(--accent);
  color: var(--muted);
  font-style: italic;
}
.prose hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.5em 0;
}
.prose code {
  font-size: 0.9em;
  background: var(--accent-soft);
  padding: 0.1em 0.35em;
}
.prose ul, .prose ol { padding-left: 1.3rem; }

/* Tables, for the lawful-basis grid on the privacy policy. */
.prose table {
  width: 100%;
  max-width: var(--measure);
  border-collapse: collapse;
  font-size: 0.95rem;
  margin: 1.5em 0;
}
.prose th,
.prose td {
  text-align: left;
  vertical-align: top;
  padding: 0.7rem 0.9rem 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.prose th {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.85rem;
  border-bottom: 2px solid var(--accent);
}
.prose td:last-child, .prose th:last-child { padding-right: 0; }
/* Two columns of prose do not fit a phone, so the table becomes rows. */
@media (max-width: 34em) {
  .prose thead { position: absolute; left: -9999px; }
  .prose tr { display: block; padding: 0.8rem 0; border-bottom: 1px solid var(--rule); }
  .prose td { display: block; border: 0; padding: 0; }
  .prose td:first-child { font-weight: 700; }
  .prose td:last-child { color: var(--muted); }
}

/* Masked to its ring, so it sits on the page as a disc rather than a black
   square. On a wide enough column the text wraps around the circle itself,
   not its bounding box. */
.about-portrait {
  display: block;
  width: 100%;
  max-width: 16rem;
  height: auto;
  margin: 0 auto 1.5rem;
}
@media (min-width: 46em) {
  .about-portrait {
    float: right;
    width: 15rem;
    max-width: 42%;
    margin: 0 0 1.25rem 2rem;
    shape-outside: circle(50%);
    shape-margin: 0.9rem;
  }
  /* Headings start a new section, so they should not sit beside it. */
  .prose h2 { clear: both; }
}

/* The line the rest of the page is arguing for. */
/* Her lists on the about page: bronze markers rather than browser bullets,
   the same square the opt-in uses, so the two read as one family. */
.prose .marked {
  list-style: none;
  padding-left: 0;
  margin-left: 0;
}
.prose .marked li {
  position: relative;
  padding-left: 1.3rem;
  margin-bottom: 0.5rem;
}
.prose .marked li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.45rem;
  height: 0.45rem;
  background: var(--accent);
}
/* The four pillars are one word each, so they set as a row where there is
   room and stack where there is not. */
.prose .marked--pillars {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.75rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.prose .marked--pillars li { margin-bottom: 0; }

.signoff {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: 0.04em;
  color: var(--accent-text);
  margin-top: 2rem !important;
}

.creed {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.2rem, 1.05rem + 0.8vw, 1.55rem);
  line-height: 1.3;
  color: var(--accent-text);
  border-top: 3px solid var(--accent);
  padding-top: 1.1rem;
  margin-top: 2rem !important;
}

/* -------------------------------------------------------- pieces & lists */

.piece-head { margin-bottom: 2rem; }
/* An untitled note's date stands in for its title - sized down, since it is
   a timestamp rather than a headline. */
.date-title { font-size: clamp(1.5rem, 1.2rem + 1.2vw, 1.9rem); }
/* A letter's standfirst, when it has one. Sits between headline and byline. */
.piece-sub {
  font-size: 1.15rem;
  line-height: 1.4;
  color: var(--muted);
  margin: 0 0 0.6rem;
}
.byline {
  color: var(--muted);
  font-size: 0.95rem;
  margin: 0;
}

.piece-nav {
  margin: 3rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.latest {
  border-top: 3px solid var(--accent);
  padding-top: 1.5rem;
  margin-bottom: 3rem;
}
.latest h2 { margin-top: 0.3rem; }
.latest h2 a { color: var(--ink); text-decoration: none; }
.latest h2 a:hover { color: var(--accent-text); text-decoration: underline; }

.button {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  padding: 0.7rem 1.4rem;
  text-decoration: none;
  font-size: 1rem;
  border: 2px solid var(--accent);
}
.button:hover { background: transparent; color: var(--accent-text); }

.two-up {
  display: grid;
  gap: 2rem;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}
@media (min-width: 40em) {
  .two-up { grid-template-columns: 1fr 1fr; gap: 2.5rem; }
}
.two-up h2 { margin-top: 0; }

.post {
  border: 1px solid var(--rule);
  background: var(--surface);
  padding: 2rem 1.5rem 0;
  margin-bottom: 2.5rem;
}
@media (min-width: 48em) {
  .post { padding: 2.5rem 2.25rem 0; }
}
.post-title {
  margin: 0 0 0.6rem;
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.15rem);
  text-transform: uppercase;
}
.post-title a { color: var(--ink); text-decoration: none; }
.post-title a:hover { color: var(--accent-text); }
.post-sub {
  margin: 0 0 0.4rem;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.4;
}
.post-byline {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}
.post-rule {
  border: 0;
  border-top: 1px dashed var(--rule);
  margin: 1.25rem 0 1.5rem;
}
/* The full-width bar that closes each post, as on the reference site. */
.read-post {
  display: block;
  margin: 2rem -1.5rem 0;
  padding: 1rem 1.5rem;
  background: var(--accent);
  color: #fff;
  font-family: var(--display);
  font-size: 1rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
}
.read-post:hover { background: var(--ink); }
@media (min-width: 48em) {
  .read-post { margin: 2.5rem -2.25rem 0; padding: 1.1rem 2.25rem; }
}

/* ---- the 3C diagram, in "It's arse backwards" ---- */

/* Rebuilt as live text rather than a picture, so it carries the site's own
   black, white and bronze, reads at any width and is searchable. The three
   panels run cool to warm the way the sequence does: chaos plain, clarity
   tinted, creation solid bronze. */
.three-c { margin: 2.5rem 0; padding: 0; }
.three-c figcaption {
  margin-bottom: 1.4rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 0.95rem + 1vw, 1.55rem);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  color: var(--ink);
}
.three-c-row {
  display: grid;
  gap: 1.6rem;
}
.three-c-stage {
  position: relative;
  /* A touch darker than --rule, so the plain panel holds its own weight
     beside the two bronze ones. */
  border: 2px solid #bfbfbf;
  background: var(--surface);
  padding: 1.15rem 1rem 1.3rem;
  text-align: center;
}
.prose .three-c-stage h3 {
  margin: 0 0 0.65rem;
  font-size: 1.25rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.prose .three-c-stage ul {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--muted);
}
.prose .three-c-stage li { max-width: none; }

.three-c-stage--clarity {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.three-c-stage--clarity h3 { color: var(--accent-text); }
.prose .three-c-stage--clarity ul { color: var(--ink); }

.three-c-stage--creation {
  border-color: var(--accent);
  background: var(--accent);
}
.three-c-stage--creation h3 { color: #fff; }
.prose .three-c-stage--creation ul { color: #fff; }

/* The arrows are decoration - the order of the panels already says it - so
   they are drawn rather than written, and screen readers never meet them.
   Stacked, they point down into the gap; side by side, they point right. */
.three-c-stage:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% + 0.45rem);
  transform: translateX(-50%);
  border-style: solid;
  border-width: 0.5rem 0.5rem 0 0.5rem;
  border-color: var(--accent) transparent transparent transparent;
}
@media (min-width: 46em) {
  .three-c-row { grid-template-columns: repeat(3, 1fr); gap: 2.4rem; }
  .three-c-stage:not(:last-child)::after {
    left: calc(100% + 0.75rem);
    top: 50%;
    transform: translateY(-50%);
    border-width: 0.5rem 0 0.5rem 0.5rem;
    border-color: transparent transparent transparent var(--accent);
  }
}

/* ---- the notes box: short notes, scrolling inside a fixed panel ---- */

.notes-box {
  border: 1px solid var(--rule);
  background: var(--surface);
  margin-bottom: 2.5rem;
}
.notes-box-title {
  margin: 0;
  padding: 0.85rem 1.5rem;
  font-size: 1.2rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-bottom: 1px dashed var(--rule);
}
.notes-scroll {
  max-height: 21rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 1.5rem;
  /* Reserve the track's width either way, so nothing shifts on scroll. */
  scrollbar-gutter: stable;
  /* Firefox */
  scrollbar-color: var(--accent) var(--surface);
  scrollbar-width: thin;
}
/* Chromium and Safari ignore ::-webkit-scrollbar the moment the two standard
   properties above are set to anything but auto, and their own default is an
   overlay bar that only shows while you scroll. Hand those two browsers back
   to the ::-webkit-scrollbar rules below, so the bronze track is there all
   the time and the box reads as scrollable at a glance. Firefox does not
   know this selector, so it keeps the standard properties. */
@supports selector(::-webkit-scrollbar) {
  .notes-scroll { scrollbar-color: auto; scrollbar-width: auto; }
}
.notes-scroll:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: -2px;
}
.notes-scroll::-webkit-scrollbar { width: 10px; }
.notes-scroll::-webkit-scrollbar-track { background: var(--surface); }
.notes-scroll::-webkit-scrollbar-thumb {
  background: var(--accent);
  border: 3px solid var(--surface);
}
@media (min-width: 48em) {
  .notes-box-title { padding: 1rem 2.25rem; }
  .notes-scroll { max-height: 25rem; padding: 0 2.25rem; }
}

/* Each note as its own short-form post: mark, name, time, then the note. */
.note-item {
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--rule);
}
.note-item:last-child { border-bottom: 0; }

.note-head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.35rem;
}
.note-author {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-text);
}
/* The note itself sets a little larger than body copy, the way a short
   post does, and never runs to a full prose measure inside the box. */
.note-item .prose { max-width: 54ch; }
.note-item .prose p { font-size: 1rem; line-height: 1.5; margin: 0 0 0.6rem; }
.note-item .prose p:last-child { margin-bottom: 0; }
.note-heading {
  margin: 0 0 0.5rem;
  font-size: 1.15rem;
  text-transform: uppercase;
}
.note-heading a { color: var(--ink); text-decoration: none; }
.note-heading a:hover { color: var(--accent-text); }

/* The bar spans the notes box exactly. The negative margins on .read-post
   exist to cancel the padding inside .post, which this box does not have. */
.notes-box .read-post { margin: 0; }

.archive-links {
  display: flex;
  gap: 1.5rem;
  padding-top: 1rem;
  font-size: 0.95rem;
}

/* Testimonials page. */
.testimonial-list { max-width: var(--measure); }
.testimonial {
  margin: 0 0 2.5rem;
  padding: 1.5rem 0 0;
  border-top: 3px solid var(--accent);
  font-style: italic;
}
.testimonial p { margin: 0 0 0.9rem; }
.testimonial cite {
  font-style: normal;
  font-size: 0.9rem;
  color: var(--muted);
}
.testimonial cite span { display: block; }

/* Screenshots, shown at their own proportions on a white card. Each one
   carries its transcription as alt text, because an image of text is
   invisible to a screen reader and to search without it. */
.receipts { margin-top: 3.5rem; }
.receipts h2 { margin-top: 0; }
.receipt-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}
@media (min-width: 46em) {
  .receipt-grid { grid-template-columns: 1fr 1fr; }
}
.receipt {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 0.75rem;
}
.receipt img {
  display: block;
  width: 100%;
  height: auto;
}
.receipt figcaption {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.contact-email {
  font-family: var(--display);
  font-size: clamp(1.2rem, 1rem + 1vw, 1.6rem);
  letter-spacing: 0.02em;
}

.stream-item {
  padding: 2rem 0;
  border-bottom: 1px solid var(--rule);
}
.stream-item:first-child { padding-top: 0; }
.stream-date {
  margin: 0 0 0.75rem;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.stream-date a { color: var(--muted); text-decoration: none; }
.stream-date a:hover { color: var(--accent-text); text-decoration: underline; }
.stream-item h2 { margin-top: 0; }
.stream-link { font-size: 0.9rem; margin-bottom: 0; }

.listing { list-style: none; margin: 0; padding: 0; }
.listing li {
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--rule);
}
.listing li:first-child { padding-top: 0; }
.listing h2 { margin: 0.2rem 0 0.5rem; }
.listing h2 a { color: var(--ink); text-decoration: none; }
.listing h2 a:hover { color: var(--accent-text); text-decoration: underline; }
.listing-date {
  margin: 0;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --------------------------------------------------------------- sidebar */

.card { margin-bottom: 2.5rem; }
.card h2 {
  font-size: 1.05rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 0.8rem;
  font-weight: 600;
}
.card p { font-size: 0.95rem; }

/* The sidebar blocks are solid panels with centred display headings,
   rather than outlined cards. */
.card--bio {
  background: var(--panel);
  color: var(--panel-ink);
  border: 2px solid var(--accent);
  padding: 1.75rem 1.35rem;
  text-align: center;
}
.card--bio h2 {
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-lift);
  margin-bottom: 0.7rem;
}
.card--bio p { color: var(--panel-ink); }
.card--bio a { color: var(--accent-lift); }
/* Full bleed to the card edge, at the photograph's own proportions. A
   circular crop would cut the kick off, and the kick is the picture. Its
   black background runs straight into the panel, so there is no seam and
   no border is wanted. */
.portrait {
  display: block;
  width: calc(100% + 2.7rem);
  /* The global img rule caps width at 100%, which would leave the negative
     margin pulling the picture off-centre instead of widening it. */
  max-width: none;
  height: auto;
  margin: -1.75rem -1.35rem 1.25rem;
}

/* "What others are saying" - heading outside, quote on its own card. */
.card--testimonial h2 {
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  color: var(--ink);
  text-align: center;
  margin-bottom: 1rem;
}
.card--testimonial blockquote {
  position: relative;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 2.75rem 1.35rem 1.35rem;
  text-align: center;
}
.card--testimonial blockquote::before {
  content: "\201C";
  position: absolute;
  top: 0.25rem;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--display);
  font-size: 4rem;
  line-height: 1;
  color: var(--accent);
}
.card--testimonial p {
  font-style: italic;
  margin: 0 0 0.9rem;
}
.card--testimonial cite {
  font-style: normal;
  font-size: 0.85rem;
  color: var(--muted);
}
.card--testimonial cite span { display: block; }

/* ---------------------------------------------------------------- search */

/* Pagefind ships its own look - square it off and put it on our palette. */
#search {
  --pagefind-ui-scale: 0.8;
  --pagefind-ui-primary: var(--accent-text);
  --pagefind-ui-text: var(--ink);
  --pagefind-ui-background: var(--bg);
  --pagefind-ui-border: var(--rule);
  --pagefind-ui-tag: var(--surface);
  --pagefind-ui-border-width: 1px;
  --pagefind-ui-border-radius: 0;
  --pagefind-ui-font: var(--body);
}
#search .pagefind-ui__search-input {
  background: var(--surface);
  color: var(--ink);
  font-size: 1rem;
  border: 3px solid var(--panel) !important;
  /* Pagefind puts its magnifier inside the field, so the left inset has to
     stay clear of it or the placeholder runs underneath. */
  padding: 0.7rem 0.8rem 0.7rem 2.6rem !important;
}
#search .pagefind-ui__search-input::placeholder { color: var(--muted); }
#search .pagefind-ui__result { border-top: 1px solid var(--rule); }

/* ---------------------------------------------------------------- opt-in */

.optin {
  border: 2px solid var(--accent);
  padding: 1.5rem 1.25rem;
  background: var(--surface);
}
.optin-heading {
  font-size: 1.3rem;
  margin: 0 0 0.5rem;
}
.optin-body {
  font-size: 0.95rem;
  margin: 0 0 1.25rem;
  color: var(--muted);
}

/* The books, shown above what they get. One photograph of the pair, so the
   lighting, the shared surface and the space between them are the
   photographer's rather than something the stylesheet has to fake. */
.optin-books {
  display: flex;
  justify-content: center;
  margin: 0 0 1.35rem;
}
.optin-books img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 9rem;
}
.optin--squeeze .optin-books img { max-height: 12rem; }

/* What they get. Bronze markers, no box - the warning below is the only
   thing in this form allowed to shout. */
.optin-includes {
  list-style: none;
  margin: 0 0 1.35rem;
  padding: 0;
  font-size: 0.95rem;
}
.optin-includes li {
  position: relative;
  padding-left: 1.15rem;
  margin-bottom: 0.4rem;
  line-height: 1.5;
}
.optin-includes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.45rem;
  height: 0.45rem;
  background: var(--accent);
}

.field { margin-bottom: 1rem; }
.field label {
  display: block;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.3rem;
}
.field input[type="text"],
.field input[type="email"] {
  width: 100%;
  font-family: var(--body);
  font-size: 1rem;
  padding: 0.65rem 0.7rem;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule);
}
.field input:focus-visible { border-color: var(--accent); }

.field--check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: start;
  margin: 1.25rem 0;
}
.field--check input {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.3rem;
  accent-color: var(--accent);
}
.field--check label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.92rem;
  color: var(--ink);
  margin: 0;
}

/* The double opt-in warning. Deliberately the loudest thing in the form -
   unconfirmed subscribers are the biggest leak in any list. */
.optin-warning {
  border-left: 4px solid var(--accent);
  background: var(--accent-soft);
  padding: 0.85rem 1rem;
  margin: 1.25rem 0;
  font-size: 0.92rem;
  line-height: 1.55;
}
.optin-warning strong { display: block; margin-bottom: 0.2rem; }

.optin button {
  width: 100%;
  background: var(--accent);
  color: #fff;
  border: 2px solid var(--accent);
  padding: 0.85rem 1.2rem;
  font-size: 1.05rem;
  cursor: pointer;
}
.optin button:hover { background: transparent; color: var(--accent-text); }
.optin button[disabled] { opacity: 0.6; cursor: progress; }

.optin-privacy {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0.9rem 0 0;
  text-align: center;
}

.optin-status:empty { display: none; }
.optin-status {
  margin: 1rem 0 0;
  padding: 0.8rem 0.9rem;
  font-size: 0.92rem;
  border-left: 4px solid var(--accent);
  background: var(--accent-soft);
}
.optin-status[data-state="error"] { border-left-color: #b3261e; }

/* ---- the sidebar opt-in, as a solid panel with a loud heading ---- */

.optin--sidebar {
  background: var(--panel);
  color: var(--panel-ink);
  border-color: var(--accent);
  padding: 1.75rem 1.35rem;
}
.optin--sidebar .optin-heading {
  font-size: 1.55rem;
  line-height: 1.1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-lift);
  text-align: center;
  margin-bottom: 0.8rem;
}
.optin--sidebar .optin-body,
.optin--sidebar .optin-privacy { color: var(--panel-muted); }
.optin--sidebar .optin-includes li { color: var(--panel-ink); }
.optin--sidebar .field label {
  color: var(--panel-muted);
}
.optin--sidebar .field input[type="text"],
.optin--sidebar .field input[type="email"] {
  background: rgba(0, 0, 0, 0.45);
  color: var(--panel-ink);
  border-color: var(--panel-rule);
}
/* Consent gets its own dashed frame inside the panel, as on the reference. */
.optin--sidebar .field--check {
  border: 2px dashed var(--accent);
  padding: 0.9rem 1rem;
  margin: 1.25rem 0;
}
.optin--sidebar .field--check label { color: var(--panel-ink); }
.optin--sidebar .optin-warning {
  background: rgba(156, 107, 48, 0.28);
  color: var(--panel-ink);
}
.optin--sidebar button:hover { color: var(--accent-lift); }
.optin--sidebar .optin-privacy a { color: var(--accent-lift); }
.optin--sidebar .optin-status { color: var(--panel-ink); }

/* The sidebar panel supplies its own frame, so the wrapper adds none. */
.card--optin { border: 0; padding: 0; }

/* Honeypot - off-screen rather than display:none, which some bots skip. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.foot-optin {
  margin-top: 3.5rem;
  max-width: var(--measure);
}

/* ---------------------------------------------------------- squeeze page */

.squeeze-body {
  /* The squeeze is dark in both themes - it sits on the illustration. */
  --ink: #f3ece0;
  --muted: #cbbfa9;
  --bg: #12100d;
  --surface: rgba(18, 16, 13, 0.82);
  --rule: #4a4034;
  --accent-text: #d79a4e;
  --accent-soft: rgba(156, 107, 48, 0.22);
  background: #12100d;
  color: var(--ink);
}

.squeeze {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: 2.5rem var(--gutter) 2rem;
  /* The artwork is painted on .squeeze-scrim below, not here. This page runs
     to two or three screens, and a background on the element is sized to the
     element rather than the window - cover then blows the illustration up
     until a fraction of its width is on screen. Only the colour stays, as
     what shows if the image never arrives. */
  background-color: #12100d;
}

/* Backdrop and legibility layer in one, pinned to the window so the whole
   illustration is in frame however far the page scrolls. position: fixed
   rather than background-attachment: fixed, which iOS has never handled
   properly. The scrim is not decoration: the artwork is busy and bright in
   places and every word above it has to survive any crop.

   Three cuts of the same scene, one per shape of screen. Each sets its own
   image and its own scrim, so the branches never have to undo each other. */
.squeeze-scrim {
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(rgba(10, 9, 7, 0.78), rgba(10, 9, 7, 0.78)),
    url("/assets/img/squeeze-bg-1100.jpg");
  background-size: cover;
  /* The figure sits right of centre; anchoring right keeps her in frame
     when a narrow screen crops the sides off. */
  background-position: 64% center;
}

@media (min-width: 60em) {
  .squeeze-scrim {
    /* A flat scrim strong enough for the left column would flatten the whole
       illustration, so the darkening is weighted to the side the text sits
       on and lifts off the artwork towards the right. */
    background-image:
      linear-gradient(
        to right,
        rgba(10, 9, 7, 0.92) 0%,
        rgba(10, 9, 7, 0.88) 38%,
        rgba(10, 9, 7, 0.6) 62%,
        rgba(10, 9, 7, 0.5) 100%
      ),
      url("/assets/img/squeeze-bg.webp");
    /* Puts the dark of the room under the left column and leaves the comic
       board, the medallion and the seal out on the right. */
    background-position: 46% center;
  }
}

/* Held upright, the wide cut crops down to a slice of the room and the comic
   board goes missing. This is the same scene painted portrait, so the whole
   of it survives on a phone. Last in the file so it also wins on a monitor
   turned on its side, where the width query above would otherwise put the
   wide cut back. */
@media (max-aspect-ratio: 4 / 5) {
  .squeeze-scrim {
    /* Flat again: the gradient above is weighted for a wide frame with the
       text in a left column, which a portrait layout does not have. */
    background-image:
      linear-gradient(rgba(10, 9, 7, 0.78), rgba(10, 9, 7, 0.78)),
      url("/assets/img/squeeze-bg-portrait.webp");
    background-position: center;
  }
}

/* A second way out, pinned to the top corner, because the form is long
   enough on a phone to push the one below it off the first screen. */
.escape-top {
  position: absolute;
  top: 0.75rem;
  right: var(--gutter);
  z-index: 2;
  font-size: 0.9rem;
  color: var(--ink);
  background: rgba(10, 9, 7, 0.7);
  padding: 0.45rem 0.8rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.escape-top:hover { background: rgba(10, 9, 7, 0.9); }

.squeeze-inner {
  position: relative;
  width: 100%;
  max-width: 34rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.8);
}

@media (min-width: 62em) {
  .squeeze {
    justify-content: flex-start;
    padding-top: 4rem;
  }
  .squeeze-inner {
    max-width: 66rem;
    margin-left: 2rem;
    display: grid;
    grid-template-columns: minmax(0, 33rem) minmax(0, 26rem);
    gap: 3rem;
    align-items: start;
  }
  /* Keeps the right column off the far right, where the figure stands. */
  .squeeze-aside {
    margin-top: 7rem;
    padding: 3.5rem 3rem;
  }
}

/* On a phone the escape block follows the form; the corner link covers the
   first screen. On desktop the block is in view from the start, so the
   corner link would only be a second copy of it. */
@media (min-width: 62em) {
  .escape-top { display: none; }
}

/* The seal has a wolf, four pillars and two rings of text in it. Below
   about 7rem none of that reads, so it gets the room to be seen. */
.seal {
  width: clamp(7rem, 5rem + 9vw, 10.5rem);
  height: auto;
  margin-bottom: 1.5rem;
}

/* ---- the lockup: CELESTE over Project Tempest over the Society ---- */

.lockup {
  margin: 0 0 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Tracking eases in with the viewport. At full width it is as wide as the
   design wants; on a 320px phone that much tracking pushes the longest line
   - the Society - into the side gutter, so it tightens rather than wraps. */
.lockup-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.4rem, 1.5rem + 5vw, 4.25rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: clamp(0.1em, 0.04em + 0.45vw, 0.16em);
  color: var(--accent);
}

.lockup-project {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1rem, 0.88rem + 0.7vw, 1.4rem);
  letter-spacing: clamp(0.13em, 0.07em + 0.45vw, 0.2em);
  text-transform: uppercase;
  color: #f3ece0;
}

.lockup-society {
  font-family: var(--body);
  font-size: clamp(0.74rem, 0.68rem + 0.3vw, 0.95rem);
  letter-spacing: clamp(0.09em, 0.04em + 0.35vw, 0.16em);
  text-transform: uppercase;
  color: var(--muted);
}

/* The credential line. Does the qualifying the headline used to carry in
   its opening clause, which frees the headline to be nothing but promise. */
.credentials {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(0.85rem, 0.78rem + 0.35vw, 1rem);
  text-transform: uppercase;
  letter-spacing: clamp(0.08em, 0.04em + 0.3vw, 0.13em);
  color: var(--accent-text);
  border-top: 2px solid var(--accent);
  padding-top: 0.9rem;
  margin: 0 0 1.5rem;
}

.yours-free {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.4rem, 1.2rem + 1vw, 1.9rem);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #f3ece0;
  margin: 0 0 0.75rem;
}

/* One sentence, set narrow and large so it stacks of its own accord. Hard
   line breaks would land in the wrong places at every width but one. */
.squeeze-headline {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.4rem, 1.12rem + 1.35vw, 1.95rem);
  line-height: 1.2;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: #fff;
  margin: 0 0 1.75rem;
}
/* Block display puts the closing clause on its own line at any width. */
.headline-turn {
  display: block;
  color: var(--accent-text);
  margin-top: 0.25em;
}

.squeeze-form .optin {
  background: var(--surface);
  backdrop-filter: blur(2px);
  /* Dashed on this page only, so it reads as the thing to fill in rather
     than one more panel among several. */
  border-style: dashed;
}
.squeeze-form .field input[type="text"],
.squeeze-form .field input[type="email"] {
  background: rgba(8, 7, 5, 0.75);
  color: var(--ink);
  border-color: var(--rule);
}

/* The line that closes the pitch, under the headline. */
.no-fluff {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.2rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #f3ece0;
  margin: 0 0 1.75rem;
}

.offer-box {
  border: 2px solid var(--accent);
  background: rgba(18, 16, 13, 0.85);
  padding: 1.25rem 1.25rem 0.5rem;
  margin: 0 0 1.5rem;
}
.offer-box p { margin: 0 0 1rem; }
.arrows {
  text-align: center;
  color: var(--accent-text);
  font-size: 1.6rem;
  letter-spacing: 0.5em;
  margin: 0 0 0.5rem !important;
  text-shadow: none;
}

/* Section 6 - the escape route, on its own panel so it reads wherever the
   illustration crops behind it. */
/* The way out, given the room the reference gives it: centred, large, and
   sitting on a soft wash rather than inside a hard-edged box. */
.squeeze-aside {
  margin-top: 2.5rem;
  /* The reference has no box here at all, because the art behind it is flat
     dark. Ours is not, so the darkening fades out instead of ending on a
     visible rectangle edge. */
  background: radial-gradient(
    ellipse at center,
    rgba(8, 7, 5, 0.88) 0%,
    rgba(8, 7, 5, 0.8) 45%,
    rgba(8, 7, 5, 0) 78%
  );
  padding: 3rem 2.5rem;
  text-align: center;
}
.escape-head {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.4rem, 1.7rem + 2.8vw, 3.8rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent-lift);
  text-decoration: underline;
  text-decoration-thickness: 4px;
  text-underline-offset: 0.14em;
  margin: 0 0 1.4rem;
}
.escape-link {
  margin: 0 0 1.5rem;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  line-height: 1.45;
}
.escape-link a { color: #ffffff; text-underline-offset: 0.18em; }
.escape-link a:hover { color: var(--accent-lift); }
.escape-note {
  margin: 0;
  font-size: 0.95rem;
  color: #d5cec2;
  line-height: 1.6;
}

/* Section 7 - footer, on the squeeze page only. */
.squeeze-footer {
  position: relative;
  width: 100%;
  margin-top: 3rem;
  padding: 1.5rem var(--gutter) 0;
  font-size: 0.82rem;
  color: var(--muted);
  text-align: center;
}
.squeeze-footer p { margin: 0 0 0.35rem; }
.squeeze-footer a { color: var(--muted); }
.squeeze-footer a:hover { color: var(--accent-text); }

/* ----------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--rule);
  margin-top: 4rem;
  background: var(--surface);
}
.footer-inner {
  max-width: 68rem;
  margin: 0 auto;
  padding: 2.5rem var(--gutter);
  font-size: 0.9rem;
  color: var(--muted);
  display: grid;
  gap: 1.25rem;
}
.footer-inner ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
}
.footer-org, .footer-copy { margin: 0; }

@media (min-width: 48em) {
  .footer-inner {
    grid-template-columns: 1fr auto;
    align-items: start;
  }
  .footer-copy { grid-column: 1 / -1; }
}

/* ------------------------------------------------------------------ print */

@media print {
  .masthead, .sidebar, .foot-optin, .site-footer, .piece-nav { display: none; }
  .shell { display: block; max-width: none; }
}
