/**
 * pagereal-article.css
 *
 * Standalone article content stylesheet. Defines its own design tokens — does NOT
 * inherit from the host environment (Next.js admin or WordPress theme). Load this
 * file in any surface that renders PageReal article HTML and the output will be
 * visually identical. Scope: everything inside .pr-article.
 *
 * Fonts loaded separately (caller's responsibility):
 *   Playfair Display (serif) — headlines
 *   Inter (sans)             — body, UI
 */

/* ─── Own design tokens ─────────────────────────────────────────────────────── */
.pr-article {
  /* Brand colors */
  --pr-coral:        #BA4923;
  --pr-coral-deep:   #993C1D;
  --pr-coral-dark:   #712B13;
  --pr-coral-tint:   #FAECE7;
  --pr-cream:        #FBF3EF;
  --pr-amber:        #EF9F27;
  --pr-amber-tint:   #FAEEDA;
  --pr-amber-dark:   #633806;

  /* Page surfaces */
  --pr-page-bg:      #FDFBF8;
  --pr-surface-tint: #F6F1E8;
  --pr-surface-alt:  #F1ECE3;

  /* Text */
  --pr-text-primary:   #1A1A1A;
  --pr-text-body:      #2A2825;
  --pr-text-secondary: #6B6862;
  --pr-text-tertiary:  #716D65;

  /* Borders */
  --pr-border:       #ECE7DF;
  --pr-border-alt:   #E5E0D8;

  /* Typography */
  --pr-font-serif:   'Playfair Display', Georgia, 'Times New Roman', serif;
  --pr-font-sans:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ─── Container reset ────────────────────────────────────────────────────────── */
.pr-article *,
.pr-article *::before,
.pr-article *::after {
  box-sizing: border-box;
}

.pr-article {
  font-family: var(--pr-font-sans);
  font-size: 16px;
  line-height: 1.75;
  color: var(--pr-text-body);
  background: var(--pr-page-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ─── Article layout ─────────────────────────────────────────────────────────── */
.pr-article__inner {
  max-width: 680px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Gift guide gets a slightly wider column for product cards */
.pr-article--gift-guide .pr-article__inner {
  max-width: 760px;
}

/* ─── Header chrome ──────────────────────────────────────────────────────────── */
.pr-article__header {
  padding: 40px 0 24px;
  border-bottom: 1px solid var(--pr-border);
  margin-bottom: 32px;
}

.pr-article__category {
  display: inline-block;
  font-family: var(--pr-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pr-coral);
  margin-bottom: 12px;
}

.pr-article__headline {
  font-family: var(--pr-font-serif);
  font-size: clamp(34px, 5.5vw, 50px);
  font-weight: 700;
  line-height: 1.15;
  color: var(--pr-text-primary);
  margin: 0 0 16px;
  letter-spacing: -0.015em;
}

.pr-article__dek {
  font-family: var(--pr-font-sans);
  font-size: 18px;
  line-height: 1.55;
  color: var(--pr-text-secondary);
  margin: 0 0 20px;
  font-weight: 400;
}

/* ─── Byline ─────────────────────────────────────────────────────────────────── */
.pr-article__byline {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--pr-text-secondary);
}

.pr-article__byline-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pr-coral-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--pr-coral-deep);
  flex-shrink: 0;
}

.pr-article__byline-author {
  font-weight: 500;
  color: var(--pr-text-primary);
}

.pr-article__byline-meta {
  color: var(--pr-text-tertiary);
}

.pr-article__byline-meta span + span::before {
  content: ' · ';
}

/* Gift guide affiliate disclosure — subtle, FTC-compliant */
.pr-article__disclosure {
  font-size: 12px;
  font-style: italic;
  color: var(--pr-text-tertiary);
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--pr-border);
}

/* ─── Featured image ─────────────────────────────────────────────────────────── */
.pr-article__featured-image {
  margin: 0 0 32px;
}

/* height:auto is load-bearing, not boilerplate.
   the_post_thumbnail() emits width/height attributes — 1024x576 for the large
   size — and those attributes are presentational hints, which any author rule
   overrides. Setting width without height means the width rule lands and the
   height hint survives, so the box becomes 100%-wide by a FIXED 576px tall.
   Default object-fit is `fill`, so the image is stretched to match rather than
   cropped. On desktop the container happens to be ~1040px and 1040x576 is
   close enough to 16:9 that nothing looks wrong; at a 343px mobile column the
   same rule renders a landscape photo into a portrait box and stretches it
   roughly 3x vertically. Measured on the live article before this fix:
   rendered aspect 0.60 against a source aspect of 1.78. */
.pr-article__featured-image img {
  width: 100%;
  height: auto;
  border-radius: 6px;
  display: block;
}

.pr-article__featured-image figcaption {
  font-size: 12px;
  color: var(--pr-text-tertiary);
  margin-top: 8px;
  line-height: 1.45;
}

