/**
 * Content base — the one stylesheet every content style inherits.
 *
 * Scope: the plugin's content wrapper, <div class="prose">, which carries the
 * Tailwind Typography rules (zero-specificity :where() selectors) and daisyUI's
 * --tw-prose-* colour bridge. This file sits above both with plain
 * `.prose el` selectors and owns three things a style never has to repeat:
 *
 *   1. Tokens. --content-* variables derived from the site's daisyUI colours,
 *      so a content style and a colour theme are independent choices.
 *   2. The measure. Line length is bounded here, whatever the wrapper's
 *      utility classes say.
 *   3. The block bridge. WordPress core ships structural CSS per block
 *      (table cell borders, grey buttons, pullquote padding, bare details);
 *      this settles every collision with the typography layer once.
 *
 * A content style (assets/css/content/<name>.css) loads after this file and
 * changes fonts, scale, rhythm and texture. It may override any token below.
 * Nothing here references a variable that is not defined here or by daisyUI.
 */

/* ------------------------------------------------------------------ */
/* 1. Tokens                                                           */
/* ------------------------------------------------------------------ */
.prose {
  --content-measure: 68ch;
  --content-body: color-mix(in oklab, var(--color-base-content) 88%, transparent);
  --content-heading: var(--color-base-content);
  --content-muted: color-mix(in oklab, var(--color-base-content) 60%, transparent);
  --content-link: var(--color-primary);
  --content-link-hover: color-mix(in oklab, var(--color-primary) 80%, var(--color-base-content));
  --content-rule: color-mix(in oklab, var(--color-base-content) 18%, transparent);
  --content-rule-strong: color-mix(in oklab, var(--color-base-content) 45%, transparent);
  --content-accent: var(--color-primary);
  --content-code-bg: var(--color-base-200);
  --content-code-fg: var(--color-base-content);
  --content-pre-bg: var(--color-neutral);
  --content-pre-fg: var(--color-neutral-content);
  --content-surface: var(--color-base-200);
  --content-radius: min(var(--radius-field, 0.375rem), 0.5rem);
  --content-button-bg: var(--color-primary);
  --content-button-fg: var(--color-primary-content);
  --content-button-radius: var(--radius-field, 0.375rem);

  /* Hand the tokens to the typography plugin so its :where() rules agree. */
  --tw-prose-body: var(--content-body);
  --tw-prose-headings: var(--content-heading);
  --tw-prose-lead: var(--content-body);
  --tw-prose-links: var(--content-link);
  --tw-prose-bold: var(--content-heading);
  --tw-prose-counters: var(--content-muted);
  --tw-prose-bullets: var(--content-muted);
  --tw-prose-hr: var(--content-rule);
  --tw-prose-quotes: var(--content-heading);
  --tw-prose-quote-borders: var(--content-rule-strong);
  --tw-prose-captions: var(--content-muted);
  --tw-prose-code: var(--content-code-fg);
  --tw-prose-pre-code: var(--content-pre-fg);
  --tw-prose-pre-bg: var(--content-pre-bg);
  --tw-prose-th-borders: var(--content-rule-strong);
  --tw-prose-td-borders: var(--content-rule);
  --tw-prose-kbd: var(--content-heading);

  color: var(--content-body);
  font-family: var(--font-body);
  font-size: var(--text-body-size, 1rem);
  line-height: var(--text-body-line-height, 1.6);
  overflow-wrap: break-word;
}

/* ------------------------------------------------------------------ */
/* 1b. Content surface                                                 */
/* A background (style default, page/site token, or the template's own  */
/* content_background) is rendered as a bg-layers wrapper around <main>. */
/* daisyUI paints every [data-theme] section opaque, so the section that */
/* holds the content goes transparent and the surface paints its colour  */
/* (it carries the same data-theme) plus pattern, noise and overlay.     */
/* ------------------------------------------------------------------ */
.plexa-content-surface[data-theme] { background-color: var(--root-bg, var(--color-base-100)); }
.plexa-content-surface section.plexa-content-section:has(.prose),
main.bg-layers section.plexa-content-section:has(.prose),
.plexa-page-surface section.plexa-content-section:has(.prose),
.page-wrapper.bg-layers section.plexa-content-section:has(.prose) {
  background-color: transparent;
}
/* A page-wide surface shows through the content section only when that
   section shares the page's colour scheme: a dark section over a light page
   keeps its own ground, and a light section over a dark base keeps its own. */
