/* ==========================================================================
   UBM — page-insights.css
   /insights (the archive) and /insights/{slug} (one article, four layouts).

   Loaded after sections.css, so everything here either composes with a shared
   block (.post-card, .prose-toc, .share-row, .filter-bar, .empty-state,
   .pagination, .empty-state) or is genuinely new to these two pages.

   House rules, same as sections.css
   · Tokens only. No raw hex, no raw ms, no hand-rolled easing. Alpha comes
     from color-mix() on a token.
   · Logical properties only. Nothing in here uses left/right/margin-left.
   · Nothing re-declares a button, a card shell or a type scale.
   ========================================================================== */

/* ==========================================================================
   PART ONE — THE ARCHIVE  (/insights)
   ========================================================================== */

/* --------------------------------------------------------------------------
   Index head — the count line under the lead
   <p class="insights-index__count"><span>12 articles</span>·<span>4 topics</span>
   -------------------------------------------------------------------------- */

.insights-index__count {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-block-start: var(--sp-5);
  padding-block-start: var(--sp-4);
  border-block-start: var(--bw) solid var(--line);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
[lang="ar"] .insights-index__count { letter-spacing: 0; }

/* --------------------------------------------------------------------------
   Featured — the one article that leads the page
   -------------------------------------------------------------------------- */

.insights-featured .eyebrow { margin-block-end: var(--sp-6); }

.insights-featured__card {
  padding-block-start: var(--sp-6);
  border-block-start: 2px solid var(--gold);
}
.insights-featured__card .post-card__excerpt { font-size: var(--fs-md); max-inline-size: 46ch; }
.insights-featured__card .post-card__media { border-radius: var(--r-sm); }

@media (min-width: 48rem) {
  /* .post-card--featured is a two-column grid in sections.css; the media spans
     the copy rows. Everything below the media has to line up with the title,
     so the copy column keeps its own rhythm. */
  .insights-featured__card { gap: var(--sp-4) var(--sp-9); align-items: start; }
  /* Top-aligned, never stretched: a stretched 4:3 box takes its width from
     the copy's height, so a long (often Arabic) title made the image wider
     than its column and laid it over the text. */
  .insights-featured__card .post-card__media { grid-row: 1 / span 6; align-self: start; inline-size: 100%; }
  .insights-featured__card .post-card__title { font-size: var(--fs-3xl); }
}

/* --------------------------------------------------------------------------
   Archive head + filters
   -------------------------------------------------------------------------- */

.insights-archive__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-6);
  margin-block-end: var(--sp-5);
}
.insights-archive__range {
  font-size: var(--fs-2xs);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.insights-filter { margin-block-end: var(--sp-5); }

/* the per-category tally, set small and quiet inside the chip */
.filter-bar__count {
  margin-inline-start: var(--sp-2);
  font-size: var(--fs-3xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
}
.filter-bar__chip.is-active .filter-bar__count { color: inherit; opacity: .75; }

.insights-search { flex: 1 1 18rem; max-inline-size: 26rem; }
.insights-search__input { block-size: 2.5rem; padding-block: 0; }

/* Tag chips */
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-3) var(--sp-4);
  padding-block-end: var(--sp-6);
  border-block-end: var(--bw) solid var(--line);
}
.tag-cloud__label {
  flex: none;
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .tag-cloud__label { letter-spacing: 0; }
.tag-cloud__list { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.tag-cloud__count {
  font-size: var(--fs-3xs);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.tag-cloud a:hover { color: var(--text-strong); border-color: var(--line-strong); }

.insights-active-filter,
.insights-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-block-start: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.insights-notice {
  padding: var(--sp-3) var(--sp-4);
  border-inline-start: 2px solid var(--gold);
  background: color-mix(in srgb, var(--c-gold-500) 7%, transparent);
}

/* --------------------------------------------------------------------------
   The grid
   Three across at desktop, two at tablet, one on a phone. The hairline runs
   between the rows, not around the cards: this is an index, not a shop.
   -------------------------------------------------------------------------- */

.insights-results { margin-block-start: var(--sp-8); }
.insights-results[aria-busy="true"] { opacity: .55; transition: opacity var(--d-fast) var(--e-out); }

.insight-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-8) var(--sp-6);
}
@media (min-width: 40rem) { .insight-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 68rem) { .insight-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.insight-card { gap: var(--sp-2); }
.insight-card .post-card__media { margin-block-end: var(--sp-4); }

/* The category accent appears twice and small: an 18px rule and a 6px dot.
   Six category colours in one viewport would be a rainbow; at this size they
   read as an index key. */
.insight-card__rule {
  inline-size: 18px;
  block-size: 2px;
  background: var(--accent);
  border-radius: var(--r-pill);
  transition: inline-size var(--d-base) var(--e-out);
}
.insight-card:hover .insight-card__rule { inline-size: 34px; }

.insight-card__cat {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-3xs);
  font-weight: 600;
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .insight-card__cat { letter-spacing: 0; }
.insight-card__dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

.insight-card__author { color: var(--text-faint); }

/* Placeholder when a post has no cover: a patch-panel elevation, not a
   grey box with a camera glyph. */
.insight-card__placeholder {
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  color: var(--line-strong);
  background:
    repeating-linear-gradient(to bottom,
      transparent 0, transparent 11px,
      color-mix(in srgb, var(--c-ink-500) 5%, transparent) 11px,
      color-mix(in srgb, var(--c-ink-500) 5%, transparent) 12px),
    var(--surface-sunken);
}
.insight-card__placeholder svg { inline-size: 60%; block-size: auto; }

.insights-pagination { margin-block-start: var(--sp-10); }
.pagination__link--edge { padding-inline: var(--sp-4); }

.insights-empty { margin-block-start: var(--sp-6); }
.insights-empty .btn { margin-block-start: var(--sp-2); }

/* A slug that does not resolve — post.php renders its own 404 so the reader
   lands in the archive rather than on the sitewide error page. */
.post-missing__actions { margin-block-start: var(--sp-5); gap: var(--sp-4); }

/* ==========================================================================
   PART TWO — ONE ARTICLE  (/insights/{slug})
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reading progress
   A gold hairline pinned under the header. Scale, not width, so it never
   triggers layout while scrolling.
   -------------------------------------------------------------------------- */

.reading-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: calc(var(--z-header) + 1);
  block-size: 2px;
  pointer-events: none;
}
.reading-progress__bar {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  background: linear-gradient(to right, var(--c-gold-600), var(--c-gold-400));
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}
[dir="rtl"] .reading-progress__bar {
  transform-origin: right center;
  background: linear-gradient(to left, var(--c-gold-600), var(--c-gold-400));
}
@media (prefers-reduced-motion: reduce) { .reading-progress { display: none; } }

/* --------------------------------------------------------------------------
   Where am I: the contents rail fills a gold line as the article is read
   (--read, 0 to 1, set by insights.js), and on screens without the rail a
   slim bar under the header names the section being read.
   -------------------------------------------------------------------------- */

.post-toc--rail ol { position: relative; }
.post-toc--rail ol::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: -1px;
  inline-size: 2px;
  block-size: calc(var(--read, 0) * 100%);
  background: var(--gold);
  opacity: .55;
  pointer-events: none;
}
.post-toc--rail a.is-current .post-toc__text { color: var(--text-strong); }

