/* ── Field Notes: the /news/ index, the story pages, and the shared signup ──
   Replaces john-news-clean.css (the retired client-rendered feed + iframe reader,
   removed 2026-09-22 with the old newsletter pipeline). Built by
   scripts/news_stories.py.

   ⛔ NEVER write a rule for a bare page-identifier class (.jh-news, .jh-news-story).
   Those are <body> classes; a same-named section rule matched <body> on 2026-08-05
   and capped the whole page to 1180px ([[jh-news-body-class-css-collision]]).
   Everything here is prefixed by its own component: .jh-news-*, .jh-story*. */

/* ---------- /news/ index hero (unchanged from the feed page) ----------
   The 180px floor: the hero is a single H1, so its content block is only ~114px and
   27svh stops winning below a ~423px-tall viewport (a landscape phone). The balancing
   16px bottom padding is dropped so the H1 sits centred between the header and the
   hero's foot. No effect at any normal height. */
.jh-news-hero { min-height: max(27svh, 180px); }
.jh-news-hero .jh-page-hero__content { text-align: center; padding-bottom: 0; }

/* ---------- /news/ index grid ---------- */
.jh-news-feed-section { max-width: 1180px; margin: 0 auto; padding: 64px 24px 96px; }
.jh-news-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 26px; }
.jh-news-empty { grid-column: 1 / -1; text-align: center; color: var(--jh-muted); margin: 0; padding: 24px 0; }
.jh-news-card {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  border: 1px solid var(--jh-line); border-radius: 16px; overflow: hidden;
  background: var(--jh-panel); transition: transform .16s ease, box-shadow .16s ease;
}
.jh-news-card:hover { transform: translateY(-3px); box-shadow: var(--jh-shadow); }
.jh-news-card:focus-visible { outline: 2px solid var(--jh-text); outline-offset: 3px; }
.jh-news-card__media { display: block; aspect-ratio: 3 / 2; background: #ddd6c6; overflow: hidden; }
.jh-news-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease; }
.jh-news-card:hover .jh-news-card__media img { transform: scale(1.04); }
.jh-news-card__body { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 9px; }
.jh-news-card__kicker {
  font-family: var(--jh-font-display); text-transform: uppercase; letter-spacing: .18em;
  font-size: .72rem; color: var(--jh-muted);
}
.jh-news-card__summary { font-size: 1rem; line-height: 1.6; color: var(--jh-text); }
.jh-news-card__more {
  margin-top: 4px; font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--jh-text);
}

/* ---------- story hero: the site-standard .jh-page-hero, kicker only ----------
   The kicker is the page's H1 (John 2026-09-22: no headline, the kicker is enough), so
   it takes the .jh-kicker look and loses the H1's default weight/margins. Height is the
   untouched .jh-page-hero rule, the same band as /about and the Calendar. */
/* The kicker's SIZE is John's, 2026-09-23 ("increase font size of Field Notes · Laikipia,
   Kenya"). ⛔ Raise it HERE, never on the shared `.jh-kicker` in john-clean.css — that
   class is the eyebrow on /about, the Calendar and every safari page, and moving it would
   resize the whole site. The clamp lands on 1.25rem from ~1230px up and eases back to
   1rem on a phone; the tracking drops from .24em to .2em so the extra size does not push
   a one-line kicker into a ragged wrap, and `text-wrap: balance` makes the phone's
   two-line case break evenly at the "·" instead of orphaning a word. */
.jh-story-hero__kicker {
  margin: 0; font-weight: 400; line-height: 1.4;
  font-size: clamp(1rem, .86rem + .62vw, 1.25rem);
  letter-spacing: .2em;
  text-wrap: balance;
  opacity: .92;
}