.plexa-page-surface section.plexa-content-section:has(.prose):is([data-theme$="-dark"], [data-theme$="-brand"], [data-theme$="-contrast"]),
.page-wrapper.bg-layers section.plexa-content-section:has(.prose):is([data-theme$="-dark"], [data-theme$="-brand"], [data-theme$="-contrast"]) {
  background-color: var(--root-bg, var(--color-base-100));
}
:is(.plexa-page-surface, .page-wrapper.bg-layers):is([data-bg-base="black"], [data-bg-base="onyx"], [data-bg-base="charcoal"], [data-bg-base="graphite"], [data-bg-base="ink"], [data-bg-base="slate"], [data-bg-base="espresso"], [data-bg-base="obsidian"], [data-bg-base="solid-dark"], [data-bg-base="gradient-dark"], [data-bg-base="gradient-night"], [data-bg-base="gradient-noir"], [data-bg-base="gradient-midnight"]) section.plexa-content-section:has(.prose) {
  background-color: var(--root-bg, var(--color-base-100));
}
:is(.plexa-page-surface, .page-wrapper.bg-layers):is([data-bg-base="black"], [data-bg-base="onyx"], [data-bg-base="charcoal"], [data-bg-base="graphite"], [data-bg-base="ink"], [data-bg-base="slate"], [data-bg-base="espresso"], [data-bg-base="obsidian"], [data-bg-base="solid-dark"], [data-bg-base="gradient-dark"], [data-bg-base="gradient-night"], [data-bg-base="gradient-noir"], [data-bg-base="gradient-midnight"]) section.plexa-content-section:has(.prose)[data-theme$="-dark"] {
  background-color: transparent;
}

/* Dark defaults: on the black and carbon grounds, text takes Apple's greys
   (#F5F5F7 primary, #86868B secondary) instead of the daisyUI dark tokens,
   so the default dark page reads like a system dark surface. */
:is(.plexa-page-surface, .page-wrapper.bg-layers, .plexa-content-surface, main.bg-layers):is([data-bg-base="black"], [data-bg-base="carbon"]) .prose {
  --content-heading: #F5F5F7;
  --content-body: #E8E8ED;
  --content-muted: #86868B;
  --content-rule: rgba(245, 245, 247, 0.14);
  --content-rule-strong: rgba(245, 245, 247, 0.32);
  --content-code-bg: #1D1D1F;
  --content-code-fg: #F5F5F7;
  --content-pre-bg: #1D1D1F;
  --content-pre-fg: #F5F5F7;
  --content-surface: #1D1D1F;
}

/* ------------------------------------------------------------------ */
/* 2. Measure                                                          */
/* ------------------------------------------------------------------ */
.prose,
.prose.max-w-none {
  max-width: var(--content-measure);
}

/* ------------------------------------------------------------------ */
/* 3. Headings, links, inline                                          */
/* ------------------------------------------------------------------ */
.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  color: var(--content-heading);
  font-family: var(--font-heading);
  text-wrap: balance;
  scroll-margin-top: 6rem;
}
/* A HEADING IN A READING COLUMN IS NOT A DISPLAY HEADING, AND THE SCALE DOES
   NOT KNOW THE DIFFERENCE. --text-h2-size is sized for a section title across
   the full width of a page; inside an article it lands in a column roughly two
   thirds as wide, above 16px body text. On the `dramatic` scale that token is
   5.063rem — 81px — so "Overview of Cockroaches" set as a section heading ran
   to two lines of 81px type over a paragraph of 16px, and a nine-minute read
   came out 16,592px tall.

   Capped, not replaced. The cap sits above every scale but `dramatic`:
   compact's h2 is 2.488rem and default's 2.25rem, both untouched, and h3 is
   2.074/1.875 against a 2.125rem cap. Only the scale that cannot fit a reading
   column is reined in, and only inside .prose — a page-level section title
   keeps the full drama, which is where drama belongs. */
