/* ==========================================================================
   Blog page — only what styles.css doesn't already cover.
   Interactive piece: the topic filter (radio .choice chips + :has()).
   ========================================================================== */

/* ---------- Intro row: title on the left, topic chips on the right ---------- */
.blog-latest { padding-block: clamp(40px, 5vw, 72px) clamp(56px, 6vw, 88px); }
.blog-best { padding-block: clamp(56px, 6vw, 88px); }
.blog-head { display: grid; gap: 22px 40px; align-items: end; padding-bottom: clamp(24px, 3vw, 36px); }
.blog-hello .lede { max-width: 34ch; margin-top: 12px; }
.blog-pick { display: grid; justify-items: start; gap: 8px; min-width: 0; }
.blog-pick .note { margin: 0 0 2px 6px; }
.blog-filter { margin: 0; }
.blog-filter small { margin-left: 8px; color: var(--muted); font-size: 0.85em; font-weight: 600; font-variant-numeric: tabular-nums; }
.blog-filter input:checked + span small { color: var(--ink); }
@media (min-width: 960px) {
  .blog-head { grid-template-columns: minmax(0, 1fr) auto; }
  .blog-pick { justify-items: end; }
  .blog-pick .blog-filter { justify-content: flex-end; }
  .blog-pick .note { margin-right: 18px; }
}

/* ---------- "Latest posts" + status line, under one drawn rule ---------- */
.blog-bar {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px;
  margin-bottom: clamp(20px, 2.6vw, 30px); padding-top: clamp(16px, 2vw, 22px);
  border-top: 1.5px solid var(--line-strong);
}
.blog-bar h2 { font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.45rem); letter-spacing: -0.01em; }
.blog-status { min-height: 1.6em; margin: 0; color: var(--muted); font-size: 1rem; }
.blog-status > span { display: none; }