/* ─── Body image slot placeholder (not yet generated) ──────────────────────────── */
.article-image-slot {
  margin: 1.3rem 0;
}

.pr-image-placeholder {
  background: var(--pr-surface-tint);
  border-radius: 6px;
  padding: 32px 24px;
  text-align: center;
  font-size: 12px;
  color: var(--pr-text-tertiary);
  font-style: italic;
  line-height: 1.5;
}

/* ─── Body content ───────────────────────────────────────────────────────────── */
.pr-article__body {
  font-size: 17px;
  line-height: 1.78;
  color: var(--pr-text-body);
}

.pr-article__body p {
  margin: 0 0 1.2em;
}

/* Section divider: a rule + top margin ahead of each h2, so a new section
   reads as a new "chapter" — dialed back from the original pass, which ran
   too much whitespace, but keeping the divider so sections still read as
   distinct breaks, not just a bigger line of text. */
.pr-article__body h2 {
  font-family: var(--pr-font-serif);
  font-size: 29px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--pr-text-primary);
  margin: 1.8em 0 0.5em;
  padding-top: 1.1em;
  border-top: 1px solid var(--pr-border);
  letter-spacing: -0.01em;
  scroll-margin-top: 24px;
}

.pr-article__body h3 {
  font-family: var(--pr-font-sans);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--pr-text-primary);
  margin: 1.3em 0 0.4em;
}

/* MARKERS ARE DECLARED, NOT INHERITED.
   These relied on the browser default for list-style, which is fine on
   WordPress but not in the admin: globals.css resets `ul, ol { list-style:
   none }` app-wide, so article lists rendered with bullets on the published
   page and as bare indented text in review — the same article looking like two
   different articles, which is the divergence this stylesheet exists to
   prevent. Stated explicitly so no host reset can change what an editor sees.
   Components that deliberately suppress markers (the TOC, chart rows, How-To
   steps) still do so; those rules come later and win. */
.pr-article__body ul,
.pr-article__body ol {
  margin: 0 0 1.4em;
  padding-left: 1.5em;
}

.pr-article__body ul { list-style: disc outside; }
.pr-article__body ol { list-style: decimal outside; }

.pr-article__body li {
  display: list-item;
  margin-bottom: 0.4em;
}

.pr-article__body a {
  color: var(--pr-coral);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.pr-article__body a:hover {
  color: var(--pr-coral-deep);
}

.pr-article__body strong {
  font-weight: 600;
  color: var(--pr-text-primary);
}

.pr-article__body em {
  font-style: italic;
}

/* Data table — emitted by the trusted table renderer (ai-core renderers/
   table-renderer.ts), never by the model. One .pr-representations block groups
   the article's grounded tables; each .pr-data-table is a two-tone comparison
   grid. Shared verbatim by the admin preview and the WordPress theme. */
.pr-article__body .pr-representations {
  margin: 1.8em 0;
  display: grid;
  gap: 1.6em;
}

.pr-article__body .pr-data-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--pr-font-sans);
  font-size: 15px;
  line-height: 1.45;
  display: block;
  overflow-x: auto;
}

.pr-article__body .pr-data-table caption {
  caption-side: top;
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pr-text-tertiary);
  padding-bottom: 0.6em;
}

.pr-article__body .pr-data-table thead th {
  text-align: left;
  background: var(--pr-surface-alt);
  color: var(--pr-text-primary);
  font-weight: 600;
  padding: 10px 14px;
  border-bottom: 2px solid var(--pr-border);
}

.pr-article__body .pr-data-table thead th:not(:first-child) {
  text-align: right;
}

.pr-article__body .pr-data-table tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--pr-text-body);
  padding: 10px 14px;
  border-bottom: 1px solid var(--pr-border-alt);
}

.pr-article__body .pr-data-table tbody td {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--pr-text-primary);
  padding: 10px 14px;
  border-bottom: 1px solid var(--pr-border-alt);
}

.pr-article__body .pr-data-table tbody tr:last-child th,
.pr-article__body .pr-data-table tbody tr:last-child td {
  border-bottom: none;
}

.pr-article__body .pr-data-table tbody tr.is-highlighted {
  background: var(--pr-amber-tint);
}

/* Bar chart — emitted by the trusted chart renderer (ai-core renderers/
   chart-renderer.ts). Deliberately markup rather than SVG so it survives
   sanitization, reflows on narrow screens, and stays readable to screen readers:
   every bar repeats its value as text, so meaning never lives in geometry alone.
   Shared verbatim by the admin preview and the WordPress theme. */
.pr-article__body .pr-chart {
  margin: 1.8em 0;
  padding: 0;
}

.pr-article__body .pr-chart figcaption {
  font-family: var(--pr-font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pr-text-tertiary);
  margin-bottom: 0.9em;
}