.prose h2 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, min(var(--text-h2-size), 2.75rem)); font-weight: var(--text-h2-weight, 700); line-height: var(--text-h2-line-height, 1.2); letter-spacing: var(--text-h2-letter-spacing, 0); }
.prose h3 { font-size: clamp(1.25rem, 1rem + 0.9vw, min(var(--text-h3-size), 2.125rem)); font-weight: var(--text-h3-weight, 600); line-height: var(--text-h3-line-height, 1.25); letter-spacing: var(--text-h3-letter-spacing, 0); }
.prose h4 { font-size: var(--text-h4-size); font-weight: var(--text-h4-weight, 600); line-height: var(--text-h4-line-height, 1.3); }
.prose h5 { font-size: var(--text-h5-size); font-weight: var(--text-h5-weight, 600); line-height: var(--text-h5-line-height, 1.4); }
.prose h6 { font-size: var(--text-h6-size); font-weight: var(--text-h6-weight, 600); line-height: var(--text-h6-line-height, 1.4); }
/* h1 inside content is a warning in the contract; render it as an h2 so it never outranks the page title. */
.prose h1 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, min(var(--text-h2-size), 2.75rem)); font-weight: var(--text-h2-weight, 700); line-height: var(--text-h2-line-height, 1.2); }

.prose a:not(.wp-block-button__link) {
  color: var(--content-link);
  font-weight: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
  text-decoration-color: color-mix(in oklab, var(--content-link) 50%, transparent);
  transition: color 120ms ease, text-decoration-color 120ms ease;
}
.prose a:not(.wp-block-button__link):hover {
  color: var(--content-link-hover);
  text-decoration-color: currentColor;
}
.prose a:focus-visible {
  outline: 2px solid var(--content-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.prose strong { color: var(--content-heading); font-weight: 600; }
.prose em { font-style: italic; }
.prose mark { background: color-mix(in oklab, var(--content-accent) 22%, transparent); color: inherit; padding: 0 0.15em; }

/* Inline code: a quiet box, never a pill (daisyUI's bridge applies --radius-selector here). */
.prose :where(code):not(pre > code),
:root .prose :where(code):not(pre > code) {
  font-family: var(--font-mono);
  font-size: 0.875em;
  font-weight: 500;
  color: var(--content-code-fg);
  background: var(--content-code-bg);
  border: 0;
  border-radius: var(--content-radius);
  padding: 0.15em 0.4em;
}
.prose kbd {
  font-family: var(--font-mono);
  font-size: 0.8em;
  color: var(--content-heading);
  background: var(--content-surface);
  border: 1px solid var(--content-rule-strong);
  border-bottom-width: 2px;
  border-radius: var(--content-radius);
  padding: 0.1em 0.4em;
}

/* ------------------------------------------------------------------ */
/* 4. Lists                                                            */
/* ------------------------------------------------------------------ */
.prose ul { list-style-type: disc; }
.prose ol { list-style-type: decimal; }
.prose ul ul { list-style-type: circle; }
.prose li::marker { color: var(--content-muted); }
.prose li > p { margin-top: 0.5em; margin-bottom: 0.5em; }

/* ------------------------------------------------------------------ */
/* 5. Block bridge                                                     */
/* ------------------------------------------------------------------ */

/* Quote */
.prose blockquote.wp-block-quote {
  border-inline-start: 3px solid var(--content-rule-strong);
  padding-inline-start: 1.25em;
  color: var(--content-heading);
  font-style: italic;
  font-weight: 400;
}
.prose blockquote.wp-block-quote p:first-of-type::before,
.prose blockquote.wp-block-quote p:last-of-type::after { content: none; }
.prose blockquote.wp-block-quote cite {
  display: block;
  margin-top: 0.75em;
  font-style: normal;
  font-size: 0.875em;
  color: var(--content-muted);
}
.prose blockquote.wp-block-quote cite::before { content: "— "; }

/* Pullquote: core gives 4em of padding and centred text; make it a rule-bounded statement. */
.prose figure.wp-block-pullquote {
  padding: 1.5em 0;
  margin: 2em 0;
  border-top: 1px solid var(--content-rule-strong);
  border-bottom: 1px solid var(--content-rule-strong);
  text-align: center;
}
.prose figure.wp-block-pullquote blockquote { border: 0; padding: 0; margin: 0; }
.prose figure.wp-block-pullquote p {
  font-family: var(--font-heading);
  font-size: 1.35em;
  line-height: 1.35;
  font-weight: 500;
  font-style: normal;
  color: var(--content-heading);
  margin: 0;
  text-wrap: balance;
}
.prose figure.wp-block-pullquote cite {
  display: block;
  margin-top: 0.75em;
  font-size: 0.875em;
  font-style: normal;
  color: var(--content-muted);
}

/* Table: one design. Core draws a grid on every cell; the typography layer draws rules. Keep rules. */
.prose figure.wp-block-table { margin: 2em 0; overflow-x: auto; }
.prose figure.wp-block-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9em;
  line-height: 1.5;
}
.prose .wp-block-table th,
.prose .wp-block-table td {
  border: 0;
  border-bottom: 1px solid var(--content-rule);
  padding: 0.6em 0.75em;
  text-align: start;
  vertical-align: top;
}
.prose .wp-block-table thead th {
  border-bottom: 2px solid var(--content-rule-strong);
  color: var(--content-heading);
  font-weight: 600;
  vertical-align: bottom;
}
.prose .wp-block-table th:first-child,
.prose .wp-block-table td:first-child { padding-inline-start: 0; }
.prose .wp-block-table th:last-child,
.prose .wp-block-table td:last-child { padding-inline-end: 0; }
.prose .wp-block-table tbody tr:last-child td { border-bottom-color: var(--content-rule-strong); }
.prose .wp-block-table.is-style-stripes tbody tr:nth-child(odd) td { background: var(--content-surface); }

/* Code block / preformatted */
.prose pre {
  font-family: var(--font-mono);
  font-size: 0.875em;
  line-height: 1.6;
  color: var(--content-pre-fg);
  background: var(--content-pre-bg);
  border-radius: var(--content-radius);
  padding: 1em 1.25em;
  overflow-x: auto;
  margin: 1.75em 0;
}
.prose pre code { background: none; border: 0; padding: 0; color: inherit; font-size: inherit; font-weight: inherit; }
.prose pre.wp-block-preformatted { white-space: pre-wrap; }

/* Separator: one thin rule, no core 2px, no opacity games. */
.prose hr.wp-block-separator {
  border: 0;
  border-top: 1px solid var(--content-rule-strong);
  margin: 3em 0;
  opacity: 1;
  width: 100%;
}
.prose hr.wp-block-separator.is-style-wide { width: 100%; }
.prose hr.wp-block-separator.is-style-dots { border: 0; text-align: center; }

/* Figures: image, video, embed, gallery share one rhythm and one caption.
   Default sizing: a picture fills the measure so mixed sizes line up;
   alignleft / alignright / aligncenter are the deliberate exceptions. */
.prose figure.wp-block-image,
.prose figure.wp-block-video,
.prose figure.wp-block-embed,
.prose figure.wp-block-gallery {
  margin: 2em 0;
}
.prose figure.wp-block-image img,
.prose figure.wp-block-video video {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--content-radius);
}
.prose figure.wp-block-image:not(.alignleft):not(.alignright):not(.aligncenter) > img,
.prose figure.wp-block-image:not(.alignleft):not(.alignright):not(.aligncenter) > a > img,
.prose figure.wp-block-video:not(.alignleft):not(.alignright):not(.aligncenter) video {
  width: 100%;
}
.prose figure.wp-block-image.aligncenter > img,
.prose figure.wp-block-image.aligncenter > a > img { margin-inline: auto; }
.prose figure.wp-block-image.alignleft { float: left; margin: 0.5em 1.5em 1em 0; max-width: 50%; }
.prose figure.wp-block-image.alignright { float: right; margin: 0.5em 0 1em 1.5em; max-width: 50%; }
.prose figure.wp-block-image.aligncenter { margin-inline: auto; text-align: center; }
.prose figcaption,
.prose .wp-element-caption {
  color: var(--content-muted);
  font-size: 0.875em;
  line-height: 1.45;
  margin: 0.6em 0 0;
  text-align: start;
}
.prose figure.wp-block-image.aligncenter figcaption,
.prose figure.wp-block-pullquote figcaption { text-align: center; }
.prose figure.wp-block-embed .wp-block-embed__wrapper { border-radius: var(--content-radius); overflow: hidden; }
.prose figure.wp-block-embed.wp-has-aspect-ratio .wp-block-embed__wrapper { position: relative; }
.prose figure.wp-block-embed.wp-embed-aspect-16-9 .wp-block-embed__wrapper::before { content: ""; display: block; padding-top: 56.25%; }
.prose figure.wp-block-embed.wp-embed-aspect-4-3 .wp-block-embed__wrapper::before { content: ""; display: block; padding-top: 75%; }
.prose figure.wp-block-embed.wp-has-aspect-ratio .wp-block-embed__wrapper iframe { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Buttons: the site's primary button, not core's grey. */
.prose .wp-block-buttons { display: flex; flex-wrap: wrap; gap: 0.75em; margin: 1.75em 0; }
.prose .wp-block-buttons.is-content-justification-center { justify-content: center; }
.prose .wp-block-buttons.is-content-justification-right { justify-content: flex-end; }
.prose .wp-block-button { margin: 0; }
.prose .wp-block-button__link,
:root .prose :where(.wp-element-button, .wp-block-button__link) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  width: auto;
  min-height: 2.75em;
  padding: 0.6em 1.4em;
  font-family: var(--font-heading);
  font-size: 0.95em;
  font-weight: 600;
  line-height: 1.2;
  color: var(--content-button-fg);
  background: var(--content-button-bg);
  border: 1px solid var(--content-button-bg);
  border-radius: var(--content-button-radius);
  text-decoration: none;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.prose .wp-block-button__link:hover {
  background: color-mix(in oklab, var(--content-button-bg) 88%, var(--color-base-content));
  border-color: color-mix(in oklab, var(--content-button-bg) 88%, var(--color-base-content));
  color: var(--content-button-fg);
}
.prose .wp-block-button.is-style-outline .wp-block-button__link,
:root .prose :where(.wp-block-button.is-style-outline .wp-block-button__link),
:root .prose :where(.wp-block-button[class*="is-style-outline"] .wp-block-button__link) {
  background: transparent;
  color: var(--content-button-bg);
  border: 1px solid var(--content-button-bg);
  padding: 0.6em 1.4em;
}
.prose .wp-block-button.is-style-outline .wp-block-button__link:hover {
  background: color-mix(in oklab, var(--content-button-bg) 10%, transparent);
}
.prose .wp-block-button__link:focus-visible { outline: 2px solid var(--content-accent); outline-offset: 2px; }

/* Details: a bordered disclosure with a real affordance. */
.prose details.wp-block-details {
  border: 1px solid var(--content-rule);
  border-radius: var(--content-radius);
  padding: 0;
  margin: 1.25em 0;
  background: transparent;
}
.prose details.wp-block-details > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.85em 1em 0.85em 2.4em;
  position: relative;
  font-weight: 600;
  color: var(--content-heading);
}
.prose details.wp-block-details > summary::-webkit-details-marker { display: none; }
.prose details.wp-block-details > summary::before {
  content: "";
  position: absolute;
  left: 1em;
  top: 50%;
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid var(--content-muted);
  border-bottom: 2px solid var(--content-muted);
  transform: translateY(-65%) rotate(-45deg);
  transition: transform 150ms ease;
}
.prose details.wp-block-details[open] > summary::before { transform: translateY(-65%) rotate(45deg); }
.prose details.wp-block-details[open] > summary { border-bottom: 1px solid var(--content-rule); }
.prose details.wp-block-details > :not(summary) { margin-inline: 1em; }
.prose details.wp-block-details > :not(summary):first-of-type { margin-top: 0.85em; }
.prose details.wp-block-details > :not(summary):last-child { margin-bottom: 0.85em; }