.reading-now {
  position: fixed;
  inset-block-start: var(--header-h-sm);
  inset-inline: 0;
  z-index: calc(var(--z-header) - 1);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: .55rem var(--gutter);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(8px);
  border-block-end: var(--bw) solid var(--line);
  font-size: var(--fs-xs);
  color: var(--text);
  transform: translateY(-110%);
  opacity: 0;
  transition: transform var(--d-base) var(--e-out), opacity var(--d-base) var(--e-out);
  pointer-events: none;
}
.reading-now.is-on { transform: none; opacity: 1; pointer-events: auto; }
/* The header slides away on scroll down (chrome.js adds .is-hidden). The bar
   rises with it, at the header's pace, so no article text shows above it. */
.site-header.is-hidden ~ #main .reading-now.is-on {
  transform: translateY(calc(var(--header-h-sm) * -1));
  transition: transform var(--d-slow) var(--e-out), opacity var(--d-base) var(--e-out);
}
.reading-now__num { color: var(--gold); font-weight: 600; font-variant-numeric: tabular-nums; }
.reading-now__text { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reading-now a { color: inherit; text-decoration: none; display: flex; gap: var(--sp-3); min-inline-size: 0; flex: 1; }
@media (min-width: 62rem) { .reading-now { display: none; } }
@media (prefers-reduced-motion: reduce) { .reading-now { transition: none; } }

/* --------------------------------------------------------------------------
   Shared hero pieces
   -------------------------------------------------------------------------- */

.post-hero { position: relative; isolation: isolate; overflow: clip; }
.post-hero > .shell { display: grid; gap: var(--sp-4); justify-items: start; }
.post-hero .breadcrumb { margin-block-end: var(--sp-3); }

.post-hero__head { display: grid; gap: var(--sp-4); justify-items: start; }
.post-hero__sub { max-inline-size: 52ch; }

.post-hero__bed { position: absolute; inset: 0; z-index: -2; }
.post-hero__bed img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.post-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--c-ink-950) 78%, transparent) 0%,
      color-mix(in srgb, var(--c-ink-950) 55%, transparent) 38%,
      color-mix(in srgb, var(--c-ink-950) 92%, transparent) 100%);
}
.post-hero__scrim--soft {
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--c-ink-950) 62%, transparent) 0%,
      color-mix(in srgb, var(--c-ink-950) 12%, transparent) 42%,
      color-mix(in srgb, var(--c-ink-950) 86%, transparent) 100%);
}