.pr-article__body .pr-chart__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.pr-article__body .pr-chart__row {
  display: grid;
  grid-template-columns: minmax(0, 12em) 1fr auto;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: var(--pr-font-sans);
  font-size: 14px;
}

.pr-article__body .pr-chart__label {
  color: var(--pr-text-body);
  line-height: 1.35;
}

.pr-article__body .pr-chart__track {
  display: block;
  background: var(--pr-surface-alt);
  border-radius: 3px;
  overflow: hidden;
  min-width: 40px;
}

.pr-article__body .pr-chart__bar {
  display: block;
  height: 18px;
  background: var(--pr-coral);
  border-radius: 3px;
}

.pr-article__body .pr-chart__row.is-highlighted .pr-chart__bar {
  background: var(--pr-coral-deep);
}

.pr-article__body .pr-chart__value {
  color: var(--pr-text-primary);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

.pr-article__body .pr-chart__unit {
  color: var(--pr-text-tertiary);
  font-weight: 400;
  font-size: 12px;
}

/* Narrow screens: label above its bar so long editorial labels stay readable. */
@media (max-width: 600px) {
  .pr-article__body .pr-chart__row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "label label" "track value";
    gap: 6px 10px;
  }
  .pr-article__body .pr-chart__label { grid-area: label; }
  .pr-article__body .pr-chart__track { grid-area: track; }
  .pr-article__body .pr-chart__value { grid-area: value; }
}

/* Pull quote — breaks from the body column: centered, oversized serif italic,
   bracketed by rules instead of a plain left border, for real magazine weight. */
.pr-article__body blockquote {
  margin: 1.8em auto;
  max-width: 480px;
  padding: 16px 8px;
  border: none;
  border-top: 2px solid var(--pr-coral);
  border-bottom: 2px solid var(--pr-coral);
  font-family: var(--pr-font-serif);
  font-size: 27px;
  line-height: 1.4;
  color: var(--pr-text-primary);
  font-style: italic;
  text-align: center;
  letter-spacing: -0.005em;
}

.pr-article__body blockquote p {
  margin: 0;
}

/* Cost/comparison tables */
.pr-article__body table {
  width: 100%;
  margin: 1.8em 0;
  border-collapse: collapse;
  font-family: var(--pr-font-sans);
  font-size: 15px;
}

.pr-article__body th,
.pr-article__body td {
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--pr-border);
}

.pr-article__body th {
  font-weight: 600;
  color: var(--pr-text-primary);
  background: var(--pr-surface-tint);
  border-bottom: 2px solid var(--pr-coral);
}

.pr-article__body td {
  color: var(--pr-text-body);
}

.pr-article__body tr:last-child td {
  border-bottom: none;
}

/* In-body images */
.pr-article__body figure,
.pr-article__body .article-image-container {
  margin: 2em 0;
  text-align: center;
}

.pr-article__body figure img,
.pr-article__body .article-image-container img {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
}

.pr-article__body figure figcaption,
.pr-article__body .article-image-container figcaption {
  font-size: 12px;
  color: var(--pr-text-tertiary);
  margin-top: 8px;
  line-height: 1.45;
}

/* ─── Jump-to-section mini-TOC ───────────────────────────────────────────────── */
.pr-article__toc {
  margin: 4px 0 24px;
  padding: 18px 22px;
  border: 1px solid var(--pr-border);
  border-radius: 8px;
  background: var(--pr-surface-tint);
}

.pr-article__toc-label {
  font-family: var(--pr-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pr-coral);
  margin: 0 0 12px;
}

.pr-article__toc ol {
  list-style: none;
  counter-reset: toc-counter;
  margin: 0;
  padding: 0;
}

.pr-article__toc li {
  counter-increment: toc-counter;
  margin-bottom: 9px;
}

.pr-article__toc li:last-child {
  margin-bottom: 0;
}

.pr-article__toc li::before {
  content: counter(toc-counter) '.';
  display: inline-block;
  width: 20px;
  color: var(--pr-coral);
  font-weight: 600;
  font-size: 13px;
}

.pr-article__toc a {
  font-family: var(--pr-font-sans);
  font-size: 14px;
  color: var(--pr-text-primary);
  text-decoration: none;
}

.pr-article__toc a:hover {
  color: var(--pr-coral);
  text-decoration: underline;
}