/* ------------------------------------------------------------------ */
/* 6. Image styles — the content_images knob                           */
/* Body class content-images-<name>, resolved template → page → style  */
/* default (Plexa_Content_Style::image_styles()). Applies to image,     */
/* gallery, video and embed figures; captions follow each treatment.    */
/* ------------------------------------------------------------------ */
.prose {
  --content-image-radius: var(--content-radius);
  --content-bleed: 4rem;
}

/* plain: square, quiet, caption below. */
.content-images-plain .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) :is(img, video, .wp-block-embed__wrapper) {
  border-radius: 0;
  box-shadow: none;
}

/* rounded: the theme radius (the base default). */
.content-images-rounded .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) :is(img, video, .wp-block-embed__wrapper) {
  border-radius: var(--content-image-radius);
}

/* framed: a mounted print — thin rule, a little mat, square corners. */
.content-images-framed .prose :is(figure.wp-block-image, figure.wp-block-video) :is(img, video) {
  border-radius: 0;
  padding: 0.5rem;
  background: var(--content-surface);
  border: 1px solid var(--content-rule-strong);
  box-sizing: border-box;
}
.content-images-framed .prose figure.wp-block-embed .wp-block-embed__wrapper {
  border-radius: 0;
  border: 1px solid var(--content-rule-strong);
  padding: 0.5rem;
  background: var(--content-surface);
}
.content-images-framed .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) figcaption {
  margin-top: 0.75em;
}