/* Category mark — the one place a domain colour appears on an article */
.post-cat {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--text-faint);
  transition: color var(--d-fast) var(--e-out);
}
.post-cat::before { display: none; }               /* the .eyebrow hairline */
.post-cat__dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}
.post-cat:hover { color: var(--text-strong); }

/* date · reading time · author */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4) var(--sp-7);
  margin-block-start: var(--sp-4);
  padding-block-start: var(--sp-4);
  border-block-start: var(--bw) solid var(--line);
  inline-size: 100%;
  max-inline-size: 52rem;
}
.post-meta__item { display: grid; gap: var(--sp-1); }
.post-meta dt {
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .post-meta dt { letter-spacing: 0; }
.post-meta dd {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.post-meta--tight { margin-block-start: 0; padding-block-start: 0; border-block-start: 0; gap: var(--sp-3) var(--sp-6); }
.post-meta--tight .post-meta__item { grid-auto-flow: column; align-items: baseline; gap: var(--sp-2); }
.post-meta--tight dd { font-weight: 500; }

/* --------------------------------------------------------------------------
   Cover figure
   -------------------------------------------------------------------------- */

.post-cover { position: relative; display: grid; gap: var(--sp-3); }
.post-cover img { inline-size: 100%; block-size: 100%; object-fit: cover; border-radius: var(--r-sm); }

.post-cover--wide img  { aspect-ratio: 16 / 9; }
.post-cover--plate img { aspect-ratio: 4 / 3; }
.post-cover--bleed img { aspect-ratio: 21 / 9; border-radius: 0; }

/* registration corner, same mark as the scrollytell drawing sheet */
.post-cover--plate::after {
  content: "";
  position: absolute;
  inset-block-start: 10px;
  inset-inline-start: 10px;
  inline-size: 14px;
  block-size: 14px;
  border-block-start: var(--bw) solid var(--line-gold);
  border-inline-start: var(--bw) solid var(--line-gold);
  pointer-events: none;
}

.post-hero__plate { margin-block-start: calc(var(--sp-8) * -1); position: relative; z-index: var(--z-raised); }
@media (max-width: 47.99rem) { .post-hero__plate { margin-block-start: var(--sp-5); } }

/* --------------------------------------------------------------------------
   Layout skeleton
   Every template lays out .post-column and (sometimes) .post-aside. The
   differences between the four are here, not in a colour.
   -------------------------------------------------------------------------- */

.post-layout {
  display: grid;
  gap: var(--sp-8);
  padding-block: var(--sp-9) var(--sp-10);
}
.post-column { min-inline-size: 0; }
.post-column__foot {
  display: grid;
  gap: var(--sp-5);
  margin-block-start: var(--sp-9);
  padding-block-start: var(--sp-6);
  border-block-start: var(--bw) solid var(--line);
  max-inline-size: var(--page-text);
}

.post-aside { min-inline-size: 0; }
/* The pinned rail never runs past the bottom of the screen. On a 768px high
   laptop the contents list plus the share stack did, and "Copy link" sat
   below the fold for the whole article. The list already scrolls on its own,
   so it is the one that gives up height; the rail itself never scrolls. */
.post-aside__sticky {
  position: sticky;
  inset-block-start: calc(var(--header-h) + var(--sp-6));
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  align-self: start;
  max-block-size: calc(100svh - var(--header-h) - var(--sp-6) * 2);
}
.post-aside__sticky > * { flex: none; }
.post-aside__sticky > .post-toc--rail { flex: 0 1 auto; min-block-size: 0; }

/* --- standard: one centred column, nothing beside it -------------------- */
.post-layout--standard { justify-items: center; }
.post-layout--standard .post-column { inline-size: 100%; max-inline-size: var(--page-text); }

/* --- editorial: measure with a narrow rail on the inline-end side ------- */
@media (min-width: 78rem) {
  .post-layout--editorial {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--page-text)) minmax(0, 1fr);
    gap: var(--sp-8) var(--sp-8);
  }
  /* Both pinned to row 1. The aside comes first in the source, so auto
     placement put it in row 1 and the column in row 2: a blank screen
     beside the rail, and a rail that scrolled away instead of sticking. */
  .post-layout--editorial .post-column { grid-column: 2; grid-row: 1; }
  .post-layout--editorial .post-aside  { grid-column: 3; grid-row: 1; }
}
@media (max-width: 77.99rem) {
  .post-layout--editorial { justify-items: center; }
  .post-layout--editorial .post-column { inline-size: 100%; max-inline-size: var(--page-text); }
  .post-aside--editorial { display: none; }
}

