/* ConnectedAlly blog — styles for the blog's own content only.
   Copied to BLOG_OUTPUT_DIR/blog.css on every rebuild and loaded after the
   React site's stylesheet.

   Rules:
   - Every selector starts with one of the blog's wrapper classes:
       .blog-article  <main> on a post page
       .blog-index    <main> on the list page
       .blog-skip     the skip link's wrapper
       .blog-chrome   the wrappers around the site header/footer
     Never a bare element, *, :root or html/body selector — those would beat
     the site's own chrome styles (test/blog-css.test.js enforces this).
   - Nothing here reaches inside .blog-chrome: the header, footer and cookie
     banner are styled only by the site's CSS.
   - No text or background colours (one exception: the decorative glow
     behind the index cards). Colours (light and dark) come from the
     site's root wrapper classes (SITE_ROOT_WRAPPER_CLASS in templates.js);
     only border tints are derived here, from currentColor.
   - Tailwind's reset (on the site's CSS) strips heading sizes, paragraph
     margins and list styles, so the content typography is restored below. */

/* Wrappers around the site header/footer: no box of their own, so the
   site's layout (flex column, sticky header) behaves as if they weren't there. */
.blog-chrome { display: contents; }

/* Skip link: hidden until focused. Uses system colours, not brand colours. */
.blog-skip .blog-skip-link {
  position: absolute;
  left: 8px;
  top: -48px;
  padding: 8px 12px;
  border-radius: 4px;
  background: Canvas;
  color: CanvasText;
  outline: 2px solid currentColor;
  z-index: 1000;
}
.blog-skip .blog-skip-link:focus { top: 8px; }

/* --- Layout (the <main> is a flex-1 item in the site's flex column) ------ */

.blog-article,
.blog-index {
  box-sizing: border-box;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 20px 48px;
  font-size: 1.125rem;
  line-height: 1.75;
}

/* --- Typography ------------------------------------------------------- */

.blog-article h1,
.blog-index h1 { font-size: 2.25rem; line-height: 1.2; font-weight: 700; margin: 0 0 0.5rem; }
.blog-article h2,
.blog-index h2 { font-size: 1.5rem; line-height: 1.3; font-weight: 700; margin: 2rem 0 0.75rem; }
.blog-article h3,
.blog-index h3 { font-size: 1.25rem; line-height: 1.4; font-weight: 600; margin: 1.5rem 0 0.5rem; }
.blog-article h4,
.blog-article h5,
.blog-article h6 { font-size: 1.125rem; font-weight: 600; margin: 1.25rem 0 0.5rem; }

.blog-article p,
.blog-index p { margin: 0 0 1.25rem; line-height: 1.75; }

.blog-article ul,
.blog-index ul { list-style: disc; padding-left: 1.5rem; margin: 0 0 1.25rem; }
.blog-article ol,
.blog-index ol { list-style: decimal; padding-left: 1.5rem; margin: 0 0 1.25rem; }
.blog-article li,
.blog-index li { margin: 0 0 0.35rem; }
.blog-article li > ul,
.blog-article li > ol { margin: 0.35rem 0 0; }

.blog-article blockquote {
  margin: 1.5rem 0;
  padding: 0.25rem 0 0.25rem 1rem;
  border-left: 4px solid color-mix(in srgb, currentColor 45%, transparent);
  font-style: italic;
}
.blog-article blockquote p:last-child { margin-bottom: 0; }

/* Links: colour inherits the surrounding text (light or dark), the underline
   is what marks them out. */
.blog-article a,
.blog-index a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.blog-article a:hover,
.blog-index a:hover { text-decoration-thickness: 2px; }
.blog-article a:focus-visible,
.blog-index a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.blog-article strong { font-weight: 700; }
.blog-article em { font-style: italic; }
.blog-article hr {
  border: 0;
  border-top: 1px solid color-mix(in srgb, currentColor 25%, transparent);
  margin: 2rem 0;
}

.blog-article code {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 0.9em;
  padding: 0.1em 0.3em;
  border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  border-radius: 4px;
}
.blog-article pre {
  overflow-x: auto;
  padding: 14px;
  margin: 0 0 1.25rem;
  border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  border-radius: 6px;
  line-height: 1.5;
}
.blog-article pre code { padding: 0; border: 0; }

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

/* In-post images (<figure><picture><img>…</picture><figcaption>). Never
   stretched past their own width; the caption uses the inherited colour. */
.blog-article figure { margin: 1.75rem 0; }
.blog-article figure img { display: block; margin: 0 auto; border-radius: 6px; }
.blog-article figcaption { margin-top: 0.5rem; font-size: 0.9375rem; text-align: center; opacity: 0.8; }

.blog-article table { border-collapse: collapse; width: 100%; display: block; overflow-x: auto; margin: 0 0 1.25rem; }
.blog-article th,
.blog-article td {
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  padding: 6px 10px;
}
.blog-article th { font-weight: 600; }
.blog-article td[align="right"],
.blog-article th[align="right"] { text-align: right; }
.blog-article td[align="center"],
.blog-article th[align="center"] { text-align: center; }

/* --- Post page specifics ------------------------------------------------- */

.blog-article .post__meta { margin: 0 0 1.5rem; font-size: 0.9375rem; opacity: 0.75; }
.blog-article .post__cover { display: block; width: 100%; height: auto; border-radius: 8px; margin: 0 0 1.75rem; }
.blog-article .post__back { margin-top: 2.5rem; }