/* card: soft lift, caption inside the card. */
.prose {
  --content-card-bg: color-mix(in oklab, var(--color-base-content) 6%, var(--color-base-100));
  --content-card-border: var(--content-rule); /* same rule as the details block */
}
.content-images-card .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) {
  background: var(--content-card-bg);
  border-radius: calc(var(--content-image-radius) * 1.5 + 2px);
  box-shadow: 0 1px 2px color-mix(in oklch, var(--color-neutral) 6%, transparent), 0 12px 28px -14px color-mix(in oklch, var(--color-neutral) 35%, transparent);
  overflow: hidden;
  display: table; /* shrink-wraps to the image width so the card never floats wider than its picture */
  max-width: 100%;
}
.content-images-card .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) :is(img, video, .wp-block-embed__wrapper) {
  border-radius: 0;
  display: block;
}
.content-images-card .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) figcaption {
  display: table-caption;
  caption-side: bottom;
  margin: 0;
  padding: 0.7em 1em 0.9em;
  background: var(--content-card-bg);
  border: 1px solid var(--content-card-border); /* the caption area is the bordered box; the picture keeps its clean edge */
  border-radius: 0 0 calc(var(--content-image-radius) * 1.5 + 2px) calc(var(--content-image-radius) * 1.5 + 2px);
  color: var(--content-muted);
}
.content-images-card .prose figure.wp-block-image.aligncenter { margin-inline: auto; }