/* --- technical: a permanent contents column on the inline-start side ---- */
@media (min-width: 62rem) {
  .post-layout--technical {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    gap: var(--sp-9);
    align-items: start;
  }
  /* The aside stretches to the article's height so its sticky contents can
     travel with the reader; with align-items: start it was only as tall as
     the list and scrolled away with the page. */
  .post-layout--technical .post-aside  { grid-column: 1; align-self: stretch; }
  .post-layout--technical .post-column { grid-column: 2; max-inline-size: 46rem; }
}
@media (max-width: 61.99rem) { .post-aside--technical { display: none; } }

/* --- visual: named grid so figures run wider than the words ------------- */
.post-layout--visual { padding-block-start: var(--sp-7); gap: 0; }
.post-layout--visual .post-column { inline-size: 100%; }

.post-aside--visual { display: none; }
@media (min-width: 82rem) {
  .post-layout--visual {
    grid-template-columns: minmax(0, 4rem) minmax(0, 1fr);
    gap: var(--sp-6);
    padding-inline-start: var(--gutter);
  }
  .post-aside--visual { display: block; }
}

/* --------------------------------------------------------------------------
   Contents
   .prose-toc supplies the type and the current-item rule; this adds the
   numeral, the sticky frame and the three variants.
   -------------------------------------------------------------------------- */

.post-toc a { display: flex; align-items: baseline; gap: var(--sp-3); }
.post-toc__num {
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: 700;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.post-toc a.is-current .post-toc__num { color: var(--accent-text); }
.post-toc__text { min-inline-size: 0; }
.post-toc__sub { display: grid; gap: 0; border-inline-start: 0; }
.post-toc__sub a { padding-inline-start: var(--sp-7); font-size: var(--fs-xs); }
.post-toc--rail { max-block-size: min(58svh, 34rem); overflow-y: auto; scrollbar-width: thin; }

/* Inline variant: a real <details>, closed by default, gone once there is a
   rail to put the contents in. */
.post-toc--inline {
  margin-block-end: var(--sp-7);
  border-block: var(--bw) solid var(--line);
}
.post-toc--inline .prose-toc { padding-block-end: var(--sp-4); }
.post-toc__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block: var(--sp-4);
  font-size: var(--fs-3xs);
  font-weight: 600;
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
}
[lang="ar"] .post-toc__summary { letter-spacing: 0; }
.post-toc__summary::-webkit-details-marker { display: none; }
.post-toc__summary::after {
  content: "";
  inline-size: 7px;
  block-size: 7px;
  border-block-end: var(--bw) solid currentColor;
  border-inline-end: var(--bw) solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--d-fast) var(--e-out);
  flex: none;
}
[open] > .post-toc__summary::after { transform: rotate(-135deg); }
.post-toc__count {
  margin-inline-start: auto;
  margin-inline-end: var(--sp-3);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 62rem) { .post-layout--technical .post-toc--inline { display: none; } }