/* Share block (after the post body, inside <article>). Pill-shaped controls,
   44px minimum touch target, text colour inherited. color: inherit and
   background: transparent only undo browser button defaults — they add no
   colour of their own. */
.blog-article .post-share {
  margin: 2.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
}
.blog-article .post-share__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.blog-article .post-share__item { margin: 0; }
.blog-article .post-share__link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 1rem;
  border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
  border-radius: 999px;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.2;
  color: inherit;
  background: transparent;
  text-decoration: none;
  cursor: pointer;
}
.blog-article .post-share__link:hover { border-color: color-mix(in srgb, currentColor 55%, transparent); }
.blog-article .post-share__link:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}
.blog-article .post-share__icon { flex-shrink: 0; width: 1.125rem; height: 1.125rem; }
/* Visually hidden, still read out: "(opens in a new window)". */
.blog-article .post-share__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.blog-article .post-share__status { margin: 0.5rem 0 0; min-height: 1.5em; font-size: 0.9375rem; }

/* --- List page: glass cards ------------------------------------------------ */

/* Wider than a post's reading width. --blog-card-radius is shared by the card
   and its image so the corners match. */
.blog-index {
  --blog-card-radius: 1rem;
  max-width: 56rem;
  position: relative;
  /* Own stacking context so the glow (z-index: -1) paints behind the cards
     but in front of the site's page background. */
  isolation: isolate;
}

/* Decorative glow behind the list — the one place blog.css uses colour.
   Absolutely positioned inside <main> (inset: 0), so it can't widen the page
   or shift layout; low opacity, behind the cards, never over text.
   closest-side ellipses fade to transparent exactly at <main>'s nearest
   edges, so there's no visible cut-off line on wide screens.
   Slightly weaker by default (light mode), stronger under the site's .dark
   class. */
.blog-index::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(closest-side at 30% 30%, color-mix(in srgb, #3b82f6 12%, transparent), transparent),
    radial-gradient(closest-side at 70% 65%, color-mix(in srgb, #ea580c 9%, transparent), transparent);
}
.blog-index:is(.dark *)::before {
  background:
    radial-gradient(closest-side at 30% 30%, color-mix(in srgb, #3b82f6 20%, transparent), transparent),
    radial-gradient(closest-side at 70% 65%, color-mix(in srgb, #ea580c 15%, transparent), transparent);
}

.blog-index .blog-index__title { margin-bottom: 1.75rem; }
.blog-index .blog-index__empty { margin: 0; }

.blog-index .post-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
}

.blog-index .post-card {
  position: relative; /* anchor for the stretched title link */
  margin: 0;
  border-radius: var(--blog-card-radius);
  border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  background: color-mix(in srgb, currentColor 6%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
/* No backdrop blur: raise the tint a little so the surface still reads. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .blog-index .post-card { background: color-mix(in srgb, currentColor 10%, transparent); }
}

/* Mobile first: image stacked on top of the text. */
.blog-index .post-card__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem;
}
@media (min-width: 640px) {
  .blog-index .post-card__inner {
    grid-template-columns: 38% minmax(0, 1fr);
    gap: 1.5rem;
    align-items: center;
  }
}

/* aspect-ratio reserves the space before the image loads (no layout shift). */
.blog-index .post-card__image,
.blog-index .post-card__placeholder {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--blog-card-radius);
}
.blog-index .post-card__image { height: auto; object-fit: cover; }
/* No cover image: a CSS-only tile from the text colour, so it suits either theme. */
.blog-index .post-card__placeholder {
  background:
    radial-gradient(circle at 25% 30%, color-mix(in srgb, currentColor 16%, transparent), transparent 60%),
    linear-gradient(135deg, color-mix(in srgb, currentColor 12%, transparent), color-mix(in srgb, currentColor 3%, transparent));
}

.blog-index .post-card__body { min-width: 0; }
.blog-index .post-card__title { margin: 0 0 0.25rem; font-size: 1.375rem; line-height: 1.3; }
.blog-index .post-card__meta { margin: 0 0 0.5rem; font-size: 0.9375rem; opacity: 0.75; }
.blog-index .post-card__excerpt {
  margin: 0 0 0.75rem;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}
.blog-index .post-card__cue { margin: 0; font-weight: 600; font-size: 0.9375rem; }

/* The title link covers the whole card; its focus ring is drawn on the
   stretched area so keyboard users see the card outlined. */
.blog-index .post-card__link { text-decoration: none; }
.blog-index .post-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--blog-card-radius);
}
.blog-index .post-card__link:focus-visible { outline: none; }
.blog-index .post-card__link:focus-visible::after {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}
.blog-index .post-card:hover .post-card__link,
.blog-index .post-card__link:focus-visible { text-decoration: underline; }

/* Hover / keyboard focus: border brightens for everyone; the lift is motion,
   so only for users who haven't asked for reduced motion. */
.blog-index .post-card:hover,
.blog-index .post-card:focus-within {
  border-color: color-mix(in srgb, currentColor 30%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .blog-index .post-card {
    transition: transform 160ms ease, border-color 160ms ease;
  }
  .blog-index .post-card:hover,
  .blog-index .post-card:focus-within {
    transform: translateY(-2px);
  }
}