/* wide: pictures take the whole content column (the article is a size
   container), while the measure keeps the text and captions. Falls back to a
   fixed bleed to the right where container units are unsupported. */
article.plexa-post-content { container-type: inline-size; }
.content-images-wide .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed, figure.wp-block-gallery):not(.alignleft):not(.alignright) {
  width: calc(100% + var(--content-bleed));
  max-width: none;
  margin-inline: 0;
}
@supports (width: 100cqw) {
  .content-images-wide .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed, figure.wp-block-gallery):not(.alignleft):not(.alignright) {
    width: 100cqw;
  }
}
.content-images-wide .prose :is(figure.wp-block-image, figure.wp-block-video):not(.alignleft):not(.alignright) :is(img, video) {
  width: 100%;
  border-radius: var(--content-image-radius);
}
.content-images-wide .prose figure.wp-block-embed .wp-block-embed__wrapper { border-radius: var(--content-image-radius); }
.content-images-wide .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed):not(.alignleft):not(.alignright) figcaption {
  max-width: var(--content-measure);
}
@media (max-width: 900px) {
  .prose { --content-bleed: 1rem; }
}

/* ------------------------------------------------------------------ */
/* 2b. Galleries are not body copy                                     */
/* ------------------------------------------------------------------ */
/* The measure above bounds LINE LENGTH, and a grid of images has no lines
   to bound. Left clamped to it, a six-column gallery renders six thumbnails
   inside a 68ch column — the container deciding the layout, not the author.
   So a gallery takes the post-content column instead, by the same escape the
   wide image treatment uses twenty lines up: 100cqw against
   article.plexa-post-content, which already declares container-type:
   inline-size. The percentage form is the fallback where container units are
   not supported.

   Not gated on .content-images-wide. That class is a choice about how body
   images are TREATED; this is not a treatment, it is what a gallery is.

   The header travels with the grid. Rendered as a sibling before it, it would
   otherwise stay at the measure and sit centred over a wider grid, which
   reads as a misalignment rather than a decision. */