/* ─── Ad slot placeholder ────────────────────────────────────────────────────── */
.pr-ad-slot {
  margin: 2.5em 0;
  background: var(--pr-surface-tint);
  border: 1px solid var(--pr-border-alt);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  color: var(--pr-text-tertiary);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.pr-ad-slot--leaderboard {
  height: 90px;
}

.pr-ad-slot--rectangle {
  height: 250px;
}

/* ─── Product card (gift guide) ──────────────────────────────────────────────── */
.pr-product-card {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  margin: 2em 0;
  padding: 20px;
  border: 1px solid var(--pr-border);
  border-radius: 8px;
  background: #fff;
}

.pr-product-card__image {
  width: 140px;
  flex-shrink: 0;
  border-radius: 6px;
  overflow: hidden;
  background: var(--pr-surface-tint);
}

.pr-product-card__image img {
  width: 100%;
  height: auto;
  display: block;
}

.pr-product-card__body {
  flex: 1;
  min-width: 0;
}

.pr-product-card__name {
  font-family: var(--pr-font-sans);
  font-size: 16px;
  font-weight: 600;
  color: var(--pr-text-primary);
  margin: 0 0 6px;
}

.pr-product-card__price {
  font-size: 18px;
  font-weight: 700;
  color: var(--pr-coral-deep);
  margin: 0 0 8px;
}

.pr-product-card__description {
  font-size: 14px;
  color: var(--pr-text-secondary);
  line-height: 1.55;
  margin: 0 0 16px;
}

.pr-product-card__cta {
  display: inline-block;
  padding: 9px 20px;
  background: var(--pr-coral);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  border-radius: 4px;
  transition: background 0.15s ease;
}

.pr-product-card__cta:hover {
  background: var(--pr-coral-deep);
  color: #fff;
}

/* The markup the pipeline ACTUALLY emits (see gift-guide-draft template) is a
   flat <div class="product-card"> with a bare <img> — not the .pr-product-card
   BEM structure above. These rules style the real thing; the img cap uses
   !important because the on-demand image injector historically baked
   `max-width: 100%` inline onto already-stored articles. */
.pr-article__body .product-card {
  margin: 2em 0;
  padding: 20px;
  border: 1px solid var(--pr-border);
  border-radius: 8px;
  background: #fff;
}

.pr-article__body .product-card img {
  max-width: 300px !important;
  width: 100% !important;
  height: auto;
  display: block;
  margin: 0 auto 16px;
  border-radius: 8px;
}

/* Stock-photo attribution line under an image (Unsplash terms require it).
   Body figcaptions are styled above; this covers the product-card credit,
   which sits in a div because the card's img has no <figure> parent. */
.pr-article__body .pr-image-credit {
  font-size: 12px;
  color: var(--pr-text-tertiary);
  text-align: center;
  margin: -8px 0 12px;
}

.pr-article__body .pr-image-credit a {
  color: var(--pr-text-tertiary);
  text-decoration: underline;
}

/* ─── Click-to-expand lightbox ───────────────────────────────────────────────
   Markup-free: pagereal-lightbox.js (WordPress theme) and ArticlePreview
   (admin) both delegate clicks on article images and build this overlay. */
.pr-article__body img,
.pr-article__featured-image img {
  cursor: zoom-in;
}

.pr-article__body .pr-image-placeholder,
.pr-article__body img[src*="placehold.co"] {
  cursor: default;
}

.pr-lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(20, 16, 12, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  cursor: zoom-out;
}

.pr-lightbox-overlay img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);
  cursor: zoom-out;
}

/* A discoverable way out. Escape and click-anywhere both close the overlay,
   but neither announces itself — a reader who opens an image and does not
   already know the convention has nothing on screen telling them how to get
   back to the article. */
.pr-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  line-height: 1;
  color: #fff;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
}

.pr-lightbox-close:hover {
  background: rgba(0, 0, 0, 0.7);
}

.pr-lightbox-close:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

/* The zoom trigger is a focus stop now, so it needs a focus ring. Without one
   a keyboard user tabbing through the article cannot see where they are. */
.pr-article__body img[data-pr-zoom]:focus-visible,
.pr-article__featured-image img[data-pr-zoom]:focus-visible {
  outline: 3px solid var(--pr-coral);
  outline-offset: 3px;
}

/* ─── Topic tags ─────────────────────────────────────────────────────────────── */
.pr-article__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 40px 0 32px;
  padding-top: 24px;
  border-top: 1px solid var(--pr-border);
}

.pr-article__tag {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 99px;
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  background: var(--pr-coral-tint);
  color: var(--pr-coral-dark);
}

/* ─── Share block ────────────────────────────────────────────────────────────── */
.pr-share-block {
  background: var(--pr-cream);
  border-radius: 8px;
  padding: 28px 24px;
  text-align: center;
  margin: 32px 0;
}

.pr-share-block__prompt {
  font-size: 15px;
  font-weight: 500;
  color: var(--pr-text-primary);
  margin: 0 0 16px;
}

.pr-share-block__buttons {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

.pr-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  border: none;
}

.pr-share-btn--primary {
  background: var(--pr-text-primary);
  color: #fff;
}

.pr-share-btn--secondary {
  background: transparent;
  color: var(--pr-text-primary);
  border: 1px solid var(--pr-border-alt);
}

.pr-share-btn--secondary:hover {
  background: var(--pr-surface-tint);
}