/* ---------- story body ---------- */
.jh-story {
  --jh-story-pt: clamp(40px, 6vw, 64px);
  --jh-story-px: clamp(16px, 4vw, 48px);
  position: relative;
  max-width: 1180px; margin: 0 auto;
  padding: var(--jh-story-pt) var(--jh-story-px) 24px;
}
.jh-story__prose { max-width: 66ch; margin: 0 auto; }
.jh-story__prose p { margin: 0 0 1.15em; font-size: 17px; line-height: 1.72; }
.jh-story__prose--first p:first-child::first-letter {
  font-family: var(--jh-font-display); float: left; font-size: 3.4em; line-height: .9; padding: 6px 10px 0 0;
}
/* ⛔ ONE BODY PHOTO PER ROW, AT THE PROSE WIDTH (John 2026-09-23: "make them the same
   width as the text / don't show two photos side by side, always just one"). The 66ch is
   `.jh-story__prose`'s own max-width, deliberately repeated so the figure and the text it
   sits between measure the same. The two-up grid that held p3+p4 is gone. */
.jh-story__fig { margin: 44px auto; max-width: 66ch; }
.jh-story__slot { position: relative; border-radius: 6px; overflow: hidden; background: #ddd6c6; }
.jh-story__slot img { display: block; width: 100%; height: auto; }
.jh-story figcaption { font-size: 13px; color: var(--jh-muted); margin-top: 10px; text-align: center; }

/* ---------- back to /news ----------
   The site's breadcrumb is JSON-LD only, so a reader's route back to the index is this
   link — above the first prose block and again under the gallery (John 2026-09-23: "we
   also need to go back to the main news page with all stories, how to navigate that"). */
.jh-story-back {
  display: inline-block; text-decoration: none; color: var(--jh-muted);
  font-family: var(--jh-font-display); font-size: .74rem; letter-spacing: .18em;
  text-transform: uppercase; transition: color .14s ease;
}
.jh-story-back:hover { color: var(--jh-text); }
.jh-story-back:focus-visible { outline: 2px solid var(--jh-text); outline-offset: 3px; }
/* ⛔ THE WRAPPER CARRIES THE WIDTH, NOT THE LINK. `66ch` on the anchor itself
   resolves in the DISPLAY face (Aboreto), which is narrower than the body face the
   prose is set in — 501.7px against the prose's 627.3px — so the link sat 63px
   right of the text it is meant to line up with. The wrapper inherits the body
   font from .jh-story, so its 66ch is the prose's own measure. */
/* ⛔ THE LINK LIVES IN THE PAGE'S LEFT MARGIN, LEVEL WITH THE FIRST PARAGRAPH
   (John, 2026-09-23, with a screenshot: "it needs to go to the left column. then
   [the opening paragraph] can be at the top centre and ← All field notes is on the
   left of that"). Absolute, so the prose column stays centred on the page instead
   of being pushed right by the link — `top` is the article's own padding, which is
   where the first prose line begins. Below 1000px there is no margin to sit in, so
   it returns to the flow above the prose, still at the left edge. */
.jh-story-back-head {
  position: absolute; top: var(--jh-story-pt); left: var(--jh-story-px);
  margin: 0; z-index: 2;
}
@media (max-width: 1000px) {
  .jh-story-back-head { position: static; margin: 0 0 22px; }
}
.jh-story-back--top { display: inline-block; }
/* ⛔ LEFT, in the prose column — never centred (John, 2026-09-23: "put the all field
   notes back on the left side in the left column not centrally"). The gallery above
   it runs the full 1240px, so a centred link floated out into the middle of the page;
   both back links now share the prose column's own left edge. */
.jh-story-back-foot { margin: 38px 0 0; text-align: left; }

/* The site's pill button — black, white text, 999px, uppercase 13px 600 .1em. The email
   copies these exact values (Life comms renderer), so they read as one design. */
.jh-story-button {
  display: inline-block; background: var(--jh-accent); color: #fff; text-decoration: none;
  font: 600 13px/1 var(--jh-font-body); letter-spacing: .1em; text-transform: uppercase;
  padding: 15px 26px; border-radius: 999px;
}
.jh-story-button:hover { filter: brightness(1.3); }
.jh-story-button:focus-visible { outline: 2px solid var(--jh-text); outline-offset: 3px; }

.jh-story-cta {
  max-width: 880px; margin: 56px auto 0; padding: 40px 16px; text-align: center;
  border-top: 1px solid var(--jh-line); border-bottom: 1px solid var(--jh-line);
}
.jh-story-cta[hidden] { display: none !important; }
.jh-story-cta__eyebrow {
  margin: 0; font-family: var(--jh-font-display); font-size: 12px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--jh-muted);
}
.jh-story-cta__title {
  font-family: var(--jh-font-display); font-weight: 400; font-size: clamp(22px, 2.6vw, 30px);
  letter-spacing: .04em; text-transform: uppercase; margin: 10px 0 8px;
}
.jh-story-cta__text { color: var(--jh-muted); margin: 0 auto 22px; max-width: 56ch; }