.prose :is(.image-gallery, .image-gallery__header) {
  max-width: none;
  width: calc(100% + var(--content-bleed));
  margin-inline: calc(var(--content-bleed) / -2);
}
/* The measure is CENTRED in the post-content column, so a child that simply
   takes 100cqw starts at the measure's inset left edge and overflows the right
   by exactly that inset. The negative margin pulls it back by half the
   difference, which centres it on the column instead. Measured, not assumed:
   the first version used margin-inline: 0 and ran off the right of the page. */
@supports (width: 100cqw) {
  .prose :is(.image-gallery, .image-gallery__header) {
    width: 100cqw;
    margin-inline: calc(50% - 50cqw);
  }
}

/* banner: full column width at a short fixed ratio (content_image_ratio,
   default 4:1), cover-cropped around the picture's focal point. The focal
   point comes from the media evaluation (--focal-x/--focal-y set on the figure
   by the render filter); without one the crop centres. */
.prose { --content-image-ratio: 4 / 1; }
.content-image-ratio-3-1 .prose { --content-image-ratio: 3 / 1; }
.content-image-ratio-4-1 .prose { --content-image-ratio: 4 / 1; }
.content-image-ratio-16-9 .prose { --content-image-ratio: 16 / 9; }
.content-image-ratio-3-2 .prose { --content-image-ratio: 3 / 2; }
.content-images-banner .prose figure.wp-block-image:not(.alignleft):not(.alignright) {
  width: 100cqw;
  max-width: none;
  margin-inline: 0;
}
.content-images-banner .prose figure.wp-block-image:not(.alignleft):not(.alignright) > img,
.content-images-banner .prose figure.wp-block-image:not(.alignleft):not(.alignright) > a > img {
  width: 100%;
  aspect-ratio: var(--content-image-ratio);
  object-fit: cover;
  object-position: var(--focal-x, 50%) var(--focal-y, 50%);
  border-radius: var(--content-image-radius);
}
.content-images-banner .prose figure.wp-block-image:not(.alignleft):not(.alignright) figcaption { max-width: var(--content-measure); }

/* tinted: brand duotone that lifts on hover, for mismatched stock photos. */
.content-images-tinted .prose figure.wp-block-image {
  display: grid;
  width: fit-content; /* the overlay must match the picture, not the measure */
  max-width: 100%;
  isolation: isolate;
}
.content-images-tinted .prose figure.wp-block-image.aligncenter { margin-inline: auto; }
.content-images-tinted .prose figure.wp-block-image > :first-child {
  grid-area: 1 / 1;
}
.content-images-tinted .prose figure.wp-block-image > :first-child img,
.content-images-tinted .prose figure.wp-block-image > img {
  filter: grayscale(1) contrast(1.05);
  border-radius: var(--content-image-radius);
  transition: filter 240ms ease;
}
.content-images-tinted .prose figure.wp-block-image::before {
  content: "";
  grid-area: 1 / 1;
  z-index: 1;
  pointer-events: none;
  background: var(--content-accent);
  mix-blend-mode: color;
  opacity: 0.85;
  border-radius: var(--content-image-radius);
  transition: opacity 240ms ease;
}
.content-images-tinted .prose figure.wp-block-image:hover::before { opacity: 0; }
.content-images-tinted .prose figure.wp-block-image:hover img { filter: none; }
.content-images-tinted .prose figure.wp-block-image figcaption { grid-area: 2 / 1; }
@media (prefers-reduced-motion: reduce) {
  .content-images-tinted .prose figure.wp-block-image::before,
  .content-images-tinted .prose figure.wp-block-image img { transition: none; }
}