@media (min-width: 78rem) { .post-layout--editorial .post-toc--inline { display: none; } }

/* Markers variant: the visual template's dot column */
.post-toc--markers { gap: var(--sp-2); }
.post-toc--markers .prose-toc__title,
.post-toc--markers .post-toc__text { display: none; }
.post-toc--markers ol { border-inline-start: 0; gap: var(--sp-2); }
.post-toc--markers a {
  padding: var(--sp-1) 0;
  border-inline-start: 0;
  border-block-end: 2px solid var(--line-strong);
  inline-size: 1.75rem;
  transition: border-color var(--d-fast) var(--e-out), color var(--d-fast) var(--e-out);
}
.post-toc--markers a.is-current { border-block-end-color: var(--gold); }
.post-toc--markers .post-toc__num { font-size: var(--fs-3xs); }

/* --------------------------------------------------------------------------
   The body
   .prose in base.css does the typography. These are the per-template moves.
   -------------------------------------------------------------------------- */

.post-body { max-inline-size: var(--page-text); }
.post-body img { border-radius: var(--r-sm); }

/* Tables arrive wrapped by prose_outline() so they can scroll on a phone. */
.prose-table {
  inline-size: 100%;
  overflow-x: auto;
  margin-block: 2em;
  border: var(--bw) solid var(--line);
  border-radius: var(--r-sm);
}
.prose-table table { inline-size: 100%; font-size: var(--fs-sm); }
.prose-table th,
.prose-table td {
  padding: var(--sp-3) var(--sp-4);
  text-align: start;
  vertical-align: top;
  border-block-end: var(--bw) solid var(--line);
}
.prose-table thead th {
  font-size: var(--fs-3xs);
  font-weight: 600;
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--surface-sunken);
  white-space: nowrap;
}
[lang="ar"] .prose-table thead th { letter-spacing: 0; }
.prose-table tbody tr:last-child td { border-block-end: 0; }

/* Embedded players keep their box even before the frame loads. */
.post-body iframe {
  inline-size: 100%;
  aspect-ratio: 16 / 9;
  block-size: auto;
  margin-block: 2em;
  border: 0;
  border-radius: var(--r-sm);
  background: var(--c-ink-900);
}

/* --- editorial: drop cap, pull quotes, alternating bleeds --------------- */

.post-body--editorial { font-size: var(--fs-md); }

/* initial-letter degrades to a normal capital where it is unsupported, which
   is the right failure: no float, no reflow, no RTL correction needed. */
.post-body--editorial > p:first-of-type::first-letter {
  -webkit-initial-letter: 3;
  initial-letter: 3;
  margin-inline-end: var(--sp-3);
  font-family: var(--font-serif);
  font-weight: 400;
  color: var(--gold);
}
/* Arabic sets no drop cap — the script has no capital form to set one from. */
[lang="ar"] .post-body--editorial > p:first-of-type::first-letter {
  -webkit-initial-letter: normal;
  initial-letter: normal;
  margin-inline-end: 0;
  font-family: inherit;
  color: inherit;
}

.post-body--editorial > blockquote {
  margin-block: 2.4em;
  padding-inline-start: 0;
  border-inline-start: 0;
  font-size: var(--fs-2xl);
  line-height: 1.28;
  text-wrap: pretty;
}
.post-body--editorial > blockquote::before {
  content: "";
  display: block;
  inline-size: 56px;
  block-size: 2px;
  margin-block-end: var(--sp-5);
  background: linear-gradient(to right, var(--gold), transparent);
  border-radius: var(--r-pill);
}
[dir="rtl"] .post-body--editorial > blockquote::before {
  background: linear-gradient(to left, var(--gold), transparent);
}

@media (min-width: 62rem) {
  /* Figures step alternately past each edge of the measure. Because the two
     rules use margin-inline-start and margin-inline-end, the rhythm mirrors
     itself in Arabic instead of breaking. */
  .post-body--editorial > figure,
  .post-body--editorial > .prose-table {
    inline-size: calc(100% + var(--sp-10));
    max-inline-size: none;
  }
  .post-body--editorial > figure:nth-of-type(odd) { margin-inline-start: calc(var(--sp-10) * -1); }
  .post-body--editorial > figure:nth-of-type(even) { margin-inline-end: calc(var(--sp-10) * -1); }
}