/* ---------- "Photos from the trip" — justified rows ----------
   Each tile grows in proportion to its aspect ratio (--r = w/h) from a basis of
   r × row-height, so every row fills the width at one height with even 8px gutters.
   The ::after filler soaks up the LAST row's slack, so a short last row keeps its
   natural size instead of being stretched into giant crops. */
.jh-story-gallery { max-width: 1240px; margin: 0 auto; padding: 64px clamp(16px, 4vw, 48px) 24px; }
.jh-story-gallery__title {
  font-family: var(--jh-font-display); font-weight: 400; font-size: clamp(22px, 2.6vw, 30px);
  letter-spacing: .04em; text-transform: uppercase; text-align: center; margin: 0 0 26px;
}
.jh-story-gallery__tiles { --jh-row: 220px; display: flex; flex-wrap: wrap; gap: 8px; }
.jh-story-gallery__tiles::after { content: ""; flex-grow: 999999; }
.jh-story-tile {
  position: relative; flex: var(--r) 1 calc(var(--r) * var(--jh-row)); height: var(--jh-row);
  -webkit-appearance: none; appearance: none; padding: 0; border: 0; margin: 0;
  background: #d9d1c1; overflow: hidden; cursor: zoom-in; border-radius: 3px;
}
.jh-story-tile img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.jh-story-tile:hover img { transform: scale(1.03); }
.jh-story-tile:focus-visible { outline: 2px solid var(--jh-text); outline-offset: 2px; }
@media (max-width: 640px) {
  /* 104px: two 3:2 tiles (2 × 156px + 6px) share a row down to a 360px phone */
  .jh-story-gallery__tiles { --jh-row: 104px; gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .jh-story-tile img, .jh-news-card, .jh-news-card__media img { transition: none; }
}

/* ---------- mosaic (2026-10-28): different-sized tiles, text above and below ----------
   4-column dense grid; big = 2x2, wide = 2x1, tall = 1x2, std = 1x1. Two columns on a phone. */
.jh-mosaic { max-width: 1240px; margin: 0 auto; padding: 56px clamp(16px, 4vw, 48px) 8px; }
.jh-mosaic__text { max-width: 66ch; margin: 0 auto 22px; font-size: 1.05rem; line-height: 1.65; text-align: center; }
.jh-mosaic__text--below { margin: 22px auto 0; }
.jh-mosaic__grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: clamp(110px, 17vw, 210px); grid-auto-flow: dense; gap: 8px; }
.jh-mosaic__tile { position: relative; padding: 0; border: 0; margin: 0; background: #d9d1c1; overflow: hidden; cursor: zoom-in; border-radius: 3px; }
.jh-mosaic__tile--big { grid-column: span 2; grid-row: span 2; }
.jh-mosaic__tile--wide { grid-column: span 2; }
.jh-mosaic__tile--tall { grid-row: span 2; }
.jh-mosaic__tile img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.jh-mosaic__tile:hover img { transform: scale(1.03); }
.jh-mosaic__tile:focus-visible { outline: 2px solid var(--jh-text); outline-offset: 2px; }
@media (max-width: 640px) {
  .jh-mosaic__grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 120px; gap: 6px; }
}
@media (prefers-reduced-motion: reduce) { .jh-mosaic__tile img { transition: none; } }

/* ---------- guest album (2026-09-24): up to nine guest photos, each credited ----------
   Below the trip gallery. Uniform 3:2 tiles in a grid (not the justified rows above) so
   every credit line sits under its own photo. */