/* ------------------------------------------------------------------ */
/* 7. Captions — the content_captions knob                             */
/* Body class content-captions-<name>: off | below (default) | overlay */
/* | side. Alt text is untouched by all of them.                       */
/* ------------------------------------------------------------------ */
.content-captions-off .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed, figure.wp-block-gallery) figcaption {
  display: none;
}

/* overlay: a gradient strip over the bottom of the picture. */
.content-captions-overlay .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) {
  position: relative;
}
.content-captions-overlay .prose :is(figure.wp-block-image, figure.wp-block-video, figure.wp-block-embed) figcaption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  margin: 0;
  padding: 2.2em 1em 0.8em;
  color: #F5F5F7;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
  border-radius: 0 0 var(--content-image-radius) var(--content-image-radius);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  z-index: 2;
}
.content-captions-overlay.content-images-card .prose figure figcaption {
  border: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
  color: #F5F5F7;
}
.content-captions-overlay.content-images-tinted .prose figure.wp-block-image figcaption { grid-area: 1 / 1; align-self: end; }

/* side: the caption sits in the margin beside the picture on wide screens. */
@media (min-width: 1100px) {
  .content-captions-side .prose figure.wp-block-image:not(.alignleft):not(.alignright):has(figcaption) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 11rem;
    column-gap: 1.25rem;
    align-items: end;
    width: calc(100% + 12.25rem);
    max-width: none;
  }
  .content-captions-side .prose figure.wp-block-image:not(.alignleft):not(.alignright) figcaption {
    margin: 0;
    font-size: 0.8em;
    line-height: 1.45;
    max-width: none;
  }
  .content-captions-side.content-images-card .prose figure.wp-block-image { display: table; width: auto; }
  .content-captions-side.content-images-card .prose figure.wp-block-image figcaption { display: table-caption; }
}

/* Group and columns: layout blocks stay out of the measure's way. */
.prose .wp-block-group,
.prose .wp-block-columns { max-width: none; }
.prose .wp-block-columns { display: flex; gap: 1.5em; flex-wrap: wrap; }
.prose .wp-block-column { flex: 1 1 15rem; min-width: 0; }
.prose .wp-block-column > :first-child { margin-top: 0; }
.prose .wp-block-column > :last-child { margin-bottom: 0; }

/* First and last child never add outer space to the wrapper. */
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .prose a, .prose .wp-block-button__link, .prose details.wp-block-details > summary::before { transition: none; }
}

/* Post meta ran together as one word.
   Plexa_Post_Content_Component::render_meta() emits the author, the date and
   the categories as adjacent inline elements with no separator and nothing
   spacing them, so a post rendered "March 4, 2026Commercial Pest Control".
   Found on the single-post structure page, 2026-09-15; it affects every page
   using the default single entry, not just that one. */
.post-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.75rem;
}

.post-meta > * + *::before {
    content: '·';
    margin-right: 0.75rem;
    opacity: 0.55;
}

/* The tag list ran together as one word, the same defect .post-meta above had
   and the same fix. Plexa_Post_Content_Component emits each term as an
   adjacent <a class="post-tag"> with nothing between them and nothing styling
   them, so a post ended with
   "american cockroach treatmentcockroach eliminationgerman cockroach…".
   Missed when .post-meta was fixed on 2026-09-15; found on the single-post
   structure page, and it affects every page that turns show_tags on. */
.post-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.post-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.75rem;
    font-size: var(--text-size-sm);
    color: var(--color-base-content);
    background: var(--color-base-200);
    border-radius: var(--radius-full, 9999px);
    text-decoration: none;
}

/* A contents-list link jumps to a heading. Without this the page teleports and
   the reader loses their place; with it the article travels and they can see
   where they went. scroll-padding keeps the target clear of the sticky header
   rather than under it. Honours a reduced-motion preference — the whole point
   of smooth scrolling is motion, so the preference is the one case where the
   jump is correct. */
html {
    scroll-padding-top: 6rem;
}

@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}