/* --- technical: numbered sections, framed code and callouts ------------- */

.post-body--technical { counter-reset: post-section; }
.post-body--technical > h2 {
  counter-increment: post-section;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--sp-4);
  padding-block-start: var(--sp-6);
  border-block-start: var(--bw) solid var(--line);
}
.post-body--technical > h2::before {
  content: counter(post-section, decimal-leading-zero);
  font-size: var(--fs-sm);
  font-weight: 900;
  letter-spacing: 0;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.post-body--technical > h3 {
  padding-inline-start: var(--sp-5);
  border-inline-start: 2px solid var(--line-gold);
}
.post-body--technical pre {
  border: var(--bw) solid color-mix(in srgb, var(--c-paper-000) 12%, transparent);
  border-inline-start: 2px solid var(--c-signal-500);
}
.post-body--technical > ul > li::before { background: var(--accent); }

/* --- visual: full-bleed figures, captions as the voice ------------------ */

.post-body--visual {
  display: grid;
  max-inline-size: none;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, 10rem)
    [text-start] minmax(0, var(--page-text))
    [text-end] minmax(0, 10rem)
    [wide-end] minmax(var(--gutter), 1fr)
    [full-end];
}
.post-body--visual > * { grid-column: text; }
.post-body--visual > figure,
.post-body--visual > img,
.post-body--visual > iframe,
.post-body--visual > .prose-table { grid-column: wide; margin-block: 3em; }
.post-body--visual > hr { grid-column: wide; }

.post-body--visual figure img { inline-size: 100%; border-radius: var(--r-xs); }
.post-body--visual figcaption {
  max-inline-size: 46ch;
  margin-block-start: var(--sp-4);
  padding-inline-start: var(--sp-5);
  border-inline-start: 2px solid var(--line-gold);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--text-muted);
}
[lang="ar"] .post-body--visual figcaption { font-style: normal; font-family: var(--font-sans); }

.post-hero--visual { min-block-size: min(78svh, 46rem); display: grid; align-items: end; padding-block: calc(var(--header-h) + var(--sp-10)) var(--sp-9); }
.post-hero--visual .post-hero__inner { display: grid; gap: var(--sp-4); justify-items: start; max-inline-size: 46rem; }
.post-hero__bed--full { z-index: -2; }

.post-strip {
  padding-block: var(--sp-5);
  border-block-end: var(--bw) solid var(--line);
  background: var(--surface);
}
.post-strip__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
}

/* --------------------------------------------------------------------------
   Editorial hero (deep, oversized)
   -------------------------------------------------------------------------- */