.jh-story-guests { max-width: 1240px; margin: 0 auto; padding: 40px clamp(16px, 4vw, 48px) 24px; }
.jh-story-guests .jh-story-gallery__title { margin-bottom: 10px; }
.jh-story-guests__note { text-align: center; margin: 0 0 24px; font-size: 15px; opacity: .72; }
.jh-story-guests__tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 10px; }
.jh-story-guest { position: relative; margin: 0; }
.jh-story-guest .jh-story-tile { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; flex: none; }
.jh-story-guest__credit { margin-top: 6px; font-size: 13px; line-height: 1.35; opacity: .75; }
@media (max-width: 640px) {
  .jh-story-guests__tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 6px; }
}

/* ---------- signup (the /news/ block, reused on every story) ---------- */
.jh-news-subscribe { margin: 84px auto 0; max-width: 560px; text-align: center; border-top: 1px solid var(--jh-line); padding-top: 54px; }
.jh-story-subscribe { padding: 0 24px 96px; }
.jh-story-subscribe .jh-news-subscribe { margin-top: 56px; }
.jh-news-subscribe__eyebrow {
  font-family: var(--jh-font-display); text-transform: uppercase; letter-spacing: .24em;
  font-size: .66rem; color: var(--jh-muted); margin: 0 0 12px;
}
.jh-news-subscribe__title { font-family: var(--jh-font-display); font-size: 1.5rem; line-height: 1.2; color: var(--jh-text); margin: 0 0 10px; font-weight: 400; }
.jh-news-subscribe__note { font-size: .92rem; line-height: 1.6; color: var(--jh-muted); margin: 0 auto 24px; max-width: 42ch; }
.jh-news-subscribe__form { display: flex; flex-direction: column; gap: 9px; max-width: 420px; margin: 0 auto; }
/* -webkit-appearance:none — iOS paints native field chrome under author CSS otherwise
   ([[ios-webkit-form-appearance]]). */