/* Which status line shows */
.blog-latest:has(#topic-all:checked) [data-for="all"],
.blog-latest:has(#topic-business:checked) [data-for="business"],
.blog-latest:has(#topic-travel:checked) [data-for="travel"],
.blog-latest:has(#topic-life:checked) [data-for="life"],
.blog-latest:has(#topic-museums:checked) [data-for="museums"] { display: inline; }

/* Which posts show (a post can have more than one topic) */
.blog-latest:has(#topic-business:checked) .blog-feed > :not([data-topic~="business"]),
.blog-latest:has(#topic-travel:checked) .blog-feed > :not([data-topic~="travel"]),
.blog-latest:has(#topic-life:checked) .blog-feed > :not([data-topic~="life"]),
.blog-latest:has(#topic-museums:checked) .blog-feed > :not([data-topic~="museums"]) { display: none; }

/* ---------- The feed ---------- */
.blog-feed { grid-auto-flow: dense; row-gap: clamp(30px, 3.4vw, 44px); }
.blog-feed .post__img { aspect-ratio: 4 / 3; }

/* Newest post: a big yellow card. Two columns wide on tablet,
   two columns by two rows on desktop. */
.post--feature {
  gap: 0; padding: clamp(12px, 1.4vw, 18px); border-radius: var(--r-lg);
  background: var(--yellow); color: var(--ink);
  transition: rotate 0.3s var(--bounce);
}
.post--feature .post__img { border-radius: var(--r); }
.post--feature .post__body { display: grid; gap: 8px; padding: clamp(16px, 2vw, 24px) clamp(6px, 1vw, 12px) clamp(6px, 0.8vw, 10px); }
.post__tag { color: var(--ink); font-weight: 700; font-size: 0.95rem; }
.post--feature h3 { font-size: clamp(1.45rem, 1.15rem + 1.1vw, 2.1rem); line-height: 1.12; letter-spacing: -0.02em; }
.post--feature p { max-width: 46ch; color: var(--ink-2); font-size: 1.05rem; }
.post--feature .blog-text__more { margin-top: 4px; }
.post--feature:hover { rotate: -0.5deg; }
.post--feature:hover h3 { text-decoration-color: var(--ink); }
.post--feature:hover .blog-text__more::after { translate: 5px 0; }
@media (min-width: 640px) { .post--feature { grid-column: span 2; } }
@media (min-width: 960px) {
  .post--feature { grid-row: span 2; }
  .post--feature .post__img { position: relative; flex: 1 1 auto; min-height: 300px; aspect-ratio: auto; }
  .post--feature .post__img img { position: absolute; inset: 0; }
}

/* The two posts without photos share one cell */
.blog-pair { display: grid; gap: 14px; align-content: start; }
.blog-text {
  display: flex; flex-direction: column; gap: 8px;
  padding: clamp(20px, 2.2vw, 26px); border-radius: 16px;
  background: var(--cream); color: inherit; text-decoration: none;
  transition: transform 0.3s var(--bounce), background-color 0.2s;
}
.blog-text h3 { font-size: 1.2rem; }
.blog-text p { color: var(--muted); font-size: 1rem; line-height: 1.5; }
.blog-text__more { display: inline-flex; gap: 0.35em; margin-top: auto; padding-top: 4px; color: var(--ink); font-weight: 600; font-size: 0.95rem; }
.blog-text__more::after { content: "→"; transition: translate 0.25s var(--bounce); }
.blog-text:hover { background: var(--yellow-soft); transform: translateY(-3px) rotate(-0.6deg); }
.blog-text:hover .blog-text__more::after { translate: 5px 0; }
@media (min-width: 960px) {
  .blog-pair { align-content: stretch; }
  .blog-text p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
}

/* Cards come back in when you switch topics. Each topic uses its own
   (identical) keyframes so every visible card replays, not just new ones.
   They move filter + transform only, so they never fight the scroll "deal"
   further down (opacity, translate, scale, rotate). */
@keyframes blog-in-a { from { filter: opacity(0); transform: translateY(16px); } to { filter: none; transform: none; } }
@keyframes blog-in-b { from { filter: opacity(0); transform: translateY(16px); } to { filter: none; transform: none; } }
@keyframes blog-in-c { from { filter: opacity(0); transform: translateY(16px); } to { filter: none; transform: none; } }
@keyframes blog-in-d { from { filter: opacity(0); transform: translateY(16px); } to { filter: none; transform: none; } }
@keyframes blog-in-e { from { filter: opacity(0); transform: translateY(16px); } to { filter: none; transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .blog-feed > * { animation: blog-in-a 0.45s var(--ease) both; animation-delay: var(--d, 0s); }
  .blog-latest:has(#topic-business:checked) .blog-feed > * { animation-name: blog-in-b; }
  .blog-latest:has(#topic-travel:checked) .blog-feed > * { animation-name: blog-in-c; }
  .blog-latest:has(#topic-life:checked) .blog-feed > * { animation-name: blog-in-d; }
  .blog-latest:has(#topic-museums:checked) .blog-feed > * { animation-name: blog-in-e; }
  .blog-feed > :nth-child(2) { --d: 40ms; }
  .blog-feed > :nth-child(3) { --d: 80ms; }
  .blog-feed > :nth-child(4) { --d: 120ms; }
  .blog-feed > :nth-child(5) { --d: 160ms; }
  .blog-feed > :nth-child(6) { --d: 200ms; }
  .blog-feed > :nth-child(7) { --d: 240ms; }
  .blog-feed > :nth-child(8) { --d: 280ms; }
  .blog-feed > :nth-child(9) { --d: 320ms; }
}

/* ---------- Best articles: a grid of cards on the cream band ---------- */
.blog-best .head { margin-bottom: clamp(22px, 3vw, 32px); }
.best { display: grid; gap: clamp(12px, 2vw, 24px); }
@media (min-width: 640px) { .best { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 960px) { .best { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.best > li { display: grid; }
.best__card {
  display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 14px; align-items: center;
  padding: 10px; border-radius: 16px; background: var(--paper);
  color: inherit; text-decoration: none;
  transition: transform 0.3s var(--bounce), box-shadow 0.2s;
}
@media (min-width: 640px) {
  .best__card { grid-template-columns: minmax(0, 1fr); align-content: start; align-items: start; padding: 12px 12px 20px; }
}
/* These thumbnails have words on them, so show them uncropped */
.best__img { width: 100%; aspect-ratio: 960 / 502; object-fit: cover; border-radius: 8px; }
.best__body { display: grid; gap: 4px; padding-inline: 4px; }
@media (min-width: 640px) { .best__body { padding-inline: 8px; } }
.best__title { color: var(--ink); font-weight: 650; font-size: 1.15rem; line-height: 1.3; }
.best__desc { color: var(--muted); font-size: 0.98rem; line-height: 1.45; }
.best__card:hover { transform: translateY(-4px) rotate(-0.6deg); box-shadow: var(--shadow); }
.best__card:hover .best__title { text-decoration: underline; text-decoration-color: var(--yellow); text-decoration-thickness: 4px; text-underline-offset: 3px; }
@media (max-width: 639px) { .best__title { font-size: 1.05rem; } .best__desc { font-size: 0.92rem; } }

/* ---------- Travel guides + business resources: two cream cards ---------- */
.blog-guides { padding-block: clamp(48px, 5vw, 72px); }
.blog-cols { display: grid; gap: clamp(18px, 2.4vw, 28px); align-items: start; }
@media (min-width: 900px) { .blog-cols { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); align-items: stretch; } }
.blog-box { display: flex; flex-direction: column; padding: clamp(22px, 2.6vw, 32px); border-radius: var(--r-lg); background: var(--cream); }
.blog-box h2 { font-size: clamp(1.5rem, 1.25rem + 0.9vw, 2rem); }
.blog-box .go { align-self: flex-start; margin-top: auto; }
/* When the two cards sit side by side, the shorter list's tiles grow to fill
   its card instead of leaving a gap under the last one */
@media (min-width: 900px) { .blog-box .blog-links { flex: 1 0 auto; grid-auto-rows: 1fr; } }

.blog-links { display: grid; gap: 8px; margin: 18px 0 14px; }
@media (min-width: 640px) { .blog-links--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.blog-links li { display: grid; }
.blog-links a {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 18px; border-radius: 12px; background: var(--paper);
  color: var(--ink); font-weight: 600; font-size: 1.08rem; line-height: 1.3; text-decoration: none;
  transition: background-color 0.2s, transform 0.25s var(--bounce);
}
.blog-links a::after { content: "→"; flex: none; color: var(--muted); transition: translate 0.25s var(--bounce), color 0.2s; }
.blog-links a:hover { background: var(--yellow-soft); transform: rotate(-0.6deg); }
.blog-links a:hover::after { translate: 5px 0; color: var(--ink); }

.blog-thumbs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 18px; }
.blog-thumb {
  display: grid; align-content: start; gap: 10px; padding: 8px 8px 14px; border-radius: 14px;
  background: var(--paper); color: var(--ink); font-weight: 600; font-size: 1rem; line-height: 1.3; text-decoration: none;
  transition: transform 0.3s var(--bounce), box-shadow 0.2s;
}
.blog-thumb span { padding-inline: 6px; }
.blog-thumb img { width: 100%; aspect-ratio: 960 / 502; object-fit: cover; border-radius: 8px; }
.blog-thumb:hover { transform: translateY(-3px) rotate(-0.8deg); box-shadow: var(--shadow); }
.blog-thumb:hover span { text-decoration: underline; text-decoration-color: var(--yellow); text-decoration-thickness: 3px; text-underline-offset: 3px; }

.blog-all { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 24px; margin-top: clamp(32px, 4vw, 48px); }

/* ---------- Newsletter ---------- */
.blog-join { padding-block: clamp(52px, 6vw, 84px); }
.blog-join__row { display: grid; gap: 24px 56px; align-items: center; }
.blog-join .lede { margin-top: 10px; }
@media (min-width: 900px) { .blog-join__row { grid-template-columns: minmax(0, 1fr) minmax(0, 520px); } }
/* The heading lights up word by word (.lit); keep its balanced wrap */
.blog-join .lit { text-wrap: balance; }

/* ==========================================================================
   Motion. Everything above is the finished state. These only run with
   prefers-reduced-motion: no-preference; the scroll-driven parts also need
   animation-timeline support. Individual translate/scale/rotate, opacity,
   clip-path and filter only, so hover and checked-state transforms still work.
   ========================================================================== */
@keyframes blog-line { from { scale: 0 1; } to { scale: 1 1; } }
@keyframes blog-pop { from { opacity: 0; translate: 0 14px; scale: 0.82; } to { opacity: 1; translate: 0 0; scale: 1; } }
@keyframes blog-scribble { from { clip-path: inset(-40% 100% -40% -10%); } to { clip-path: inset(-40% -10% -40% -10%); } }
@keyframes blog-wipe { from { clip-path: inset(100% 0 0 0 round var(--r)); } to { clip-path: inset(0 0 0 0 round var(--r)); } }
@keyframes blog-zoom { from { scale: 1.22; } to { scale: 1; } }
@keyframes blog-zoom-p { from { scale: 1.42; } to { scale: 1.16; } }
@keyframes blog-deal {
  from { opacity: 0; translate: var(--dx) var(--dy); scale: var(--ds); rotate: var(--dr); }
  to { opacity: 1; translate: 0 0; scale: 1; rotate: 0deg; }
}
@keyframes blog-thumb { from { opacity: 0; translate: 72px 0; clip-path: inset(0 0 0 100% round 8px); } to { opacity: 1; translate: 0 0; clip-path: inset(0 0 0 0 round 8px); } }
@keyframes blog-row { from { opacity: 0; translate: -36px 0; } to { opacity: 1; translate: 0 0; } }
@keyframes blog-band { from { clip-path: inset(0 4vw round 44px); } to { clip-path: inset(0 0 round 0px); } }

@media (prefers-reduced-motion: no-preference) {
  /* ---- On load: the rule under the intro draws itself, the heading rises,
     the topic chips pop in one by one, "Pick a topic" gets written ---- */
  .blog-bar { position: relative; border-top-color: transparent; }
  .blog-bar::before {
    content: ""; position: absolute; left: 0; right: 0; top: -1.5px; height: 1.5px;
    background: var(--line-strong); transform-origin: 0 50%;
    animation: blog-line 1.2s 0.3s cubic-bezier(0.7, 0, 0.2, 1) both;
  }
  .blog-bar h2 { animation: m-rise 0.9s 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .blog-filter .choice { animation: blog-pop 0.6s var(--c, 0.55s) var(--bounce) both; }
  .blog-filter .choice:nth-of-type(2) { --c: 0.62s; }
  .blog-filter .choice:nth-of-type(3) { --c: 0.69s; }
  .blog-filter .choice:nth-of-type(4) { --c: 0.76s; }
  .blog-filter .choice:nth-of-type(5) { --c: 0.83s; }
  .blog-pick .note { animation: blog-scribble 0.8s 1.05s cubic-bezier(0.5, 0, 0.3, 1) both; }
  .blog-status { animation: m-rise 0.8s 0.85s cubic-bezier(0.2, 0.8, 0.2, 1) both; }

  /* ---- On load: the newest posts' photos wipe open, one after another ---- */
  .blog-feed > :nth-child(-n+3) .post__img { animation: blog-wipe 1.1s var(--w, 0.32s) cubic-bezier(0.7, 0, 0.2, 1) both; }
  .blog-feed > :nth-child(-n+3) .post__img img { animation: blog-zoom 1.6s var(--w, 0.32s) cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .blog-feed > :nth-child(2) { --w: 0.45s; }
  .blog-feed > :nth-child(3) { --w: 0.58s; }

  @supports (animation-timeline: view()) {
    /* Dealt cards and sliding thumbnails start off to the side; keep that
       from ever widening the page */
    .blog-latest, .blog-best, .blog-guides { overflow-x: clip; }

    /* The zoom lands on the parallax scale, then the photo keeps drifting */
    .blog-feed > :nth-child(-n+3) .post__img img {
      animation: blog-zoom-p 1.6s var(--w, 0.32s) cubic-bezier(0.2, 0.8, 0.2, 1) both, m-parallax linear both;
      animation-timeline: auto, view();
      animation-range: normal, cover 0% cover 100%;
    }

    /* ---- Latest posts: cards are dealt in as you scroll. Each column comes
       from its own depth, angle and side, as if dealt from the middle. ---- */
    .blog-feed > * { --dx: 0px; --dy: 120px; --ds: 0.86; --dr: -2.5deg; --deal: entry 0% entry 75%; }
    .blog-feed > :nth-child(even) { --dr: 2.5deg; --dy: 140px; --ds: 0.83; }
    /* Tablet: the big card fills the first row, so even cards sit on the left */
    @media (min-width: 640px) and (max-width: 959px) {
      .blog-feed > :nth-child(even) { --dx: 48px; --dy: 120px; --ds: 0.88; --dr: -3deg; --deal: entry 0% entry 70%; }
      .blog-feed > :nth-child(odd) { --dx: -48px; --dy: 150px; --ds: 0.84; --dr: 3deg; --deal: entry 12% entry 85%; }
    }
    /* Desktop: the big card takes two columns of the first two rows, so from
       the third row on, 3n+1 / 3n+2 / 3n are the left / middle / right columns */
    @media (min-width: 960px) {
      .blog-feed > :nth-child(3n+1) { --dx: 70px; --dy: 120px; --ds: 0.88; --dr: -4deg; --deal: entry 0% entry 65%; }
      .blog-feed > :nth-child(3n+2) { --dx: 0px; --dy: 180px; --ds: 0.8; --dr: 1.5deg; --deal: entry 10% entry 80%; }
      .blog-feed > :nth-child(3n) { --dx: -70px; --dy: 145px; --ds: 0.85; --dr: 4deg; --deal: entry 20% entry 95%; }
    }
    /* Only with "Everything" picked, and never for the cards in view on load
       (they wipe in instead), so a filtered view never lands half-dealt. */
    .blog-latest:has(#topic-all:checked) .blog-feed > :nth-child(n+2) {
      animation: blog-in-a 0.45s var(--ease) both, blog-deal linear both;
      animation-delay: var(--d, 0s), 0s;
      animation-timeline: auto, view();
      animation-range: normal, var(--deal);
    }
    @media (min-width: 960px) {
      .blog-latest:has(#topic-all:checked) .blog-feed > :nth-child(2),
      .blog-latest:has(#topic-all:checked) .blog-feed > :nth-child(3) { animation-name: blog-in-a, none; }
    }

    /* ---- Colour bands open out to full width as they arrive ---- */
    @media (min-width: 760px) {
      .blog-best, .blog-join { animation: blog-band linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
    }

    /* ---- Best articles: cards rise in turn, then each thumbnail slides in
       from the right ---- */
    .blog-best .best.stagger > li { animation-range: entry 0% cover 30%; }
    .blog-best .best__img { animation: blog-thumb linear both; animation-timeline: view(); animation-range: entry 25% cover 42%; }
    @media (min-width: 640px) and (max-width: 959px) {
      .blog-best .best.stagger > li:nth-child(even) { animation-range: entry 10% cover 34%; }
    }
    @media (min-width: 960px) {
      .blog-best .best.stagger > li:nth-child(3n+2) { animation-range: entry 10% cover 34%; }
      .blog-best .best.stagger > li:nth-child(3n) { animation-range: entry 20% cover 38%; }
    }

    /* ---- Guides + resources: link tiles slide in from the left, one by one ---- */
    .blog-links.stagger > li { animation-name: blog-row; animation-range: entry 0% cover 22%; }
    .blog-thumb img { animation: blog-thumb linear both; animation-timeline: view(); animation-range: entry 10% cover 30%; }
  }
}