.post-hero--editorial {
  min-block-size: min(82svh, 48rem);
  display: grid;
  align-items: end;
  padding-block: calc(var(--header-h) + var(--sp-10)) var(--sp-10);
  background: var(--c-ink-950);
}
.post-hero--editorial .post-hero__bed img { opacity: .5; filter: saturate(.7) contrast(1.05); }
.post-hero__inner { position: relative; display: grid; gap: var(--sp-5); justify-items: start; max-inline-size: 54rem; }
.post-hero__title { max-inline-size: 17ch; }
.post-hero__standfirst {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-xl);
  line-height: 1.4;
  color: var(--text);
  max-inline-size: 44ch;
  text-wrap: pretty;
}
[lang="ar"] .post-hero__standfirst { font-style: normal; font-family: var(--font-sans); font-weight: 500; }
.post-hero__standfirst--quiet { font-family: var(--font-sans); font-style: normal; font-size: var(--fs-md); color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Technical hero spec strip
   -------------------------------------------------------------------------- */

.post-spec {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-block-start: var(--sp-7);
  border-block-start: var(--bw) solid var(--line);
}
.post-spec__item {
  display: grid;
  gap: var(--sp-1);
  padding-block: var(--sp-4);
  border-block-end: var(--bw) solid var(--line);
}
.post-spec dt {
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .post-spec dt { letter-spacing: 0; }
.post-spec dd { font-size: var(--fs-sm); font-weight: 600; color: var(--text-strong); }

@media (min-width: 48rem) {
  .post-spec { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .post-spec__item { padding-inline-end: var(--sp-5); }
  .post-spec__item:nth-child(n+2) { border-inline-start: var(--bw) solid var(--line); padding-inline-start: var(--sp-5); }
  .post-spec__item:nth-child(odd)  { border-inline-start: 0; padding-inline-start: 0; }
}
@media (min-width: 68rem) {
  .post-spec { grid-template-columns: repeat(4, minmax(0, 1fr)); border-block-end: var(--bw) solid var(--line); }
  .post-spec__item { border-block-end: 0; }
  .post-spec__item:nth-child(n+2) { border-inline-start: var(--bw) solid var(--line); padding-inline-start: var(--sp-5); }
  .post-spec__item:nth-child(odd)  { border-inline-start: var(--bw) solid var(--line); padding-inline-start: var(--sp-5); }
  .post-spec__item:first-child     { border-inline-start: 0; padding-inline-start: 0; }
}

/* --------------------------------------------------------------------------
   Share + tags
   -------------------------------------------------------------------------- */

.post-share__copy[data-state="copied"] { color: var(--c-success); border-color: color-mix(in srgb, var(--c-success) 50%, transparent); }
.post-share__status { font-size: var(--fs-2xs); color: var(--text-faint); }

.post-share--stack {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  padding-block-start: var(--sp-5);
  border-block-start: var(--bw) solid var(--line);
}
.post-share--stack .share-row__label { inline-size: 100%; margin-block-end: var(--sp-1); }
.post-share--stack .post-share__status { display: none; }

.post-tags { display: grid; gap: var(--sp-3); }
.post-tags__label {
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .post-tags__label { letter-spacing: 0; }
.post-tags ul { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.post-tags a:hover { color: var(--text-strong); border-color: var(--line-strong); }

/* --------------------------------------------------------------------------
   Closing furniture — author, prev/next
   -------------------------------------------------------------------------- */

.post-author {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
  padding-block: var(--sp-7);
  border-block: var(--bw) solid var(--line);
  max-inline-size: 52rem;
}
.post-author__body { display: grid; gap: var(--sp-2); justify-items: start; }
.post-author__label {
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--gold);
}
[lang="ar"] .post-author__label { letter-spacing: 0; }
.post-author__name { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: 700; color: var(--text-strong); }
.post-author__role { font-size: var(--fs-2xs); letter-spacing: var(--tr-eyebrow); text-transform: uppercase; color: var(--text-faint); }
[lang="ar"] .post-author__role { letter-spacing: 0; }
.post-author__bio  { font-size: var(--fs-sm); color: var(--text-muted); max-inline-size: 56ch; }

@media (max-width: 35.99rem) {
  .post-author { grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
}

.post-nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  margin-block-start: var(--sp-8);
}
.post-nav__link {
  display: grid;
  gap: var(--sp-2);
  padding-block: var(--sp-6);
  border-block-end: var(--bw) solid var(--line);
  transition: background-color var(--d-base) var(--e-out);
}
.post-nav__link:first-child { border-block-start: var(--bw) solid var(--line); }
.post-nav__label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-3xs);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--text-faint);
}
[lang="ar"] .post-nav__label { letter-spacing: 0; }
.post-nav__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text-strong);
  transition: color var(--d-base) var(--e-out);
  text-wrap: balance;
}
.post-nav__link:hover .post-nav__title { color: var(--accent-text); }
.post-nav__arrow { flex: none; transition: transform var(--d-base) var(--e-out); }
.post-nav__link:hover .post-nav__arrow { transform: translateX(-3px); }
.post-nav__link--next { text-align: end; justify-items: end; }
.post-nav__link--next .post-nav__label { flex-direction: row-reverse; }
.post-nav__link--next:hover .post-nav__arrow { transform: translateX(3px); }
[dir="rtl"] .post-nav__link:hover .post-nav__arrow { transform: translateX(3px); }
[dir="rtl"] .post-nav__link--next:hover .post-nav__arrow { transform: translateX(-3px); }

@media (min-width: 48rem) {
  .post-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-6); }
  .post-nav__link { border-block-start: var(--bw) solid var(--line); }
  .post-nav__link--next { grid-column: 2; }
}

.post-related .insight-grid--related { gap: var(--sp-7) var(--sp-6); }

