/*
 * components.css — cards, buttons, pagination, CTAs, code/Enlighter polish,
 * forms, newsletter shortcode, breadcrumb, related-tags chips, post hero
 * header, article body, sticky headings, mobile TOC, archive controls bar.
 *
 * Loaded on every page (dependency: jacar-layout).
 */

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .65rem 1.25rem;
  border-radius: var(--radius);
  font-size: .9375rem;
  font-weight: 600;
  border: 2px solid transparent;
  transition: background var(--t), color var(--t), border-color var(--t), box-shadow var(--t);
  cursor: pointer;
  line-height: 1.4;
  text-decoration: none;
}
.btn svg { width: 18px; height: 18px; }
.btn-primary {
  background: var(--teal);
  color: #fff;
  border-color: var(--teal);
}
.btn-primary:hover {
  background: var(--teal-hover);
  border-color: var(--teal-hover);
  color: #fff;
  box-shadow: 0 4px 12px rgba(43,138,148,.35);
}
.btn-white {
  background: rgba(255,255,255,.15);
  color: #fff;
  border-color: rgba(255,255,255,.3);
}
.btn-white:hover {
  background: rgba(255,255,255,.25);
  color: #fff;
}
.btn-outline {
  background: transparent;
  color: var(--teal);
  border-color: var(--teal);
}
.btn-outline:hover {
  background: var(--teal);
  color: #fff;
}

/* ============================================================
   BREADCRUMBS
   ============================================================ */
.breadcrumbs {
  padding: .75rem 0;
  font-size: .8125rem;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border-faint);
}
.breadcrumbs a { color: var(--text-faint); }
.breadcrumbs a:hover { color: var(--teal); }
.breadcrumb-sep { margin-inline: .4rem; opacity: .5; }

/* ============================================================
   POST GRID (archive / home) — cards, list view, post-meta,
   cat-badge, tag-pill, post-tags, hero caption.
   ============================================================ */
.posts-section { padding: 3rem 0; }
.posts-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 2rem;
  gap: 1rem;
}
.posts-header h2 {
  font-size: 1.4rem;
  color: var(--text);
}
.posts-header a {
  font-size: .875rem;
  font-weight: 600;
  color: var(--teal);
  white-space: nowrap;
}

/* Featured post (first post, full width) */
.post-featured {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  background: var(--bg);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
  margin-bottom: 2.5rem;
  transition: box-shadow var(--t-slow);
  border: 1px solid var(--border);
}
@media (min-width: 720px) {
  .post-featured { grid-template-columns: 1fr 1fr; }
}
.post-featured:hover { box-shadow: var(--shadow-lg); }
.post-featured__image {
  aspect-ratio: 16/9;
  overflow: hidden;
}
@media (min-width: 720px) {
  .post-featured__image { aspect-ratio: auto; min-height: 280px; }
}
.post-featured__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
}
.post-featured:hover .post-featured__image img { transform: scale(1.03); }
.post-featured__body {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.post-featured__body h2 { font-size: clamp(1.2rem, 2.5vw, 1.6rem); margin-bottom: .75rem; }
.post-featured__body h2 a { color: var(--text); }
.post-featured__body h2 a:hover { color: var(--teal); }
.post-featured__excerpt { color: var(--text-muted); margin-bottom: 1rem; font-size: .9375rem; }
.post-featured__meta { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }

/* Post grid */
.post-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

/* ── List view variant — horizontal rows ── */
.post-grid--list {
  display: flex;
  flex-direction: column;
  gap: .75rem;
}
.post-grid--list .post-card,
.post-grid--list .post-featured {
  flex-direction: row;
  align-items: stretch;
  min-height: 120px;
}
.post-grid--list .post-card__image,
.post-grid--list .post-featured__image {
  flex: 0 0 200px;
  height: auto;
  overflow: hidden;
}
.post-grid--list .post-card__image img,
.post-grid--list .post-featured__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.post-grid--list .post-card__body,
.post-grid--list .post-featured__body {
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
  min-width: 0;
}
.post-grid--list .post-card__title,
.post-grid--list .post-featured h2 {
  font-size: 1.05rem;
  margin-bottom: .35rem;
}
.post-grid--list .post-card__excerpt,
.post-grid--list .post-featured__excerpt {
  font-size: .875rem;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: .5rem;
}
@media (max-width: 640px) {
  .post-grid--list .post-card,
  .post-grid--list .post-featured { flex-direction: column; }
  .post-grid--list .post-card__image,
  .post-grid--list .post-featured__image { flex-basis: auto; height: 180px; }
}

.post-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow var(--t-slow), transform var(--t-slow), border-color var(--t-slow);
}
.post-card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
  border-color: var(--teal-light);
}
.post-card__image {
  aspect-ratio: 16/9;
  overflow: hidden;
  background: var(--surface);
}
.post-card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
}
.post-card:hover .post-card__image img { transform: scale(1.04); }
.post-card__body {
  padding: 1.25rem;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.post-card__title {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: .5rem;
  line-height: 1.35;
}
.post-card__title a {
  color: var(--text);
  transition: color var(--t);
}
.post-card:hover .post-card__title a { color: var(--teal); }
.post-card__excerpt {
  color: var(--text-muted);
  font-size: .875rem;
  line-height: 1.6;
  flex: 1;
  margin-bottom: .75rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card__footer { margin-top: auto; }

/* Post meta (date, reading time, category) */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  align-items: center;
  font-size: .8125rem;
  color: var(--text-faint);
}
.post-meta svg { width: 13px; height: 13px; vertical-align: -.15em; }
.post-meta a { color: var(--text-faint); }
.post-meta a:hover { color: var(--teal); }

/* ── Unified post-meta strip ──────────────────────────────────────────
   Used by every post card / list item across the site (homepage hero,
   archive cards, category lists, search results, related posts, etc.).
   Order: views · reading time · date · rating. Icons render in teal so
   the strip reads as a metric row and not running prose.
*/
.post-meta--strip {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .9rem;
  align-items: center;
  font-variant-numeric: tabular-nums;
}
.post-meta__item {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  line-height: 1;
}
.post-meta__item-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--teal);
}
.post-meta__item-icon svg { width: 14px; height: 14px; }
.post-meta__item-val { color: inherit; }

/* Calendar uses a slightly muted teal so date never visually dominates
   over views / reading time / rating, which are the live metrics. */
.post-meta__item--date .post-meta__item-icon { color: color-mix(in srgb, var(--teal) 75%, var(--text-faint)); }

/* ── Star rating mini-bar ─────────────────────────────────────────────
   Two-layer track + clipped fill. The track holds five outlined stars
   in the muted border colour; the fill overlays solid teal stars and
   is clipped horizontally to `width: <pct>%`, where pct = avg/5*100.
   Only renders when there is at least one vote (PHP gates this).
*/
.post-meta__stars {
  position: relative;
  display: inline-block;
  line-height: 0;
  height: 14px;
}
.post-meta__stars-track,
.post-meta__stars-fill {
  display: inline-flex;
  gap: 1px;
}
.post-meta__stars-track svg {
  width: 14px; height: 14px;
  color: color-mix(in srgb, var(--text-faint) 55%, transparent);
  fill: none;
}
.post-meta__stars-fill {
  position: absolute;
  inset: 0 auto 0 0;
  overflow: hidden;
  white-space: nowrap;
}
.post-meta__stars-fill svg {
  width: 14px; height: 14px;
  color: var(--teal);
  fill: currentColor;
  stroke: currentColor;
}
.post-meta__item--rating .post-meta__item-val {
  color: var(--text);
  font-weight: 600;
  font-size: .8125rem;
}

/* On dark hero / bento overlays (white-on-dark), keep the stars/icons
   visible against the photo by lifting the muted track to a visible
   white-translucent. The teal fill stays as-is — it has the contrast. */
.bento-card__overlay .post-meta__stars-track svg,
.post-featured__image ~ * .post-meta__stars-track svg {
  color: rgba(255,255,255,.35);
}

.cat-badge {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  padding: .2rem .6rem;
  border-radius: 20px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--teal) 14%, transparent);
  color: var(--teal);
  transition: background var(--t), color var(--t);
  text-decoration: none;
}
.cat-badge:hover {
  background: var(--teal);
  color: #fff;
}
.cat-badge-wrap { margin-bottom: .6rem; }