.jh-news-subscribe__name,
.jh-news-subscribe__email,
.jh-news-subscribe__button { -webkit-appearance: none; appearance: none; }
.jh-news-subscribe__name {
  width: 100%; box-sizing: border-box; border: 1px solid var(--jh-line); border-radius: 999px;
  background: var(--jh-panel); outline: none; font: inherit; font-size: .95rem; color: var(--jh-text); padding: 13px 18px;
}
.jh-news-subscribe__name:focus { border-color: var(--jh-text); box-shadow: 0 0 0 3px rgba(23, 21, 17, .06); }
.jh-news-subscribe__row {
  display: flex; align-items: center; gap: 8px; background: var(--jh-panel);
  border: 1px solid var(--jh-line); border-radius: 999px; padding: 5px 5px 5px 4px;
}
.jh-news-subscribe__row:focus-within { border-color: var(--jh-text); box-shadow: 0 0 0 3px rgba(23, 21, 17, .06); }
.jh-news-subscribe__email {
  flex: 1; min-width: 0; border: 0; border-radius: 999px; background: transparent; outline: none; font: inherit;
  font-size: .95rem; color: var(--jh-text); padding: 11px 16px;
}
.jh-news-subscribe__button {
  flex-shrink: 0; width: 42px; height: 42px; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--jh-accent); color: #fff; font-size: 1.15rem; line-height: 1; transition: filter .14s ease;
}
.jh-news-subscribe__button:hover { filter: brightness(1.3); }
.jh-news-subscribe__button[disabled] { cursor: wait; opacity: .7; }
.jh-news-subscribe__notice { font-size: .82rem; color: var(--jh-muted); margin: 14px 0 0; min-height: 18px; }
.jh-news-subscribe__notice.is-success { color: #2a6b36; }
.jh-news-subscribe__notice.is-error { color: #8b2f2f; }

/* Draft cards — LOCAL ONLY (scripts/news_stories.local_index_page_html). A story John
   has not published yet never reaches the live index, so these rules only ever paint on
   127.0.0.1; they live here so the local page uses the same stylesheet as the real one. */
.jh-news-card.is-draft .jh-news-card__media {
  position: relative;
}

.jh-news-card__badge {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 2;
  background: rgba(23, 21, 17, 0.82);
  color: #fff;
  font-family: var(--jh-font-body);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 10px;
  border-radius: 999px;
}

.jh-news-card.is-draft {
  outline: 1px dashed rgba(23, 21, 17, 0.28);
  outline-offset: 4px;
}

/* John 2026-10-28: gallery sits under the intro at the text column's width; text section follows. */
.jh-mosaic--narrow { max-width: 66ch; padding: 8px 0 24px; }
.jh-mosaic--narrow .jh-mosaic__grid { grid-auto-rows: clamp(70px, 11vw, 120px); gap: 6px; }
.jh-story__prose--wildlife .jh-mosaic__text { max-width: none; text-align: left; margin: 0 0 1.15em; font-size: 17px; line-height: 1.72; }

/* ---------- three galleries (2026-10-28) ---------- */
.jh-mosaic--narrow { padding: 14px 0 6px; }
.jh-mosaic__rows { display: grid; gap: 6px; }
.jh-mosaic__row { display: flex; gap: 6px; width: 100%; }
.jh-mosaic__row .jh-mosaic__tile { min-width: 0; height: 100%; border-radius: 8px; }
.jh-mosaic__feature { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 6px; aspect-ratio: 2.1 / 1; }
.jh-mosaic__feature .jh-mosaic__tile { border-radius: 8px; min-width: 0; min-height: 0; }
.jh-mosaic__f1 { grid-column: 1; grid-row: 1 / span 2; }
.jh-mosaic__f2 { grid-column: 2 / span 2; grid-row: 1; }
.jh-mosaic__f3 { grid-column: 2; grid-row: 2; }
.jh-mosaic__f4 { grid-column: 3; grid-row: 2; }
.jh-story__prose--gallery { margin-top: 14px; margin-bottom: 14px; }
.jh-story__prose--gallery .jh-mosaic__text { max-width: none; text-align: left; margin: 0; font-size: 17px; line-height: 1.72; }
/* no-download: images never take pointer events; the button receives the click */
.jh-mosaic img, [data-jh-lightbox] img { -webkit-user-drag: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.jh-mosaic__tile img { pointer-events: none; }
[data-jh-lightbox] img { pointer-events: none; }
@media (max-width: 640px) { .jh-mosaic__feature { aspect-ratio: 1.4 / 1; } }
.jh-story__lead { margin: 18px auto 10px; }
.jh-story__lead img { display: block; width: 100%; height: auto; border-radius: 8px; pointer-events: none; -webkit-user-drag: none; user-select: none; -webkit-touch-callout: none; }

/* John 2026-10-28: no dead air between the last text and Join us */
.jh-story-cta { margin-top: 18px; }
.jh-story .jh-story__prose:last-of-type p:last-child, .jh-story__prose--wildlife p:last-child, .jh-story__prose--wildlife:empty { margin-bottom: 0; }
.jh-story__prose--wildlife:empty { display: none; }
.jh-story .jh-mosaic--narrow:last-of-type { padding-bottom: 0; }
.jh-mosaic__tile img { border-radius: 8px; }

/* John 2026-10-28: less space above the top photo; photo 10% shorter (same width, cropped) */
.jh-story:has(.jh-story__lead) { --jh-story-pt: clamp(14px, 2vw, 22px); }
.jh-story__lead { margin-top: 0; }
.jh-story__lead img { object-fit: cover; height: auto; }

/* John 2026-10-28: tidy page foot — Join us flows straight into Stay in touch */
.jh-story:has(.jh-story-cta) { padding-bottom: 0; }
.jh-story-cta { border-bottom: 0; padding-bottom: 8px; }
.jh-story-subscribe { padding-bottom: 72px; }
.jh-story-subscribe .jh-news-subscribe { margin-top: 0; border-top: 0; padding-top: 24px; }
.jh-story-subscribe .jh-news-subscribe { border-top: 1px solid var(--jh-line); padding-top: 40px; margin-top: 12px; }