/* ─── Recommendation card ────────────────────────────────────────────────────── */
.pr-recommendations {
  background: var(--pr-surface-tint);
  border-radius: 8px;
  padding: 28px 24px;
  margin: 32px 0 48px;
}

.pr-recommendations__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pr-text-tertiary);
  margin: 0 0 20px;
}

.pr-recommendations__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.pr-rec-card {
  background: #fff;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--pr-border);
}

.pr-rec-card__image {
  width: 100%;
  aspect-ratio: 16/9;
  background: var(--pr-surface-alt);
  overflow: hidden;
}

.pr-rec-card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pr-rec-card__body {
  padding: 12px;
}

.pr-rec-card__category {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pr-coral);
  margin-bottom: 4px;
}

.pr-rec-card__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--pr-text-primary);
  line-height: 1.35;
  margin: 0 0 6px;
}

.pr-rec-card__meta {
  font-size: 11px;
  color: var(--pr-text-tertiary);
}

.pr-recommendations__stub {
  font-size: 13px;
  color: var(--pr-text-tertiary);
  font-style: italic;
  text-align: center;
  padding: 24px 0 8px;
}

/* ─── Mobile ─────────────────────────────────────────────────────────────────── */
@media (max-width: 600px) {
  .pr-article__inner {
    padding: 0 16px;
  }

  .pr-article__header {
    padding: 24px 0 20px;
  }

  .pr-article__headline {
    font-size: 26px;
  }

  .pr-article__dek {
    font-size: 16px;
  }

  .pr-article__body {
    font-size: 16px;
  }

  .pr-article__body h2 {
    font-size: 20px;
  }

  .pr-product-card {
    flex-direction: column;
  }

  .pr-product-card__image {
    width: 100%;
  }

  .pr-product-card__cta {
    display: block;
    text-align: center;
    width: 100%;
  }

  .pr-recommendations__grid {
    grid-template-columns: 1fr;
  }

  .pr-ad-slot--leaderboard {
    height: 250px; /* switch to rectangle on mobile */
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESENTATION LAYER — art direction without touching article content
   ═══════════════════════════════════════════════════════════════════════════

   Everything below changes EMPHASIS ONLY. It adds no text, no facts and no
   markup: every rule keys off structure that already exists in approved
   article HTML (`figure.article-image-slot`, `data-slot-index`, document
   order). Nothing here needs an article, an image or a prompt to be
   regenerated, and it applies identically to articles published before it
   existed.

   WHY THIS FILE. `admin/public/pagereal-article.css` is the single source of
   truth for article styling — `wordpress-theme/build-theme.sh` copies it
   verbatim into the theme at build time. Presentation logic therefore lives
   here and NOWHERE else, so the admin preview and the published page cannot
   drift. That is the same lesson Product Cards taught: one renderer, two
   surfaces.

   THE PROBLEM THIS SOLVES. Body images are emitted by the image-injection
   route with a hard-coded inline style — `max-width:440px; margin:8px auto`
   (admin/src/app/api/ai/generate-image/route.ts). Every body image is
   therefore the same width and centred, inside a 680px measure, forever. The
   repetition is baked into article HTML, not into CSS, so no ordinary
   stylesheet rule can vary it. Overriding that inline declaration is the one
   place `!important` is load-bearing rather than lazy, and it is scoped as
   narrowly as possible: body image-slot figures only.

   Deferred: teach the image route to stop emitting inline layout so these
   overrides can be dropped. Presentation must not depend on it — articles
   already published carry the inline style permanently. */

/* ─── Shared breakout ────────────────────────────────────────────────────────
   `.pr-article__inner` is a 680px centred column with 24px padding. A figure
   escapes it by re-centring on the viewport. Capped so a wide image never
   outgrows the page, and never wider than the viewport minus the gutter. */
.pr-article__body figure.article-image-slot,
.pr-article__featured-image {
  --pr-measure: 680px;
}

/* ─── HERO ───────────────────────────────────────────────────────────────────
   The hero was previously 100% of the 680px measure — the same width as the
   text, and only 240px wider than a body image. It read as "first picture",
   not as the article's opening image. Breaking it out of the measure is what
   makes it the first real visual reward. */
.pr-article__featured-image {
  width: min(100vw - 48px, 1040px);
  max-width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
  margin-bottom: 44px;
}

.pr-article__featured-image img {
  border-radius: 8px;
}

/* ─── BODY IMAGE GRAMMAR ─────────────────────────────────────────────────────
   Treatment is chosen by applyFigureGrammar() in article-structure.ts and
   arrives as a class on the figure. Both surfaces receive the same class from
   the same function, so the composition an editor approves is the composition
   a reader gets.

   The rules that render those classes are below. Only two things live here that
   the grammar cannot express: the inline cap override (next) and the
   containment guarantees. */

/* Neutralise the baked-in inline cap so the figure controls width. Scoped to
   body image slots; the `!important` targets exactly the inline declaration
   described above and nothing else. */
.pr-article__body figure.article-image-slot img {
  max-width: 100% !important;
  width: 100% !important;
  height: auto !important;
  margin: 0 !important;
  display: block;
  border-radius: 8px;
}

/* Rhythm: an image belongs to the section it sits in, so it keeps more space
   above it than below — it separates from the prose it follows, and stays
   attached to the prose it introduces. */
.pr-article__body figure.article-image-slot {
  margin: 2.2em 0 1.6em;
}

/* TREATMENT IS A CLASS, NOT A POSITION.
   This used to be `:nth-of-type` parity — deterministic but blind. An inline
   float is only safe when the section has enough prose to wrap past the image's
   bottom edge, and CSS cannot count words. applyFigureGrammar() decides and
   writes the class; these rules only render it. Both surfaces get the same
   class from the same function. */

/* WIDE — escapes the measure and gives the strong visual break between inline
   sections. Deliberately narrower than the hero: the hero stays unique. */
.pr-article__body figure.article-image-slot.pr-figure--wide {
  width: min(100vw - 48px, 900px);
  max-width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
  margin-top: 2.6em;
  margin-bottom: 2em;
}

/* INLINE — the prose wraps around it.
   42% of the measure keeps the figure editorially significant rather than a
   thumbnail, while leaving a text column wide enough to avoid ragged
   two-word lines. `shape-margin` keeps the gutter honest if a future image
   ever carries transparency. */
.pr-article__body figure.article-image-slot.pr-figure--inline-right,
.pr-article__body figure.article-image-slot.pr-figure--inline-left {
  width: 42%;
  max-width: 300px;
  margin-top: 0.35em;
  margin-bottom: 1.1em;
}

.pr-article__body figure.article-image-slot.pr-figure--inline-right {
  float: right;
  margin-left: 1.8em;
  shape-outside: margin-box;
}

.pr-article__body figure.article-image-slot.pr-figure--inline-left {
  float: left;
  margin-right: 1.8em;
  shape-outside: margin-box;
}

/* CONTAINMENT — a float must never leak into the next section.
   Two independent guarantees, because float bugs are the classic fragility
   here and one mechanism is not enough:
     1. every h2 clears both sides, so a new section always starts clean;
     2. the ad break and TOC clear too, so neither can end up beside a picture.
   `display: flow-root` on the body additionally makes the body itself a
   block-formatting context, so a trailing float can never escape the article. */
.pr-article__body {
  display: flow-root;
}

.pr-article__body h2,
.pr-article__body .pr-ad-break,
.pr-article__body .pr-article__toc {
  clear: both;
}

/* A list beside a float reads as a ragged column, and a procedure beside one is
   worse. A pullquote is worse still: it is a display element with its own
   centred measure, and squeezing it next to a picture destroys both. All of
   them clear, so they always get the full measure. */
.pr-article__body ol,
.pr-article__body ul,
.pr-article__body blockquote,
.pr-article__body .pr-representations,
.pr-article__body .pr-data-table,
.pr-article__body .pr-chart {
  clear: both;
}

/* ─── SECTION GROUPING ───────────────────────────────────────────────────────
   The h2 rule above already carries the hairline divider and its padding — this
   only widens the gap. Space BETWEEN sections was 1.8em+1.1em; against a 1.2em
   paragraph gap that is barely a beat, so consecutive sections read as one
   continuous scroll. Widening only the OUTER gap is what makes a section legible
   as a unit: nothing inside it moves. */
.pr-article__body h2 {
  margin-top: 2.6em;
  padding-top: 1.4em;
}

/* A subsection belongs to the section above it, so it stays closer to its
   parent than a new section does — h3 is deliberately tighter than h2. */
.pr-article__body h3 {
  margin-top: 1.9em;
  margin-bottom: 0.4em;
}

/* ─── LISTS ──────────────────────────────────────────────────────────────────
   Markers were the same weight and colour as body text, so a list read as
   indented prose. Giving the marker the brand coral and a heavier weight makes
   the list legible as a list at a glance, without changing a word of it. */
.pr-article__body ul,
.pr-article__body ol {
  padding-left: 1.35em;
  margin: 0 0 1.5em;
}

.pr-article__body li {
  margin-bottom: 0.55em;
  padding-left: 0.2em;
}

.pr-article__body li::marker {
  color: var(--pr-coral);
  font-weight: 700;
}

/* An ordered list is a sequence — in a How-To it is usually THE procedure, so
   its numbers earn a little more presence. This styles the list the article
   already has; it never promotes prose into steps. */
.pr-article__body ol > li::marker {
  font-family: var(--pr-font-sans);
  font-size: 0.95em;
}

/* ─── NEUTRAL AD BREAK ───────────────────────────────────────────────────────
   A provider-agnostic slot the renderer may fill. Article HTML carries only an
   empty marker — never an ad network's markup — so advertising stays a theme
   concern and the same article can be monetised differently later without any
   content change.

   Inserted by buildArticleStructure() immediately before the SECOND h2, which
   is what guarantees the reader has had the intro plus one whole section first.
   A top-level h2 is by definition not inside a procedure, a list or a product
   card, so the break cannot land in any of them.

   Until a provider is wired up it reserves its space quietly rather than
   showing a grey "Advertisement" box in an editor's face on every preview. */
.pr-article__body .pr-ad-break {
  min-height: 90px;
  margin: 2.2em 0;
}

/* Deliberately borderless while empty. It sits immediately before an h2, which
   already draws the section divider — bordering the break too stacked three
   hairlines in a row and read as a rendering fault rather than a reserved
   slot. A provider that fills it brings its own frame. */

/* An ad break has no business separating a heading from the section above it
   when it is the first thing in the body. */
.pr-article__body .pr-ad-break:first-child {
  display: none;
}

/* ─── FORMAT POLICIES ────────────────────────────────────────────────────────
   Small deterministic differences on the SAME primitives — not five layouts.
   The modifier class comes from formatModifierClass() in article-structure.ts
   and from pagereal_format_modifier_class() in the theme, which are the same
   mapping, so a format renders identically on both surfaces.

   Everything here is opt-in emphasis. No format hides content, reorders
   anything, or changes what an article says. */

/* HOW_TO — the procedure is the article.
   The distinction is already in the markup and needs no inference: <ol> is the
   real, ordered procedure; <ul> carries parameters, alternatives and
   troubleshooting. So numbered steps get presence and bulleted lists
   deliberately do NOT — troubleshooting must never read as step 4. */
.pr-article--how-to .pr-article__body ol {
  counter-reset: pr-step;
  list-style: none;
  padding-left: 0;
}

.pr-article--how-to .pr-article__body ol > li {
  counter-increment: pr-step;
  position: relative;
  padding-left: 2.6em;
  margin-bottom: 1em;
}

.pr-article--how-to .pr-article__body ol > li::before {
  content: counter(pr-step);
  position: absolute;
  left: 0;
  top: 0.05em;
  width: 1.85em;
  height: 1.85em;
  border-radius: 50%;
  background: var(--pr-coral-tint);
  color: var(--pr-coral-deep);
  font-family: var(--pr-font-sans);
  font-size: 0.82em;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Nested ordered lists stay ordinary — the step treatment is for the top-level
   procedure only. */
.pr-article--how-to .pr-article__body ol ol {
  counter-reset: none;
  list-style: decimal;
  padding-left: 1.35em;
}

.pr-article--how-to .pr-article__body ol ol > li {
  counter-increment: none;
  padding-left: 0.2em;
}

.pr-article--how-to .pr-article__body ol ol > li::before {
  content: none;
}

/* NEWS_ANALYSIS — restraint is the format's job.
   Alternating wide imagery reads as magazine playfulness, which undercuts
   seriousness on a news page. Images stay at the text measure; hero dominance
   and section rhythm are kept, because those are legibility, not decoration. */
.pr-article--news-analysis .pr-article__body figure.article-image-slot.pr-figure--wide {
  width: 100%;
  max-width: 100%;
  margin-left: 0;
  transform: none;
  margin-top: 2.2em;
  margin-bottom: 1.6em;
}

/* LISTICLE — entries need to feel separate.
   Only the boundary is strengthened. A framing section ("How we picked") is an
   h2 exactly like a real entry, and nothing in the markup distinguishes them,
   so anything stronger would style framing as an entry. Deliberately
   conservative until a real entry signal exists. */
.pr-article--listicle .pr-article__body h2 {
  margin-top: 3em;
  padding-top: 1.6em;
}

/* GIFT_GUIDE — the wider column already comes from .pr-article--gift-guide.
   Product cards are code output and own their own presentation: the image
   grammar targets figure.article-image-slot only, so cards are untouched
   whether they are ON or OFF. Nothing is added here on purpose. */

/* ─── MOBILE ─────────────────────────────────────────────────────────────────
   Every breakout collapses back into the column. No horizontal scroll, no
   transform, single column — the grammar simply stops applying. */
@media (max-width: 700px) {
  /* THE GRAMMAR SIMPLY STOPS APPLYING.
     Every treatment — wide breakout and both floats — collapses to one clean
     column. No float, no side-by-side text, no transform, no horizontal
     overflow. The classes stay on the markup (structure is decided once, for
     all viewports); only their rendering changes. */
  .pr-article__featured-image,
  .pr-article__body figure.article-image-slot,
  .pr-article__body figure.article-image-slot.pr-figure--wide,
  .pr-article__body figure.article-image-slot.pr-figure--inline-right,
  .pr-article__body figure.article-image-slot.pr-figure--inline-left {
    float: none;
    width: 100%;
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
    transform: none;
    shape-outside: none;
  }

  .pr-article__featured-image {
    margin-bottom: 28px;
  }

  .pr-article__body figure.article-image-slot,
  .pr-article__body figure.article-image-slot.pr-figure--wide,
  .pr-article__body figure.article-image-slot.pr-figure--inline-right,
  .pr-article__body figure.article-image-slot.pr-figure--inline-left {
    margin-top: 1.7em;
    margin-bottom: 1.3em;
  }

  .pr-article__body h2 {
    margin-top: 2em;
    padding-top: 1.1em;
  }
}

/* ── Citations ──────────────────────────────────────────────────────────────
 *
 * SELECTORS ARE SCOPED UNDER THEIR SECTION, not written as bare classes.
 * `.pr-article__body h2` and `.pr-article__body ol` are (0,1,1) and this block
 * sits inside the body, so a single-class rule loses to them however late it
 * appears — the first pass rendered the Sources list double-numbered under a
 * 29px serif heading with a rule above it. `.pr-article__toc` already solved
 * the same problem the same way; this follows it rather than inventing a
 * second convention or reaching for !important.
 *
 * The marker sits in running prose the reader is meant to stay inside, so it is
 * small and quiet — but it gets a real hit area, because a bare superscript
 * numeral is a two-millimetre tap target on a phone.
 */

.pr-article__body .pr-cite {
  font-family: var(--pr-font-sans);
  font-size: 0.68em;
  font-weight: 600;
  line-height: 0;
  vertical-align: super;
  white-space: nowrap;
}

.pr-article__body .pr-cite a {
  color: var(--pr-coral);
  /* Padding, not a larger glyph: the tap area grows, the type does not.
     Asymmetric, and the left side is pulled back out again — a marker belongs
     against the word it cites, and 3px of left padding reads as a word space,
     which is what made the first version look detached. The right side keeps
     its padding because nothing follows but punctuation. */
  padding: 2px 3px 2px 1px;
  margin-left: -1px;
  border-radius: 3px;
  text-decoration: none;
}

.pr-article__body .pr-cite a:hover,
.pr-article__body .pr-cite a:focus-visible {
  background: var(--pr-coral-tint);
  color: var(--pr-coral-dark);
  text-decoration: none;
}

.pr-article__sources {
  margin: 44px 0 0;
  padding: 24px 26px;
  border: 1px solid var(--pr-border);
  border-radius: 8px;
  background: var(--pr-surface-tint);
  clear: both;
}

/* Overrides the body's serif h2 — its size, its top border and its margins,
   all of which are for a section break in running prose, not a list label. */
.pr-article__body .pr-article__sources h2 {
  font-family: var(--pr-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pr-coral);
  margin: 0 0 14px;
  padding-top: 0;
  border-top: none;
}

/* Kills the body's decimal marker so the hanging counter below is the only
   number on the row. */
.pr-article__sources ol {
  list-style: none;
  counter-reset: pr-source-counter;
  margin: 0;
  padding: 0;
}

.pr-article__sources ol > li {
  counter-increment: pr-source-counter;
  position: relative;
  /* Room for the hanging numeral, so the publisher names line up as a
     scannable column. */
  padding: 0 0 0 28px;
  margin: 0 0 13px;
  font-family: var(--pr-font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--pr-text-secondary);
}

.pr-article__sources ol > li:last-child {
  margin-bottom: 0;
}

.pr-article__sources ol > li::before {
  content: counter(pr-source-counter);
  position: absolute;
  left: 0;
  top: 1px;
  width: 18px;
  text-align: right;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--pr-text-tertiary);
}

/* The entry arrived at from a marker, briefly obvious once it scrolls in. */
.pr-article__sources ol > li:target {
  background: var(--pr-amber-tint);
  border-radius: 4px;
  box-shadow: 0 0 0 6px var(--pr-amber-tint);
}

.pr-article__sources .pr-source__link {
  font-weight: 600;
  color: var(--pr-coral);
  text-decoration: none;
  word-break: break-word;
}

.pr-article__sources .pr-source__link:hover,
.pr-article__sources .pr-source__link:focus-visible {
  text-decoration: underline;
}

/* What the source was cited for. Quiet: the publisher is what gets scanned
   for, and this is what confirms it once found. */
.pr-article__sources .pr-source__context {
  display: block;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pr-text-tertiary);
  margin-top: 1px;
}

.pr-article__sources .pr-source__back {
  color: var(--pr-text-tertiary);
  text-decoration: none;
  margin-left: 6px;
  font-size: 13px;
}

.pr-article__sources .pr-source__back:hover,
.pr-article__sources .pr-source__back:focus-visible {
  color: var(--pr-coral);
}

@media (max-width: 640px) {
  .pr-article__sources {
    padding: 20px 18px;
  }
}