/* --------------------------------------------------------------------------
   The first paint
   An article is long, and before its first paint the browser laid out all
   of it. On a mid-range phone that one step was about three times heavier
   in Arabic (text shaping over 1,100 elements) and held the first paint of
   an Arabic article back by about 0.7 s. So until the first screen has been
   painted, blocks far below it are skipped (content-visibility: auto).
   app.js then sets <html data-painted> and the page is laid out whole, so
   the scroll position restored on Back, find-in-page and the scrollbar all
   behave exactly as they always did; those went wrong while blocks stood
   at estimated sizes. An address with a #section skips nothing at all
   (:has(:target)): the browser scrolls to it before app.js runs. Without
   JavaScript, or in a browser without :has(), none of this applies and
   the page is laid out at once, as before.

   Skipping also contains a block, so it is kept to blocks where that
   changes nothing, which makes lifting it invisible:
   - From the sixth block of the body on, so the opening never waits.
   - Never a heading: the technical template numbers its h2s with a
     counter, which style containment would restart on each one.
   - Paragraphs, lists, quotations and tables only. A figure would stop its
     caption's margin collapsing through it, and grew 34px. (Checked on
     every article in both languages: no other block changes size.)
   - The sections after the article (comments, author, related, the call to
     action) as wholes; each has its own padding.
   The sizes are estimates for the blocks skipped.
   -------------------------------------------------------------------------- */

.js:not([data-painted]):not(:has(:target)) .post-body > :is(p, ul, ol, blockquote, .prose-table):nth-child(n+6) {
  content-visibility: auto;
  contain-intrinsic-block-size: 8em;
}
.js:not([data-painted]):not(:has(:target)) .post-body > .prose-table:nth-child(n+6) {
  contain-intrinsic-block-size: 26em;
}
.js:not([data-painted]):not(:has(:target)) #main > .post ~ section {
  content-visibility: auto;
  contain-intrinsic-block-size: 900px;
}

/* --------------------------------------------------------------------------
   Print — the body, nothing else
   -------------------------------------------------------------------------- */

@media print {
  .reading-progress,
  .post-aside,
  .post-toc,
  .post-share,
  .post-nav,
  .post-related,
  .post-cta { display: none !important; }
  .post-layout { padding-block: 0; display: block; }
  .post-body { max-inline-size: none; }
}

/* --------------------------------------------------------------------------
   Comments under an article (partials/post-comments.php)
   -------------------------------------------------------------------------- */

.comments { border-block-start: var(--bw) solid var(--line); }
.comments__shell { display: grid; gap: var(--sp-7); max-inline-size: calc(var(--page-text) + 2 * var(--gutter)); }
.comments__head { display: grid; gap: var(--sp-2); }
.comments__count {
  display: inline-grid; place-items: center;
  min-inline-size: 1.8em; padding-inline: .45em; margin-inline-start: .35em;
  border-radius: 999px; background: var(--surface-sunken);
  font-size: .55em; vertical-align: middle; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.comments__empty { color: var(--text-muted); }
.comments__notice {
  padding: var(--sp-4) var(--sp-5);
  border: var(--bw) solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-radius: var(--r-sm);
  color: var(--text-strong);
}
.comments__notice--error { border-color: var(--c-danger); background: color-mix(in srgb, var(--c-danger) 8%, transparent); }

.comments__list, .comments__replies { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-5); }
.comments__replies { margin-block-start: var(--sp-4); padding-inline-start: var(--sp-6); border-inline-start: 2px solid var(--line-gold); }
.comment { display: grid; gap: var(--sp-2); }
.comment__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-3); }
.comment__name { font-weight: 600; color: var(--text-strong); }
.comment__badge {
  font-size: var(--fs-3xs); font-weight: 700; letter-spacing: .08em;
  padding: .15em .5em; border-radius: 4px;
  background: var(--gold); color: var(--c-ink-900);
}
.comment__time { font-size: var(--fs-2xs); color: var(--text-faint); }
.comment__body { color: var(--text); overflow-wrap: anywhere; }
.comment__body p + p { margin-block-start: .7em; }

.comments__form {
  display: grid; gap: var(--sp-5);
  padding: clamp(var(--sp-5), 3vw, var(--sp-7));
  border: var(--bw) solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-raised);
}
.comments__form h3 { margin: 0; }
.comments__submit { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-5); }
.comments__trap { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