.tag-pill {
  font-size: .7rem;
  border: 1px solid var(--border);
  padding: .12rem .5rem;
  border-radius: 20px;
  color: var(--text-muted);
  text-decoration: none;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.tag-pill:hover { background: var(--teal); color: #fff; border-color: var(--teal); }

.post-tags {
  margin-top: .5rem;
}

.post-hero__caption {
  font-size: .8125rem;
  color: var(--text-faint);
  text-align: center;
  padding: .5rem 1rem;
}

/* ============================================================
   BENTO CARDS — featured 2×2, medium, small, rank badge,
   cat-badge small variant.
   ============================================================ */
.bento-section {
  padding: 2rem 0 4rem;
}

.bento-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 300px 300px auto;
  gap: 1rem;
}

/* ── Shared card base ── */
.bento-card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
}

/* ── Featured: 2×2 ── */
.bento-card--featured {
  grid-column: 1 / span 2;
  grid-row: 1 / span 2;
  border-radius: 12px;
  background: linear-gradient(135deg, #0f172a 0%, #1e293b 60%, #0d2b2b 100%);
}

.bento-card--featured .bento-card__img-link {
  display: block;
  width: 100%;
  height: 100%;
}

.bento-card--featured .bento-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s ease;
}
.bento-card--featured:hover .bento-card__img { transform: scale(1.04); }

.bento-card__overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 1.5rem 1.5rem 1.25rem;
  background: linear-gradient(to top, rgba(0,0,0,.88) 0%, rgba(0,0,0,.45) 55%, transparent 100%);
}

.bento-card__overlay .bento-card__title {
  font-size: clamp(1.1rem, 2vw, 1.65rem);
  font-weight: 700;
  line-height: 1.25;
  margin: 0 0 .6rem;
  color: #fff;
}
.bento-card__overlay .bento-card__title a {
  color: inherit;
  text-decoration: none;
}
.bento-card__overlay .bento-card__title a:hover { text-decoration: underline; }

.bento-card__overlay .post-meta { color: rgba(255,255,255,.75); font-size: .8125rem; }

.bento-card__overlay .bento-card__excerpt {
  color: rgba(255,255,255,.82);
  font-size: .9375rem;
  line-height: 1.5;
  margin: 0 0 .75rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Shared excerpt styling for medium + small */
.bento-card__excerpt {
  color: var(--text-muted);
  font-size: .8125rem;
  line-height: 1.5;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Medium ── */
.bento-card--medium {
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  transition: transform var(--t), border-color var(--t), box-shadow var(--t);
}
.bento-card--medium:hover {
  transform: translateY(-3px);
  border-color: var(--teal);
  box-shadow: 0 8px 28px rgba(43, 138, 148, .13);
}

.bento-card--medium .bento-card__img-link { display: block; flex-shrink: 0; }
.bento-card--medium .bento-card__img {
  width: 100%;
  height: 165px;
  object-fit: cover;
  display: block;
  border-radius: 11px 11px 0 0;
}

.bento-card--medium .bento-card__body {
  padding: .75rem 1rem .9rem;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  flex: 1;
}

.bento-card--medium .bento-card__title {
  font-size: .9rem;
  font-weight: 600;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Pin the date+reading-time row to the bottom of medium cards */
.bento-card--medium .bento-card__meta { margin-top: auto; }
.bento-card--medium .bento-card__title a {
  color: var(--text);
  text-decoration: none;
}
.bento-card--medium:hover .bento-card__title a { color: var(--teal); }

/* ── Small ── */
.bento-card--small {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: .5rem;
  transition: background var(--t), border-color var(--t);
  min-height: 135px;
}
.bento-card--small:hover {
  background: var(--teal-lighter);
  border-color: var(--teal);
}
/* Keep cat-badge legible when the card hover paints a teal-lighter bg */
.bento-card--small:hover .cat-badge,
.bento-card--medium:hover .cat-badge {
  background: var(--teal);
  color: #fff;
}

.bento-card--small .bento-card__title {
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bento-card--small .bento-card__title a {
  color: var(--text);
  text-decoration: none;
}
.bento-card--small:hover .bento-card__title a { color: var(--teal); }

.bento-card--small .bento-card__meta { font-size: .75rem; }

/* ── Rank badge ── */
.bento-rank {
  position: absolute;
  top: .6rem;
  right: .6rem;
  height: 28px;
  padding: 0 .55rem 0 .35rem;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  background: rgba(15, 23, 42, 0.85);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  font-size: .8125rem;
  font-weight: 800;
  color: #fff;
  box-shadow: 0 2px 10px rgba(0,0,0,.35);
  z-index: 3;
  line-height: 1;
  letter-spacing: -.01em;
}
.bento-rank__trophy {
  width: 16px; height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bento-rank__trophy svg { width: 16px; height: 16px; }
.bento-rank__num { font-variant-numeric: tabular-nums; }

/* Trophy colour matches the legacy badge background per rank
   (gold / silver / bronze). The pill itself stays neutral so all
   three colours stand out on any thumbnail. */
/* Post-Views-Counter auto-insert: hidden because we render the count in the
   .post-meta strip at the top of the post (single.php), per editorial choice. */
.post-views.content-post,
.entry-meta.post-views { display: none !important; }

.bento-rank--1 .bento-rank__trophy { color: #f59e0b; }
.bento-rank--2 .bento-rank__trophy { color: #94a3b8; }
.bento-rank--3 .bento-rank__trophy { color: #b45309; }

/* ── cat-badge small variant ── */
.cat-badge--sm {
  font-size: .6875rem;
  padding: .15rem .5rem;
}

/* ── Dark mode adjustments ── */
[data-theme="dark"] .bento-card--medium,
[data-theme="dark"] .bento-card--small {
  background: var(--bg-2);
  border-color: var(--border);
}
[data-theme="dark"] .bento-card--small:hover { background: rgba(43,138,148,.12); }

/* ============================================================
   SINGLE POST — hero header + article body
   ============================================================ */
.single-wrap {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  padding: 2.5rem 0 4rem;
}
@media (min-width: 1080px) {
  .single-wrap {
    grid-template-columns: var(--sidebar) 1fr;
    align-items: start;
  }
}

/* Post hero header */
.post-hero {
  margin-bottom: 2rem;
}
.post-hero__cats { margin-bottom: .75rem; display: flex; flex-wrap: wrap; gap: .5rem; }
.post-hero__title {
  font-size: clamp(1.6rem, 4.5vw, 2.75rem);
  line-height: 1.2;
  margin-bottom: 1.25rem;
  letter-spacing: -.02em;
}
/* Sticky post-hero stack: title (h1) + meta strip (date · reading
   time · author · views) anchored together under the site header so
   the reader always sees the article they are in. They release once
   the first h2 in the body reaches the sticky line — see the inline
   observer in single.php that toggles .is-released on this element. */
.post-hero-stack {
  position: sticky;
  top: 62px;                              /* matches .header-inner height */
  z-index: 50;
  margin: 0 -1rem 1.5rem;
  padding: .65rem 1rem .75rem;
  border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, .08));
  /* Fully opaque so article text doesn't bleed through as the body
     scrolls underneath the sticky stack. */
  background: var(--color-bg-page, #fff);
}
.post-hero-stack .post-hero__title {
  margin: 0 0 .35rem;
  /* Indent transitions in/out as .has-mini-thumb is added/removed. */
  transition: padding-left .45s cubic-bezier(.22, 1.5, .36, 1);
}
.post-hero-stack.has-mini-thumb .post-hero__title {
  /* 100px thumb + ~14px gap. Only the title indents — the meta row
     stays at its natural left edge. */
  padding-left: 114px;
}
.post-hero-stack .post-hero__meta {
  /* meta is no longer independently sticky; it rides on the stack. */
  position: static;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
}

/* Mini-thumbnail that fades into the sticky stack once the full-size
   .post-hero__image has scrolled completely above the viewport. JS
   toggles .has-mini-thumb on .post-hero-stack — see event-handlers.js.
   Default state: collapsed, off to the left. */
.post-hero-stack__thumb {
  /* Absolute-positioned so it doesn't push the meta row to the right
     when revealed. Only the H1's padding-left animates to make room.
     Top-aligned with the sticky author card in the sidebar:
     .post-hero-stack pins at viewport y = --sticky-top, the author
     card pins at y = --sidebar-base-top (= --sticky-top + 24). */
  position: absolute;
  left: 1rem;
  top: 24px;
  width: 100px;
  height: 100px;
  /* High z-index so the thumb is never covered by sticky h2/h3 (z 11/10)
     or any other neighbouring layer when it extends below the
     hero-stack's box (rendered out-of-flow via absolute positioning). */
  z-index: 60;
  opacity: 0;
  overflow: hidden;
  border-radius: 12px;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 4px 16px rgba(0,0,0,.25);
  transform: translateX(-36px) scale(.6);
  transform-origin: left center;
  pointer-events: none;
  transition:
    opacity   .35s ease,
    transform .45s cubic-bezier(.22, 1.5, .36, 1);
}
.post-hero-stack__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  /* cover: image fills the box edge-to-edge; tall/wide source images
     are cropped to fit. */
  object-fit: cover;
  border-radius: 12px;
}
.post-hero-stack.has-mini-thumb .post-hero-stack__thumb {
  opacity: 1;
  transform: translateX(0) scale(1);
}
@media (prefers-reduced-motion: reduce) {
  .post-hero-stack__thumb { transition: none; }
}
/* Single-post meta icons: brand teal (the site's "blue"). Icons use
   stroke="currentColor"/fill="currentColor", so setting `color` on
   the SVG cascades into the strokes/fills. Scoped to .post-hero__meta
   so archive/grid card metas keep their faint default color. */
.post-hero__meta svg { color: var(--teal); }
/* ============================================================
   Stars rating in the post-hero meta row.

   Layout: views span gets margin-left:auto so it (and the stars
   that follow it) snap to the right edge of the meta row. The
   YASR widget is relocated into [data-yasr-mount] by core.js;
   the plugin's stars are scaled down so their visual size
   matches the 13–14px Tabler icons used elsewhere in .post-meta,
   the prompt and dashicon are hidden, and the bracketed Total /
   Media stats only surface as a hover tooltip.
   ============================================================ */
.post-hero__meta .post-meta__views { margin-left: auto; }

.post-hero__stars {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .8125rem;
  color: var(--text-faint);
  line-height: 1.2;
}
/* Leading voting icon (thumb-up) — matches the calendar / clock /
   user glyph sizing for visual rhythm. */
.post-hero__stars > svg[data-icon="thumb-up"] {
  width: 13px;
  height: 13px;
  vertical-align: -.15em;
  flex: 0 0 auto;
}

/* Attention pulse — toggled on .post-hero__stars by event-handlers.js
   when the bottom of .post-content scrolls into view. Multi-stage
   "WOW" composition: spring-pop scale with a rotate jitter, a warm
   bg flash, expanding box-shadow ripples, an icon wiggle, plus a
   sparkle ring orbiting the widget. Single 2.8s run, then settles
   back. Honors prefers-reduced-motion. */

/* (1) Outer pop — spring scale up with a small rotate jitter, settles. */
@keyframes jacar-vote-pop {
  0%   { transform: scale(1)    rotate(0deg); }
  8%   { transform: scale(0.92) rotate(-3deg); }
  18%  { transform: scale(1.42) rotate(4deg); }
  28%  { transform: scale(1.05) rotate(-3deg); }
  40%  { transform: scale(1.22) rotate(3deg); }
  55%  { transform: scale(1.04) rotate(-1.5deg); }
  70%  { transform: scale(1.12) rotate(1.5deg); }
  85%  { transform: scale(1)    rotate(0deg); }
  100% { transform: scale(1)    rotate(0deg); }
}

/* (2) Background + multi-ring box-shadow ripple. Two concentric rings
   expand at different speeds — golden-amber outer, brighter cream
   inner — for a starburst-y feel. Inline background pulses from
   transparent → bright cream → soft amber → transparent. */
@keyframes jacar-vote-flash {
  0%   {
    background: transparent;
    box-shadow:
      0 0 0 0 rgba(245, 181, 10, 0),
      0 0 0 0 rgba(255, 224, 102, 0),
      0 0 0 0 rgba(245, 181, 10, 0);
  }
  18%  {
    background: color-mix(in srgb, #ffe066 60%, transparent);
    box-shadow:
      0 0 0 8px  rgba(245, 181, 10, .7),
      0 0 0 0    rgba(255, 224, 102, .9),
      0 0 36px 12px rgba(245, 181, 10, .55);
  }
  40%  {
    background: color-mix(in srgb, #f5b50a 35%, transparent);
    box-shadow:
      0 0 0 22px rgba(245, 181, 10, 0),
      0 0 0 12px rgba(255, 224, 102, .55),
      0 0 50px 18px rgba(245, 181, 10, .35);
  }
  70%  {
    background: color-mix(in srgb, #f5b50a 18%, transparent);
    box-shadow:
      0 0 0 28px rgba(245, 181, 10, 0),
      0 0 0 26px rgba(255, 224, 102, 0),
      0 0 30px 10px rgba(245, 181, 10, .2);
  }
  100% {
    background: transparent;
    box-shadow:
      0 0 0 32px rgba(245, 181, 10, 0),
      0 0 0 32px rgba(255, 224, 102, 0),
      0 0 0  0  rgba(245, 181, 10, 0);
  }
}

/* (3) Inner thumb-up icon wiggle — fast oscillation during the peak. */
@keyframes jacar-vote-icon-wiggle {
  0%, 100% { transform: rotate(0deg) scale(1); filter: drop-shadow(0 0 0 rgba(255, 224, 102, 0)); }
  10%  { transform: rotate(-18deg) scale(1.15); filter: drop-shadow(0 0 6px rgba(255, 224, 102, .9)); }
  22%  { transform: rotate(16deg)  scale(1.25); filter: drop-shadow(0 0 8px rgba(255, 224, 102, 1)); }
  34%  { transform: rotate(-12deg) scale(1.18); filter: drop-shadow(0 0 6px rgba(255, 224, 102, .8)); }
  46%  { transform: rotate(10deg)  scale(1.12); filter: drop-shadow(0 0 4px rgba(255, 224, 102, .6)); }
  58%  { transform: rotate(-6deg)  scale(1.08); filter: drop-shadow(0 0 3px rgba(255, 224, 102, .4)); }
  72%  { transform: rotate(4deg)   scale(1.04); filter: drop-shadow(0 0 0 rgba(255, 224, 102, 0)); }
}

/* (4) Sparkle ring — eight star glyphs orbit the widget, fading in
   and scaling outward like a fireworks burst. */
@keyframes jacar-vote-sparkle {
  0%   { opacity: 0; transform: scale(0.55) rotate(0deg); }
  18%  { opacity: 1; transform: scale(1)    rotate(60deg); }
  55%  { opacity: 1; transform: scale(1.7)  rotate(180deg); }
  100% { opacity: 0; transform: scale(2.2)  rotate(280deg); }
}

.post-hero__stars.is-attention {
  position: relative;
  /* High enough to clear the post-hero-stack siblings (z 50) within
     its own stacking context. The :has() rule below also lifts the
     entire .post-hero-stack while the blink is active so the halo
     and sparkles aren't clipped by neighbouring sticky elements. */
  z-index: 100;
  border-radius: 999px;
  padding: .15rem .55rem;
  margin-inline: -.3rem;
  transform-origin: center center;
  animation:
    jacar-vote-pop   2.8s cubic-bezier(.22, 1.5, .36, 1) 1,
    jacar-vote-flash 2.8s ease-out 1;
  /* Smooth fade for the residual properties when the animation ends. */
  transition: background .4s ease, padding .4s ease, margin-inline .4s ease;
}
/* Sparkle ring sits OUTSIDE the widget via negative inset. The
   `letter-spacing` between the eight ✦ glyphs distributes them
   roughly evenly around the rounded shape; rotation in the
   keyframe gives the orbit illusion. */
.post-hero__stars.is-attention::before {
  content: "✦  ✧  ✦  ✧  ✦  ✧  ✦  ✧";
  position: absolute;
  inset: -10px -14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 9px;
  letter-spacing: .25em;
  color: #ffd34d;
  text-shadow:
    0 0 6px  rgba(255, 211, 77, .95),
    0 0 12px rgba(255, 211, 77, .55);
  pointer-events: none;
  animation: jacar-vote-sparkle 2.8s ease-out 1;
  /* Above the parent's bg/box-shadow rings. */
  z-index: 1;
}
/* Inner thumb-up icon wiggles in sync with the parent pop. */
.post-hero__stars.is-attention svg[data-icon="thumb-up"] {
  transform-origin: center center;
  animation: jacar-vote-icon-wiggle 2.8s cubic-bezier(.22, 1.5, .36, 1) 1;
  color: #f5b50a;
}

@media (prefers-reduced-motion: reduce) {
  .post-hero__stars.is-attention,
  .post-hero__stars.is-attention::before,
  .post-hero__stars.is-attention svg[data-icon="thumb-up"] {
    animation: none;
  }
  .post-hero__stars.is-attention {
    background: color-mix(in srgb, #f5b50a 22%, transparent);
    box-shadow: 0 0 0 2px rgba(245, 181, 10, .55);
  }
}
/* Lift the entire post-hero-stack (otherwise z 50) above the sticky
   H2/H3 stack and any other neighbouring layer while the blink is
   active, so the expanding box-shadow rings and orbiting sparkles
   render above everything. Browsers without :has() (very old) gracefully
   skip this rule and the blink still plays at z 50. */
.post-hero-stack:has(.post-hero__stars.is-attention) {
  z-index: 1000;
}

/* Outer wrapper that YASR auto-inserts (carries inline
   style="text-align:center" — override). */
.post-hero__stars .yasr-auto-insert-visitor,
.post-hero__stars .yasr-auto-insert-visitor-rating {
  text-align: left !important;
  margin: 0 !important;
  padding: 0 !important;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}

/* Visitor-votes core block + its inner row. */
.post-hero__stars .yasr-visitor-votes,
.post-hero__stars .yasr-vv-second-row-container {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
}

/* "¿Te ha resultado útil?" prompt — redundant when the stars
   are right there and the meta row is already terse. */
.post-hero__stars .yasr-custom-text-vv-before,
.post-hero__stars [class^="yasr-custom-text-vv-before"] {
  display: none;
}

/* Stars rater: pinned to the meta-row text size (13px). YASR renders
   the stars as a tiled background-image on a single inline-block
   element (.yasr-rater-stars-vv = .yasr-star-rating); core.js
   (resizeYasrStars) rewrites that element's inline width / height /
   background-size to TARGET px so the rendered glyphs match. CSS only
   handles vertical alignment — width MUST come from JS so the filled
   overlay (.yasr-star-value, set in % by YASR) keeps the right ratio. */
.post-hero__stars .yasr-rater-stars-vv {
  vertical-align: middle;
  line-height: 1;
}

/* Stats container: hidden by default, surfaces as a tooltip when
   the user hovers / focuses the stars block. Numbers only — the
   "Total:" / "Media:" labels are stripped by core.js. */
.post-hero__stars .yasr-vv-stats-text-container {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .25rem .55rem;
  font-size: .72rem;
  letter-spacing: .01em;
  color: var(--text-faint);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow-sm, 0 2px 6px rgba(0,0,0,.08));
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
  transform: translateY(-2px);
}
.post-hero__stars:hover .yasr-vv-stats-text-container,
.post-hero__stars:focus-within .yasr-vv-stats-text-container {
  opacity: 1;
  transform: translateY(0);
}
.post-hero__stars .yasr-dashicons-visitor-stats { display: none; }

/* Transient bits we don't want disturbing the row. */
.post-hero__stars .yasr-vv-container-loader {
  display: none;
}
.post-hero__stars .yasr-vv-bottom-container { display: none; }
.post-hero__stars .yasr-vv-bottom-container:not(:empty) {
  display: inline;
  margin-left: .35rem;
  font-size: .7rem;
  color: var(--teal);
}
/* WP admin bar is 32px on ≥783px and 46px below that. The default
   .admin-bar rule covers ≥783px (62 header + 32 bar = 94); the
   ≤782px override covers the wider mobile bar (62 + 46 = 108). */
.admin-bar .post-hero-stack { top: 94px; }
@media (max-width: 782px) {
  .admin-bar .post-hero-stack { top: 108px; }
}
@media (max-width: 600px) {
  .post-hero-stack { top: 56px; padding: .55rem .75rem .65rem; margin-inline: -.75rem; }
  .admin-bar .post-hero-stack { top: 102px; }
}
.post-hero__image {
  width: 100%;
  aspect-ratio: 16/8;
  overflow: hidden;
  border-radius: var(--radius-lg);
  margin-bottom: 2rem;
  /* Shadow only renders while the image fits 100% inside the
     viewport — once any edge crosses out of view core.js drops
     the .is-fully-visible class and the shadow fades to none. */
  box-shadow: none;
  transition: box-shadow .2s ease;
}
.post-hero__image.is-fully-visible {
  box-shadow: var(--shadow-lg);
}
.post-hero__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Article body */
.post-body {
  min-width: 0;
}
/* Tail (tags, mobile-author, JCS CTA, related-posts, comments) sits
   OUTSIDE .post-body so the sidebar (which matches .post-body height
   via align-self: stretch) and .post-hero-stack release at end of
   .post-content. Spans full grid width on desktop; flows naturally
   on mobile single-column. */
.post-body-tail {
  min-width: 0;
  margin-top: 2.5rem;
}
@media (min-width: 1080px) {
  .post-body-tail { grid-column: 1 / -1; }
}
.post-content {
  font-size: 1.0625rem;
  line-height: 1.8;
  color: var(--text);
}
.post-content h2 {
  font-size: 1.5rem;
  margin-top: 2.5rem;
  margin-bottom: 1rem;
  padding-top: .5rem;
  border-top: 2px solid var(--teal-light);
  color: var(--teal);
}
.post-content h3 {
  font-size: 1.2rem;
  margin-top: 2rem;
  margin-bottom: .75rem;
}
.post-content h4 { margin-top: 1.5rem; margin-bottom: .5rem; }

/* ─────────────────────────────────────────────────────────────────
   Outline numbering for headings inside .post-content
   h2 → "1."         "2."        ...
   h3 → "1.1"        "1.2"       ... (resets per h2)
   h4 → "1.1.1"      "1.1.2"     ... (resets per h3)
   h5 → "1.1.1.1"    ...         (resets per h4)
   h6 → "1.1.1.1.1"  ...
   The numeric prefix is rendered as a teal accent so it reads as a
   navigational tag, distinct from the heading text. */
.post-content { counter-reset: jh2 jh3 jh4 jh5 jh6; }
/* Counter-reset MUST live on the section wrappers, not on the heading
   itself. Body content wraps each H2 in <section class="post-section">
   and each H3 in a sibling <section class="post-subsection">. CSS
   counter scope = element + descendants + following-siblings, so a
   reset declared on h2 only reaches h2's siblings *inside* the same
   post-section — not the H3 that lives in the next post-subsection.
   Moving the reset to .post-section / .post-subsection makes each new
   wrapper start a fresh counter scope visible to all following sibling
   sections (the H3-bearing post-subsections that come after each H2). */
.post-content .post-section    { counter-reset: jh3 jh4 jh5 jh6; }
.post-content .post-subsection { counter-reset: jh4 jh5 jh6; }
.post-content h2 { counter-increment: jh2; }
.post-content h3 { counter-increment: jh3; }
.post-content h4 { counter-increment: jh4; counter-reset: jh5 jh6; }
.post-content h5 { counter-increment: jh5; counter-reset: jh6; }
.post-content h6 { counter-increment: jh6; }
.post-content h2::before {
  content: counter(jh2) ". ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
.post-content h3::before {
  content: counter(jh2) "." counter(jh3) " ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
.post-content h4::before {
  content: counter(jh2) "." counter(jh3) "." counter(jh4) " ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
.post-content h5::before {
  content: counter(jh2) "." counter(jh3) "." counter(jh4) "." counter(jh5) " ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
.post-content h6::before {
  content: counter(jh2) "." counter(jh3) "." counter(jh4) "." counter(jh5) "." counter(jh6) " ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
/* FAQ block (.jacar-faq) is a separate semantic Q&A surface — its H2
   ("Preguntas frecuentes") and Q-row H3s are NOT part of the article
   outline. Skip the increment so the next regular H2 doesn't jump,
   and suppress the ::before prefix entirely. */
.post-content .jacar-faq h2,
.post-content .jacar-faq h3,
.post-content .jacar-faq h4,
.post-content .jacar-faq h5,
.post-content .jacar-faq h6 {
  counter-increment: none;
}
.post-content .jacar-faq h2::before,
.post-content .jacar-faq h3::before,
.post-content .jacar-faq h4::before,
.post-content .jacar-faq h5::before,
.post-content .jacar-faq h6::before {
  content: none;
}
.post-content p,
.post-content li {
  text-align: justify;
  /* hyphens: auto softens the ragged inter-word gaps that justify
     otherwise produces; relies on the lang attribute on <html>
     (set by WPGlobus per language) for the right break dictionary.
     Tuned to be rare:
     - hyphenate-limit-lines: 1
       Forbids two consecutive lines ending in a hyphen. With normal
       6-8 line paragraphs this approximates "no more than ~1 hyphen
       every 5 lines" — the engine simply can't cluster them.
     - hyphenate-limit-chars: 10 4 4
       Only words ≥10 chars hyphenate, and the leading/trailing
       fragment must be ≥4 chars — so short words and last-resort
       splits are skipped, leaving long technical terms to break
       only when they really need it. */
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-lines: 1;
  -webkit-hyphenate-limit-lines: 1;
  hyphenate-limit-chars: 10 4 4;
  -webkit-hyphenate-limit-before: 4;
  -webkit-hyphenate-limit-after: 4;
}
.post-content p { margin-bottom: 1.25em; }
.post-content a { text-decoration: underline; text-underline-offset: 3px; }
.post-content a:hover { color: var(--teal-hover); }
.post-content img {
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin: 1.5rem auto;
}
.post-content ul, .post-content ol { margin-bottom: 1.25em; }
.post-content li { margin-bottom: .4em; }
.post-content > *:last-child { margin-bottom: 0; }

/* ============================================================
   POST SIDEBAR (desktop left column) — author card + TOC.
   Author card and TOC are independently sticky so each one stays
   visible until the next scrolls under it. Standard rhythm gap
   between the two cards. Hidden on mobile (uses
   .author-box-mobile-wrap + .toc-mobile instead).
   ============================================================ */
.post-sidebar {
  display: none;
}
.post-sidebar__toc { margin-top: var(--rhythm-block, 1.5rem); }
/* Base top offset for the desktop sidebar's sticky cards. Pins below
   the .post-hero-stack line with a 24px breathing gap so the author
   card sits clear of the hero.
   IMPORTANT: --sidebar-base-top must be re-declared on .admin-bar.
   var() inside a custom property is substituted at the element where
   the property is declared, not at the element using it. Declared on
   :root, var(--sticky-top) resolves to 62px (`.admin-bar` is on body,
   not html) and the computed `calc(62px + 24px)` inherits down — the
   94/108px admin-bar override of --sticky-top never reaches the calc.
   The .admin-bar declaration below re-evaluates the calc against the
   body-level --sticky-top so author + TOC pin under both header AND
   admin-bar with the 24px gap. */
:root      { --sidebar-base-top: calc(var(--sticky-top) + 24px); }
.admin-bar { --sidebar-base-top: calc(var(--sticky-top) + 24px); }
/* ── Stacking sticky headings inside single-post content ──
   The post's own H1/H2/H3 stick progressively as you scroll:
   - H1 (post title) sticks below the site header
   - H2 sticks below H1 (within its post-section wrapper)
   - H3 sticks below H2 (within its post-subsection wrapper)
   Only spans the post column — natural flow controls width. */
:root {
  --sticky-top:        62px;
  --sticky-h1-height:  60px;
  --sticky-h2-height:  44px;
  --sticky-h3-height:  40px;
}
.admin-bar { --sticky-top: 94px; }
@media (max-width: 782px) { .admin-bar { --sticky-top: 108px; } }

.post-hero__title {
  position: sticky;
  top: var(--sticky-top);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  margin: 0 0 1rem;
  padding: .5rem 0;
  z-index: 12;
}

.post-content .post-section {
  position: relative;
}
.post-content .post-section h2 {
  /* Anchor-scroll offset is handled by the page-level scroll-padding-top
     override on body.is-single (see rule below). H2 itself needs no
     scroll-margin-top — once the page is scroll-padded for the post-hero
     stack, the H2 anchor lands immediately under the pinned H1 band. */
  position: sticky;
  top: calc(var(--sticky-top) + var(--sticky-h1-height) - 1px);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  margin: 0;
  padding: .5rem 0;
  z-index: 11;
  border-bottom: 1px solid var(--border-faint);
}
/* Pinned state — JS toggles .is-pinned when the H2 reaches its
   sticky line (see core.js). Drop the inherited 2px teal top border
   so the floating pinned header reads as a clean strip; the
   border-bottom stays as the visual separator from the body text. */
.post-content .post-section h2.is-pinned {
  border-top: 0;
}
/* H3 anchor target lands below BOTH the post-hero stack AND the pinned
   H2 above it, so the leading H2 of the section stays visible while
   the H3 sits at the start of its subsection. body.is-single already
   raises scroll-padding-top to var(--sticky-h1-height); the extra
   var(--sticky-h2-height) is the additional clearance for the pinned
   H2 strip that sits above this H3 once the section is in view.
   The scroll-margin lives on the wrapper (the actual anchor target —
   id is moved here by wrapGroups in core.js) rather than on the
   sticky H3 itself, so the browser's anchor scroll computes the
   landing position from the wrapper's natural docY. */
.post-content .post-subsection {
  position: relative;
  scroll-margin-top: var(--sticky-h2-height, 56px);
}
.post-content .post-subsection h3 {
  position: sticky;
  top: calc(var(--sticky-top) + var(--sticky-h1-height) + var(--sticky-h2-height) - 5px);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  margin: 0;
  padding: .4rem 0;
  z-index: 10;
}

/* Keep normal vertical rhythm between the sticky headings and following paragraphs */
.post-content .post-section > * + * { margin-top: 1rem; }
.post-content .post-subsection > * + * { margin-top: .75rem; }

@media (min-width: 1080px) {
  .post-sidebar {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    margin-top: 0;
    /* The parent .single-wrap is `display: grid; align-items: start`,
       which would shrink this column to its content's natural height.
       That is fatal for `position: sticky` children: once the user
       scrolls past the column's bottom, the children stop sticking.
       align-self: stretch overrides align-items, so the column matches
       the article body's full height — and the sticky children stay
       sticky for the entire article. */
    align-self: stretch;
  }
  .author-box-mobile-wrap { display: none; }

  /* Independent sticky stack. Both cards pin at top:70px (below the
     site header). Document-flow does the stacking: the author-box
     pins first; the TOC's natural position is below it, and when the
     TOC scrolls up its bottom edge stays under the still-pinned
     author card. No JS needed for the stacking. Each card has its
     own max-height + overflow:auto so a long TOC can scroll inside
     its own card without breaking the page scroll. */
  .post-sidebar .author-box {
    /* Sticky, but no internal scroll — author card flows at its
       natural height. */
    position: sticky;
    top: var(--sidebar-base-top);
    margin-top: 0;
  }
  .post-sidebar__toc {
    /* TOC is sticky too, pinned BELOW the still-pinned author card.
       event-handlers.js sets --post-sidebar-toc-top to
       (author-card-height + sidebar-base-top + gap)px; the
       --sidebar-base-top fallback covers the brief moment before JS
       runs (TOC overlaps author until measurement lands). Capped to
       the viewport with overflow-y so a long TOC doesn't run off
       screen. */
    position: sticky;
    top: var(--post-sidebar-toc-top, var(--sidebar-base-top));
    margin-top: 0;
    max-height: calc(100vh - var(--post-sidebar-toc-top, var(--sidebar-base-top)) - 20px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* Subtle custom scrollbar on the TOC (the only sidebar card that
     scrolls internally — author card flows at natural height). */
  .post-sidebar__toc::-webkit-scrollbar { width: 4px; }
  .post-sidebar__toc::-webkit-scrollbar-track { background: transparent; }
  .post-sidebar__toc::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
}

.toc {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
}
.toc__title {
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-faint);
  margin-bottom: .75rem;
  display: flex;
  align-items: center;
  gap: .4rem;
}
.toc__title svg { width: 14px; height: 14px; }
.toc__list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: .875rem;
  line-height: 1.4;
}
.toc__list li { margin: 0; padding: 0; }
.toc__list a {
  display: block;
  padding: .3rem .5rem;
  border-radius: 5px;
  color: var(--text-muted);
  transition: color var(--t), background var(--t);
  border-left: 2px solid transparent;
  margin-left: calc(var(--depth, 0) * 1rem);
}
.toc__list a:hover, .toc__list a.active {
  color: var(--teal);
  background: var(--teal-lighter);
  border-left-color: var(--teal);
}
.toc__list li.toc-h3 > a { --depth: 1; font-size: .8125rem; }

/* Outline numbering for TOC entries — mirrors the .post-content
   counter cascade so entries read 1., 1.1, 1.1.1, … and match the
   numbered headings in the article body. The number is rendered as
   a teal accent and inserted at the start of the link text via a
   ::before pseudo on the <a>, so hover/focus state still covers
   the full row including the prefix. */
.toc__list { counter-reset: tocH2 tocH3 tocH4 tocH5 tocH6; }
/* Use counter-set (not counter-reset) on the heading LIs. The TOC is a
   flat <ol> where toc-h2 / toc-h3 LIs are siblings, not nested. With
   counter-reset on a sibling LI, browsers create a NEW counter scoped
   to that LI's parent — but the scope-resolution for following siblings
   in a flat list ends up reading the OUTERMOST counter (the one created
   on the OL), so subsequent H3s under a new H2 keep counting from the
   prior value (4.5, 4.6, 4.7…). counter-set explicitly sets the
   existing OL-level counter back to 0, which propagates to following
   siblings as expected — H3 numbering becomes 4.1, 4.2, 4.3 then
   5.1, 5.2 on the next H2 group. */
.toc__list li.toc-h2 { counter-increment: tocH2; counter-set: tocH3 0 tocH4 0 tocH5 0 tocH6 0; }
.toc__list li.toc-h3 { counter-increment: tocH3; counter-set: tocH4 0 tocH5 0 tocH6 0; }
.toc__list li.toc-h4 { counter-increment: tocH4; counter-set: tocH5 0 tocH6 0; }
.toc__list li.toc-h5 { counter-increment: tocH5; counter-set: tocH6 0; }
.toc__list li.toc-h6 { counter-increment: tocH6; }
.toc__list li.toc-h2 > a::before {
  content: counter(tocH2) ". ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
}
/* H3 entries echo the body-content nested format: "<h2>.<h3>" — counter
   cascade flows across flat <ol> siblings in document order, so the
   tocH3 reset on each .toc-h2 correctly restarts numbering inside each
   H2 group (1.1, 1.2, …, 2.1, 2.2, …). H4–H6 entries don't appear in
   the TOC (jacar_get_toc only emits depth ≤ 3), so we don't render
   prefixes for them; if that ever changes, extend with the same
   nested counter() chain used in .post-content. */
.toc__list li.toc-h3 > a::before {
  content: counter(tocH2) "." counter(tocH3) " ";
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  margin-right: .35em;
  font-size: .92em;
}
/* FAQ items echoed in the TOC: same exclusion as in the article body
   — no outline number, no counter increment. */
.toc__list li.toc-faq { counter-increment: none; }
.toc__list li.toc-faq > a::before { content: none; }

/* Mobile TOC (accordion above content) */
.toc-mobile {
  display: block;
  margin-bottom: 2rem;
}
@media (min-width: 1080px) { .toc-mobile { display: none; } }
.toc-mobile details {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.toc-mobile summary {
  padding: .75rem 1rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
  justify-content: space-between;
}
.toc-mobile summary::-webkit-details-marker { display: none; }
.toc-mobile summary svg { width: 16px; height: 16px; transition: transform var(--t); }
.toc-mobile details[open] summary svg.chevron { transform: rotate(180deg); }
.toc-mobile .toc__list { padding: .5rem 1rem 1rem; }

/* ============================================================
   PAGINATION
   ============================================================ */
.pagination {
  display: flex;
  gap: .5rem;
  justify-content: center;
  align-items: center;
  padding: 3rem 0 1rem;
  flex-wrap: wrap;
}
.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding: 0 .75rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: .9375rem;
  font-weight: 500;
  transition: all var(--t);
}
.pagination .page-numbers:hover,
.pagination .page-numbers.current {
  background: var(--teal);
  border-color: var(--teal);
  color: #fff;
}

/* ============================================================
   CATEGORY BAR — per-card icon polish (.cat-bar__icon)
   ============================================================ */
.cat-bar-section {
  padding: 2.5rem 0 1rem;
  background: var(--bg);
  overflow: visible;
}

.cat-bar {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  padding: .5rem 0 .75rem;
}
.cat-bar::-webkit-scrollbar { display: none; }

.cat-bar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  text-decoration: none;
  flex-shrink: 0;
  scroll-snap-align: start;
  padding-top: 4px;
  transition: transform var(--t);
}
.cat-bar__item:hover { transform: translateY(-3px); }

.cat-bar__icon {
  position: relative;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--teal);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background var(--t), box-shadow var(--t);
}
.cat-bar__item:hover .cat-bar__icon {
  background: var(--teal-dark);
  box-shadow: 0 6px 20px rgba(43, 138, 148, .28);
}
.cat-bar__icon svg { width: 26px; height: 26px; }
/* Per-icon size tuning — some Tabler paths have less visual mass than others */
.cat-bar__icon svg[data-icon="brain"]      { width: 30px; height: 30px; }
.cat-bar__icon svg[data-icon="tools"]      { width: 30px; height: 30px; }
.cat-bar__icon svg[data-icon="user"]       { width: 28px; height: 28px; }
.cat-bar__icon svg[data-icon="git-branch"] { width: 28px; height: 28px; }
.cat-bar__icon svg[data-icon="code"]       { width: 28px; height: 28px; }

.cat-bar__name {
  font-size: .75rem;
  font-weight: 600;
  color: var(--text);
  text-align: center;
  max-width: 76px;
  line-height: 1.3;
  transition: color var(--t);
}
.cat-bar__item:hover .cat-bar__name { color: var(--teal); }

.cat-bar__count {
  position: absolute;
  top: -4px;
  right: -8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 .35rem;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-size: .65rem;
  font-weight: 700;
  line-height: 1;
  border: 2px solid var(--bg);
  box-shadow: 0 1px 4px rgba(0,0,0,.18);
}

/* ============================================================
   ARCHIVE CONTROLS BAR — view-mode pill, sort select, reset
   ============================================================ */
.archive-ctrls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  padding: .85rem 1rem;
  margin-bottom: 1.5rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.ctrl-pill {
  display: inline-flex;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.ctrl-pill__btn {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .75rem;
  background: transparent;
  border: 0;
  border-radius: 999px;
  color: var(--text-muted);
  font-size: .8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.ctrl-pill__btn svg { width: 15px; height: 15px; }
.ctrl-pill__btn:hover { color: var(--text); }
.ctrl-pill__btn[aria-pressed="true"] {
  background: var(--teal);
  color: #fff;
}

.ctrl-select {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .8125rem;
  color: var(--text-muted);
}
.ctrl-select__label { font-weight: 500; }
.ctrl-select__input {
  padding: .35rem .65rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: .8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--t);
}
.ctrl-select__input:hover,
.ctrl-select__input:focus { border-color: var(--teal); outline: none; }

.ctrl-reset {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .35rem .75rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  font-size: .8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.ctrl-reset svg { width: 14px; height: 14px; }
.ctrl-reset:hover {
  background: color-mix(in srgb, var(--teal) 10%, transparent);
  border-color: var(--teal);
  color: var(--teal);
}

@media (max-width: 640px) {
  .archive-ctrls { padding: .65rem .75rem; }
  .ctrl-select__label { display: none; }
  .ctrl-reset { margin-left: 0; }
}

/* ============================================================
   CTA COMPONENT — Jacar Systems cross-promotion (was jcs-cta.css)
   Loaded site-wide via inc/jcs-links.php hook (now via this file).
   ============================================================ */

/* ── Header "Empresa / Company" pill ─────────────────── */
.primary-nav__company {
  display: inline-flex;
  align-items: center;
  margin-left: 0.75rem;
  padding: 0.4rem 0.85rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--lime-bg);
  border: 1px solid var(--lime);
  border-radius: var(--radius);
  text-decoration: none;
  transition: background 150ms ease, transform 150ms ease;
}
.primary-nav__company:hover {
  background: var(--lime);
  color: var(--text);
  transform: translateY(-1px);
}
.mobile-nav .primary-nav__company {
  display: block;
  margin: 0 0 1rem;
  text-align: center;
}

/* ── End-of-content / lab-panel CTA card ────────────── */
.jcs-cta {
  margin: 2.5rem auto;
  max-width: var(--w-content);
  padding: 1.5rem 1.5rem 1.25rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-left: 4px solid var(--teal);
  border-radius: var(--radius);
}
.jcs-cta__eyebrow {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--teal-dark);
  font-weight: 600;
}
.jcs-cta__body {
  margin: 0 0 1rem;
  color: var(--text);
  line-height: 1.55;
}
.jcs-cta__link {
  display: inline-block;
  font-weight: 600;
  color: var(--teal-dark);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}
.jcs-cta__link:hover {
  color: var(--teal-hover);
}

/* ── Sobre page comparison panel ────────────────────── */
.sobre-compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  margin: 2rem auto;
  max-width: var(--w-content);
}
@media (max-width: 640px) {
  .sobre-compare { grid-template-columns: 1fr; }
}
.sobre-compare__col {
  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.sobre-compare__col h3 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}
.sobre-compare__col ul {
  margin: 0; padding-left: 1.25rem;
  color: var(--text-muted);
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .primary-nav__company { transition: none; transform: none !important; }
}

/* ============================================================
   NEWSLETTER SHORTCODE — [newsletter-signup] form
   (was newsletter-shortcode.css)
   ============================================================ */
.jacar-newsletter-signup {
    display: block;
    max-width: 34rem;
    margin: 1.5rem 0;
}
.jacar-newsletter-signup__label {
    display: block;
    font-weight: 600;
    margin-bottom: .5rem;
    color: inherit;
}
.jacar-newsletter-signup__row {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}
.jacar-newsletter-signup__input {
    flex: 1 1 14rem;
    padding: .55rem .8rem;
    border: 1px solid currentColor;
    border-radius: .4rem;
    background: transparent;
    color: inherit;
    font: inherit;
}
.jacar-newsletter-signup__input:focus-visible {
    outline: 2px solid #3db8c5;
    outline-offset: 2px;
}
.jacar-newsletter-signup__btn {
    padding: .55rem 1.1rem;
    border: 0;
    border-radius: .4rem;
    background: #3db8c5;
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.jacar-newsletter-signup__btn:hover { filter: brightness(1.08); }
.jacar-newsletter-signup__btn:disabled { opacity: .6; cursor: progress; }
.jacar-newsletter-signup__status {
    margin: .5rem 0 0;
    min-height: 1.25rem;
    font-size: .9rem;
}
.jacar-newsletter-signup__status.is-success { color: #56a356; }
.jacar-newsletter-signup__status.is-error   { color: #c65353; }
.jacar-newsletter-signup__status.is-loading { opacity: .7; }

/* ============================================================
   RELATED-TAGS CHIPS — under archive controls bar
   ============================================================ */
.ctrl-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  margin: -.5rem 0 1.5rem;
  padding-bottom: .5rem;
}
.ctrl-tags__label {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--text-faint);
  margin-right: .5rem;
}
.ctrl-tags__label svg { width: 13px; height: 13px; }

.ctrl-tag {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .22rem .6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1.4;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.ctrl-tag:hover {
  border-color: var(--teal);
  color: var(--teal);
  background: color-mix(in srgb, var(--teal) 8%, transparent);
}
.ctrl-tag.is-active {
  background: var(--teal);
  color: #fff;
  border-color: var(--teal);
}
.ctrl-tag.is-active::after {
  content: '×';
  font-weight: 700;
  font-size: .9rem;
  line-height: 1;
  margin-left: .1rem;
}
.ctrl-tag__count {
  font-size: .65rem;
  font-weight: 700;
  opacity: .65;
  font-variant-numeric: tabular-nums;
}
.ctrl-tag.is-active .ctrl-tag__count { opacity: .85; }

/* ============================================================
   READING PROGRESS BAR (post-reading UX widget)
   Pure CSS via scroll-driven animation — `width` animates 0→100%
   bound to the document scroll-timeline. No JS scroll listener,
   nothing to throttle, no main-thread work per frame: the browser
   compositor advances the animation as the scrollbar moves so
   scrollbar-drag stays fluid even on long posts.
   ============================================================ */
#jacar-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 0%;
  height: 3px;
  background: linear-gradient(90deg, var(--teal), var(--lime));
  z-index: 9999;
  pointer-events: none;
}
@keyframes jacar-progress-fill {
  from { width: 0%; }
  to   { width: 100%; }
}
@supports (animation-timeline: scroll()) {
  #jacar-progress {
    animation: jacar-progress-fill linear both;
    animation-timeline: scroll(root block);
  }
}
.admin-bar #jacar-progress { top: 32px; }
@media screen and (max-width: 782px) { .admin-bar #jacar-progress { top: 46px; } }

/* ============================================================
   AUTHOR BOX — sectioned column layout (4 blocks).
   1. .author-box__header  : photo (col 1) + "Escrito por" valigned to
                             photo bottom (col 2).
   2. .author-box__id      : centered name + role.
   3. .author-box__bio     : full-width description; collapses to height
                             0 when .author-box has .is-compact (added
                             by event-handlers.js once the user has
                             scrolled into the article body).
   4. .author-box__links   : centered link buttons.
   ============================================================ */
.author-box {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.25rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  margin-top: 0;
}
.author-box__hero {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: .9rem;
}
.author-box__avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--teal-light);
  box-shadow: 0 0 0 2px var(--teal);
}
.author-box__label {
  font-size: .65rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-faint);
  font-weight: 700;
  margin: 0;
}
.author-box__id {
  text-align: center;
  display: flex;
  flex-direction: column;
  /* label · name · role stacked tight */
  gap: .15rem;
  min-width: 0;
}
.author-box__name {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  margin: 0;
}
.author-box__name a { color: var(--text); }
.author-box__name a:hover { color: var(--teal); }
.author-box__role {
  font-size: .8rem;
  color: var(--text-muted);
  margin: 0;
}
.author-box__bio {
  font-size: .9rem;
  color: var(--text-muted);
  line-height: 1.55;
  /* Match .post-content p/li typography: justify with sparse,
     non-clustered hyphenation for long technical words. */
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-lines: 1;
  -webkit-hyphenate-limit-lines: 1;
  hyphenate-limit-chars: 10 4 4;
  -webkit-hyphenate-limit-before: 4;
  -webkit-hyphenate-limit-after: 4;
  /* Collapse animation. JS used to toggle `.is-compact` on the parent
     based on scrollY > 240 — that ran on every scroll frame. Now the
     bio's max-height/opacity are bound directly to the document
     scroll-timeline, animating 0–240 px of scroll. The compositor
     advances it without main-thread JS, so scrollbar drag stays
     fluid. The `.is-compact` class fallback is kept below for
     browsers without scroll-driven animations. */
  max-height: 320px;
  opacity: 1;
  overflow: hidden;
  transition: max-height .35s ease, opacity .25s ease, margin .25s ease;
}
.author-box.is-compact .author-box__bio {
  max-height: 0;
  opacity: 0;
  margin: 0;
}
@keyframes jacar-bio-collapse {
  from { max-height: 320px; opacity: 1; margin-bottom: 1rem; }
  to   { max-height: 0;     opacity: 0; margin: 0; }
}
@media (min-width: 1080px) {
  @supports (animation-timeline: scroll()) {
    .author-box__bio {
      animation: jacar-bio-collapse linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 240px;
    }
  }
}
/* Author card footer: 2 columns side by side. Left column = three
   tiny "number + label" stat rows stacked vertically. Right column
   = three icon-link chips stacked vertically. Sidebar inner width
   is ~206px; left col absorbs the slack while the right col stays
   at its content width (a single chip's worth ≈ 28px). */
.author-box__footer {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: space-between;
  gap: .75rem;
  border-top: 1px solid var(--border);
  padding-top: .75rem;
  margin-top: 0;
}

/* Stats column wider than the prior 1/3 — flex-grow 7 vs 8 splits
   the row 7/15 : 8/15 (≈47%:53%), shrinking the links column to 4/5
   of its former 2/3 width. */
.author-box__stats {
  display: flex;
  flex-direction: column;
  /* Vertically centered within the footer row. */
  justify-content: center;
  gap: .25rem;
  align-items: stretch;
  flex: 1 1 0;
  /* Stats column wider than the links column (was 7/15; now 10/15
     ≈67%). */
  flex-grow: 10;
  min-width: 0;
}
.author-box__stat {
  display: flex;
  /* row-reverse + space-between: HTML keeps the semantic
     "<strong>number</strong><em>label</em>" order, but visually
     the row reads "label flush left, number flush right" — giving
     a clean right-aligned column of numbers across the three rows. */
  flex-direction: row-reverse;
  justify-content: space-between;
  /* Vertically centred — was `baseline`, which made the rating row
     (taller star glyphs) drop the label below the number. */
  align-items: center;
  gap: .5rem;
  padding: 0;
  border: 0;
  line-height: 1.15;
}
.author-box__stat strong {
  font-size: .75rem;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.author-box__stat em {
  font-style: normal;
  font-size: .68rem;
  /* Capitalised in markup ("Artículos", "Lecturas", "Rating");
     don't lowercase them at render time. */
  letter-spacing: .01em;
  /* Accent color: the brand teal at lower opacity, distinct from the
     bold number's --text on the same row. */
  color: var(--teal);
  opacity: .8;
}

/* Rating row: stars instead of a number. (.author-box__stat already
   sets align-items: center; no extra override needed here.) */
.author-box__stars {
  position: relative;
  display: inline-block;
  font-size: .85rem;
  line-height: 1;
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}
.author-box__stars-track {
  color: var(--border);
}
.author-box__stars-fill {
  position: absolute;
  inset: 0;
  overflow: hidden;
  white-space: nowrap;
  /* Amber that reads well on light + dark themes; YASR-style yellow
     for filled stars. */
  color: #f5b50a;
  /* width is set inline via style="width: NN%" from the rating */
}

/* Right column 8/15 (≈53%) — icon chips in two rows. */
.author-box__links {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  flex: 1 1 0;
  flex-grow: 8;
  align-items: flex-end;
  justify-content: center;
  margin: 0;
}
.author-box__links-row {
  display: flex;
  flex-direction: row;
  gap: .35rem;
  align-items: center;
}
/* Author-card icon buttons — physical "real button" feel.
   Resting state: solid surface card, soft border, faint drop shadow
   (depth). Hover: lifts up 2px, fills with brand teal, white icon,
   bigger shadow + outer ring. Active: presses back down with a small
   scale-down. focus-visible exposes a 2px teal ring. */
.author-box__footer .author-box__link--icon {
  /* Pixel-perfect icon centering. display + align/justify-center +
     line-height 1 + box-sizing border-box guarantee the icon sits
     dead-centre regardless of its intrinsic size, the chip's border,
     or any inherited line-height. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  box-sizing: border-box;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-muted);
  border-radius: 50%;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, .07),
    inset 0 -1px 0 rgba(0, 0, 0, .04);
  transition:
    transform   .18s cubic-bezier(.22, 1.5, .36, 1),
    background  .2s ease,
    color       .2s ease,
    border-color .2s ease,
    box-shadow  .25s ease;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.author-box__footer .author-box__link--icon:hover {
  background: var(--teal);
  border-color: var(--teal);
  color: #fff;
  transform: translateY(-2px);
  box-shadow:
    0 8px 16px -4px rgba(43, 138, 148, .45),
    0 0 0 4px rgba(43, 138, 148, .14);
}
.author-box__footer .author-box__link--icon:active {
  transform: translateY(0) scale(.95);
  box-shadow:
    0 2px 4px rgba(43, 138, 148, .35),
    0 0 0 0 rgba(43, 138, 148, 0);
  transition-duration: .08s;
}
.author-box__footer .author-box__link--icon:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}
/* Glyph sizing — `display: block` + `flex: 0 0 auto` + `vertical-align`
   reset prevent any inline-baseline drift inside the flex chip. The
   Jacar brand mark (.author-box__link--brand svg) is rendered larger
   than the Tabler glyphs since its star/triangle silhouette reads
   smaller at the same nominal size. */
.author-box__footer .author-box__link--icon svg {
  display: block;
  flex: 0 0 auto;
  vertical-align: middle;
  width: 18px;
  height: 18px;
}
.author-box__footer .author-box__link--icon.author-box__link--brand svg {
  width: 22px;
  height: 22px;
}
.author-box__link {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .8125rem;
  font-weight: 600;
  padding: .3rem .7rem;
  border-radius: 20px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  transition: color var(--t), background var(--t), border-color var(--t);
}
.author-box__link svg { width: 14px; height: 14px; }
.author-box__link:hover {
  color: var(--teal);
  border-color: var(--teal);
  background: var(--teal-lighter);
}

/* Icon-only variant — circle, label moves to title/aria-label tooltip. */
.author-box__link--icon {
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  justify-content: center;
  gap: 0;
}
.author-box__link--icon svg { width: 16px; height: 16px; }
.author-box__link--icon img {
  width: 18px;
  height: 18px;
  display: block;
  /* The brand favicon has its own colours; don't tint on hover. */
}
.author-box__link--brand:hover {
  /* Brand-coloured glyph stays as-is; only soften the chip background. */
  background: var(--teal-lighter);
  border-color: var(--teal);
}

/* ============================================================
   FAQ SECTION (block component)
   ============================================================ */
.jacar-faq {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 2px solid var(--lime);
}
.jacar-faq h2 {
  font-size: 1.4rem;
  margin-bottom: 1.5rem;
  display: flex;
  align-items: center;
  gap: .5rem;
  border-top: none;
  padding-top: 0;
}
.jacar-faq h2::before {
  content: '';
  display: inline-block;
  width: 24px;
  height: 24px;
  background: var(--lime);
  border-radius: 6px;
  flex-shrink: 0;
}
.jacar-faq-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: .75rem;
  overflow: hidden;
  transition: border-color var(--t), box-shadow var(--t);
}
.jacar-faq-item:hover {
  border-color: var(--teal-light);
  box-shadow: var(--shadow-sm);
}
.jacar-faq-item h3 {
  font-size: 1rem;
  padding: 1rem 1.25rem;
  margin: 0;
  cursor: pointer;
  background: var(--bg-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .75rem;
  transition: background var(--t);
  border-bottom: 1px solid transparent;
  line-height: 1.4;
}
.jacar-faq-item h3:hover { background: var(--teal-lighter); color: var(--teal); }
.jacar-faq-item p {
  padding: 1rem 1.25rem;
  color: var(--text-muted);
  font-size: .9375rem;
  line-height: 1.7;
  margin: 0;
  border-top: 1px solid var(--border-faint);
}

/* ============================================================
   RELATED POSTS (post-bottom widget)
   ============================================================ */
.related-posts {
  margin-top: 4rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--border);
}
.related-posts__title {
  font-size: 1.3rem;
  margin-bottom: 1.5rem;
}
.related-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.25rem;
}

/* ============================================================
   SEARCH FORM (reusable form component)
   ============================================================ */
.search-form-wrap {
  max-width: 560px;
  margin: 0 auto;
}
.search-field-group {
  display: flex;
  border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg);
  transition: border-color var(--t);
}
.search-field-group:focus-within { border-color: var(--teal); }
.search-field-group input {
  flex: 1;
  padding: .75rem 1rem;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 1rem;
}
.search-field-group input:focus { outline: none; }
.search-field-group button {
  padding: .75rem 1.25rem;
  background: var(--teal);
  border: none;
  color: #fff;
  font-weight: 600;
  font-size: .9375rem;
  cursor: pointer;
  transition: background var(--t);
}
.search-field-group button:hover { background: var(--teal-hover); }

/* ============================================================
   POST-BOTTOM RESPONSIVE TWEAKS (mobile, ≤640px) — migrated from
   style.css §22.
   ============================================================ */
@media (max-width: 640px) {
  .post-hero__title { font-size: 1.5rem; }
  .author-box { flex-direction: column; align-items: center; text-align: center; }
  .author-box__links { justify-content: center; }
}

/* ============================================================
   ORPHAN HUB — supplemental "Más en esta categoría" block
   rendered by inc/category-orphan-hub.php on home + category
   archives. Minimal styling so it reads as an intentional section.
   ============================================================ */
.orphan-hub {
  max-width: var(--w-content, 740px);
  margin: 3rem auto 1.5rem;
  padding: 0 1.25rem;
}
.orphan-hub > details {
  border-top: 1px solid var(--border, rgba(127,127,127,0.18));
  padding-top: 1rem;
}
.orphan-hub summary {
  font-family: var(--font-heading, 'Inter Tight', system-ui, sans-serif);
  font-size: 1rem;
  font-weight: 600;
  color: var(--text, currentColor);
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  user-select: none;
}
.orphan-hub summary::-webkit-details-marker { display: none; }
.orphan-hub summary::before {
  content: "›";
  display: inline-block;
  font-size: 1.1em;
  line-height: 1;
  transition: transform 150ms ease;
  color: var(--text-faint, var(--text, currentColor));
}
.orphan-hub > details[open] summary::before { transform: rotate(90deg); }
.orphan-hub ul {
  margin: 0.85rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.35rem 1rem;
}
@media (min-width: 720px) {
  .orphan-hub ul { grid-template-columns: 1fr 1fr; }
}
.orphan-hub li {
  font-size: 0.93rem;
  line-height: 1.45;
}
.orphan-hub a {
  color: var(--text-muted, var(--text, currentColor));
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 150ms ease, border-color 150ms ease;
}
.orphan-hub a:hover {
  color: var(--teal, currentColor);
  border-bottom-color: var(--teal, currentColor);
}

/* ============================================================
   GEO content-shape blocks (Phase α — spec 2026-05-04)
   ============================================================ */

.cp-quick-answer {
  margin: 0 0 1.5rem 0;
  padding: 1rem 1.25rem;
  border-left: 4px solid var(--teal);
  background: var(--teal-lighter);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 1rem;
  line-height: 1.6;
}
.cp-quick-answer p { margin: 0; }

.cp-updated {
  margin: 0 0 1rem 0;
  font-size: .875rem;
  color: var(--text-muted);
  font-style: italic;
}

.cp-citations {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: .9375rem;
  list-style: decimal inside;
  color: var(--text-muted);
}
.cp-citations li {
  margin: .35rem 0;
  word-break: break-word;
}
.cp-citations li a {
  color: var(--teal);
  text-decoration: underline;
}

/* The renumbering markers inside the body. */
.post-content sup a,
.post-content sup {
  font-size: .75em;
  vertical-align: super;
  line-height: 0;
}
