/* GENERATED by web/scripts/build-article-css.mjs from assets/css/blog-redesign.css + blog-redesign-custom.css.
   Do not edit: change the sources (or templates-new/article.css for the new frame) and run `npm run build`. */
/* ============================================================
   BLOG — Single article + Archive
   Uses tokens.css + wishes-ui.css. No new colors invented.
   Container 1500px, Inter, brand violet.
   RTL-safe (logical properties everywhere it matters).
   ============================================================ */

/* Page background — same warm off-white as the site */

/* Reusable logo mark (matches Front Page lockup) */






/* ============================================================
   READING PROGRESS BAR (top, thin, sticky)
   ============================================================ */
.rp-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: rgba(189, 86, 56, 0.10);
  z-index: 80;
  pointer-events: none;
}
.rp-fill {
  height: 100%;
  width: 0%;
  background: var(--gradient-primary);
  transition: width 0.08s linear;
}

/* ============================================================
   ARTICLE LAYOUT
   ============================================================ */
.article-shell {
  max-width: 1500px;
  margin: 0 auto;
  padding: 1.5rem 2rem 2rem;
}

.article-grid {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 4rem;
  align-items: start;
}

/* ----- Sticky ToC (desktop) ----- */
.toc {
  position: sticky;
  top: 2rem;
  align-self: start;
}
.toc-card {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1.25rem 1.25rem 1rem;
}
.toc-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-text-muted);
  margin-bottom: 0.85rem;
}
.toc-list {
  list-style: none;
  padding: 0; margin: 0;
  counter-reset: toc;
}
.toc-list li { position: relative; }
.toc-list > li { counter-increment: toc; }
.toc-list a {
  display: block;
  padding: 0.5rem 0.75rem 0.5rem 2rem;
  font-size: 0.83rem;
  line-height: 1.4;
  color: var(--color-text-muted);
  text-decoration: none;
  border-radius: 8px;
  position: relative;
  transition: color 0.2s, background 0.2s;
}
.toc-list > li > a::before {
  content: counter(toc, decimal-leading-zero);
  position: absolute;
  left: 0.5rem;
  top: 0.5rem;
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--color-primary);
  opacity: 0.55;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}
.toc-list a:hover { color: var(--color-text-dark); background: rgba(189, 86, 56, 0.04); }
.toc-list a.is-active {
  color: var(--color-primary);
  background: var(--color-primary-light);
  font-weight: 600;
}
.toc-list a.is-active::before { opacity: 1; }
/* Nested */
.toc-list ol {
  list-style: none;
  padding: 0; margin: 0 0 0.25rem;
  border-left: 1px solid var(--color-border);
  margin-left: 1rem;
}
.toc-list ol a {
  padding: 0.35rem 0.6rem 0.35rem 0.85rem;
  font-size: 0.78rem;
}
.toc-list ol a::before { display: none; }
.toc-list ol a.is-active { background: transparent; color: var(--color-primary); border-left: 2px solid var(--color-primary); border-radius: 0; padding-left: 0.85rem; margin-left: -1px; }

.toc-meta {
  display: flex; gap: 0.5rem;
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--color-border);
  font-size: 0.74rem;
  color: var(--color-text-muted);
  align-items: center;
}
.toc-meta svg { vertical-align: -2px; margin-right: 2px; }

/* Mobile-only ToC: hidden on desktop */
.toc-mobile { display: none; }

/* ============================================================
   ARTICLE
   ============================================================ */
.article {
  max-width: 760px;
  width: 100%;
}

.breadcrumbs {
  font-size: 0.82rem;
  color: var(--color-text-muted);
  margin-bottom: 1.25rem;
}
.breadcrumbs a { color: var(--color-text-muted); text-decoration: none; display: inline-flex; align-items: center; min-height: 24px; }
.breadcrumbs a:hover { color: var(--color-primary); }
.breadcrumbs span.sep { margin: 0 0.5rem; opacity: 0.5; }

.article-head {
  margin-bottom: 2rem;
}
.article-meta {
  display: flex; align-items: center; gap: 0.65rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-bottom: 1rem;
}
.article-cat {
  background: var(--color-primary-light);
  color: var(--color-primary);
  padding: 0.22rem 0.7rem;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}
.meta-dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: 0.5; }

.article-title {
  font-size: clamp(2rem, 3.5vw, 2.85rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
  margin-bottom: 1rem;
  text-wrap: balance;
}
.article-lede {
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  margin-bottom: 1.75rem;
  text-wrap: pretty;
}

.article-author-row {
  display: flex; align-items: center; gap: 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--color-border);
}
.author-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-bg-light);
}
.author-name { font-size: 0.92rem; font-weight: 700; line-height: 1.2; }
.author-role { font-size: 0.78rem; color: var(--color-text-muted); }
.article-actions {
  margin-inline-start: auto;
  display: flex; gap: 0.4rem;
}

/* Hero figure */
.article-hero {
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 1.75rem;
  box-shadow: var(--shadow-md);
  aspect-ratio: 16/9;
}
.hero-img {
  width: 100%; height: 100%;
  background:
    radial-gradient(circle at 30% 40%, #ffd6c2 0%, transparent 35%),
    radial-gradient(circle at 70% 35%, #f3c9b8 0%, transparent 38%),
    radial-gradient(circle at 50% 80%, #ffeacf 0%, transparent 50%),
    linear-gradient(135deg, #fce8d8 0%, #f7e3da 100%);
}

/* ============================================================
   KEY TAKEAWAYS
   ============================================================ */
.key-takeaways {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1.5rem 1.75rem 1.5rem;
  margin-bottom: 2.25rem;
  position: relative;
  overflow: hidden;
}
.key-takeaways::before {
  content: "";
  position: absolute;
  inset-inline-start: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--gradient-primary);
}
.kt-head {
  display: flex; gap: 0.75rem;
  align-items: center;
  margin-bottom: 1rem;
}
.kt-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.kt-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-primary);
}
.kt-sub {
  font-size: 0.82rem;
  color: var(--color-text-muted);
  margin-top: 2px;
}
.kt-list {
  list-style: none;
  padding: 0; margin: 0;
  display: grid;
  gap: 0.65rem;
}
.kt-list li {
  position: relative;
  padding-inline-start: 1.6rem;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--color-text-dark);
}
.kt-list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.55rem;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0 0 0 4px var(--color-primary-light);
}
.kt-list strong { color: var(--color-text-dark); font-weight: 700; }

/* ============================================================
   ARTICLE BODY (long-form)
   ============================================================ */
.article-body { font-size: 1.05rem; }
.article-body h2 {
  font-size: 1.7rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.2;
  margin: 2.25rem 0 0.85rem;
  scroll-margin-top: 90px;
  text-wrap: balance;
}
.article-body h3 {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 1.5rem 0 0.65rem;
  scroll-margin-top: 90px;
}
.article-body p {
  font-size: 1.02rem;
  line-height: 1.75;
  color: var(--color-text-dark);
  margin-bottom: 1rem;
  text-wrap: pretty;
}

/* ============================================================
   CALLOUTS — quotes, before/after
   ============================================================ */
.callout {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1.25rem 1.5rem 1.25rem 1.5rem;
  margin: 1.75rem 0;
  position: relative;
  overflow: hidden;
}
.callout p {
  font-size: 1.08rem;
  line-height: 1.65;
  color: var(--color-text-dark);
  margin: 0;
  text-wrap: pretty;
}
.callout cite {
  display: block;
  margin-top: 0.65rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  font-style: normal;
}

.callout--quote {
  background: linear-gradient(135deg, #f7f4ff 0%, #faf6ec 100%);
  border-color: rgba(189, 86, 56, 0.18);
  padding-inline-start: 4rem;
  font-family: var(--font-primary);
}
.callout--quote .callout-mark {
  position: absolute;
  inset-inline-start: 1.1rem;
  top: 0.5rem;
  font-size: 3.5rem;
  line-height: 1;
  font-weight: 800;
  color: var(--color-primary);
  opacity: 0.35;
  font-family: Georgia, 'Times New Roman', serif;
}
.callout--quote p {
  font-size: 1.15rem;
  font-weight: 500;
  font-style: italic;
  color: var(--color-text-dark);
}

.callout-tag {
  display: inline-flex;
  align-items: center;
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.75rem;
}
.callout--before {
  background: #fff8f5;
  border-color: rgba(122, 87, 68, 0.25);
}
.callout--before .callout-tag {
  background: rgba(122, 87, 68, 0.12);
  color: var(--color-accent-brown);
}
.callout--before p { color: var(--color-text-muted); font-style: italic; }

.callout--after {
  background: #f4fbf7;
  border-color: rgba(16, 185, 129, 0.25);
}
.callout--after .callout-tag {
  background: rgba(16, 185, 129, 0.12);
  color: #0e8a63;
}
.callout--after p { color: var(--color-text-dark); font-weight: 500; }

/* ============================================================
   INLINE CTA (kept as-is, must NOT be broken)
   ============================================================ */
.inline-cta {
  background: var(--gradient-cta);
  color: white;
  border-radius: var(--radius-lg);
  padding: 2rem 2rem;
  margin: 2.5rem 0;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1.5rem;
  align-items: center;
  box-shadow: var(--shadow-primary);
}
.inline-cta .cta-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  opacity: 0.85;
  margin-bottom: 0.3rem;
}
/* .cta-title: the promo banner's headline used to be an <h3> sitting between
   the article H1 and the first H2 of the body, which made every generator
   landing an H1 -> H3 -> H2 outline (56 pages in the 2026-07 audit). The
   banner is an <aside>, not a section of the article, so the heading was
   dropped from the document outline rather than renumbered. Class selector
   (0,2,0) beats `.inline-cta p` (0,1,1), so the paragraph styles below do not
   leak into it. */
.inline-cta h3,
.inline-cta .cta-title {
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin-bottom: 0.5rem;
  color: white;
  /* line-height and opacity are restated because .cta-title is a <p>: without
     them the `.inline-cta p` rule below applies its 1.5 / .92 to the headline,
     which the old <h3> never inherited. */
  line-height: 1.15;
  opacity: 1;
}
.inline-cta p {
  font-size: 0.93rem;
  line-height: 1.5;
  opacity: 0.92;
}
.inline-cta .btn {
  background: white;
  color: var(--color-primary);
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,0.25);
}
.inline-cta .btn:hover { transform: translateY(-2px); box-shadow: 0 12px 28px -8px rgba(0,0,0,0.3); }

/* ============================================================
   FAQ ACCORDION
   ============================================================ */
.faq { margin: 2.75rem 0 2rem; }
.faq-head { margin-bottom: 1.25rem; }
.faq-head h2 {
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-top: 0.35rem;
  text-wrap: balance;
}
.faq-list {
  display: grid;
  gap: 0.6rem;
}
.faq-item {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.faq-item[open] {
  border-color: rgba(189, 86, 56, 0.35);
  box-shadow: var(--shadow-sm);
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 1.1rem 1.35rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-text-dark);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-chev {
  flex-shrink: 0;
  color: var(--color-primary);
  transition: transform 0.25s var(--ease-standard);
}
.faq-item[open] .faq-chev { transform: rotate(180deg); }
.faq-body {
  padding: 0 1.35rem 1.2rem;
  font-size: 0.97rem;
  line-height: 1.65;
  color: var(--color-text-muted);
}

/* ============================================================
   TAGS as pills
   ============================================================ */
.tags-section {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  padding: 1.5rem 0;
  border-top: 1px solid var(--color-border);
  margin-top: 2.25rem;
}
.tags-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-text-muted);
}
.tag-pills {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  padding: 0; margin: 0;
}
.tag-pills a {
  display: inline-flex;
  padding: 0.45rem 0.85rem;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--color-text-dark);
  text-decoration: none;
  transition: all 0.2s var(--ease-standard);
}
.tag-pills a:hover {
  background: var(--color-primary-light);
  border-color: rgba(189, 86, 56, 0.35);
  color: var(--color-primary);
}

/* ============================================================
   AUTHOR BIO
   ============================================================ */
.author-bio {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.5rem;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1.75rem;
  margin: 2rem 0;
}
.bio-avatar {
  width: 88px; height: 88px;
  border-radius: 50%;
  object-fit: cover;
}
.bio-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-text-muted);
  margin-bottom: 0.3rem;
}
.bio-body h3 {
  font-size: 1.2rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
}
.bio-body p {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  margin-bottom: 1rem;
}
.bio-stats {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: 0.85rem 0;
  margin-bottom: 0.5rem;
  border-top: 1px dashed var(--color-border);
  border-bottom: 1px dashed var(--color-border);
}
.bio-stat strong {
  display: block;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.bio-stat span {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}
.bio-link {
  display: inline-flex;
  align-items: center;
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--color-primary);
  text-decoration: none;
  margin-top: 0.85rem;
  min-height: 24px;
}
.bio-link:hover { color: var(--color-primary-hover); }

/* ============================================================
   SHARE ROW
   ============================================================ */
.share-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1.25rem 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  margin: 2rem 0;
}
.share-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-text-muted);
}
.share-btns { display: flex; gap: 0.4rem; margin-inline-start: auto; }
.share-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: white;
  border: none; cursor: pointer;
  text-decoration: none;
  transition: transform 0.2s;
}
.share-btn:hover { transform: translateY(-2px); }
.share-btn--li { background: #0a66c2; }
.share-btn--tw { background: #000; }
.share-btn--fb { background: #1877f2; }
.share-btn--copy { background: var(--color-text-dark); }

/* ============================================================
   READ NEXT — 1 large + 2 small
   ============================================================ */
.read-next { margin: 2rem 0 4rem; }
.rn-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--color-border);
}
.rn-head h2 {
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-top: 0.35rem;
  text-wrap: balance;
}
.rn-all-btn {
  flex-shrink: 0;
  font-size: 0.85rem;
  padding: 0.55rem 1.1rem;
}
.rn-all-btn:hover {
  background: var(--color-primary);
  color: white;
  border-color: var(--color-primary);
}
.rn-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}
.rn-card {
  display: flex;
  flex-direction: column;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s, box-shadow 0.25s, border-color 0.25s;
}
.rn-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: rgba(189, 86, 56, 0.25);
}
.rn-img {
  aspect-ratio: 16/10;
  position: relative;
}
.rn-img--1 { background: linear-gradient(135deg, #f7e3da 0%, #d6c8ff 50%, #b4a0ff 100%); }
.rn-img--2 { background: linear-gradient(135deg, #fce8d8 0%, #f3d2bb 100%); }
.rn-img--3 { background: linear-gradient(135deg, #e7f5ed 0%, #cee5d8 100%); }
.rn-badge {
  position: absolute;
  inset-inline-start: 0.85rem;
  top: 0.85rem;
  background: var(--color-primary);
  color: white;
  padding: 0.3rem 0.75rem;
  border-radius: var(--radius-pill);
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  box-shadow: var(--shadow-primary);
}
.rn-body {
  padding: 1.1rem 1.25rem 1.25rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.rn-cat {
  display: inline-block;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-weight: 700;
  color: var(--color-primary);
  margin-bottom: 0.55rem;
}
.rn-card h3 {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  margin-bottom: 0.6rem;
  text-wrap: balance;
  flex: 1;
}
.rn-meta {
  font-size: 0.74rem;
  color: var(--color-text-muted);
  margin-top: auto;
}

/* ============================================================
   BACK TO TOP
   ============================================================ */
.back-to-top {
  position: fixed;
  bottom: 24px;
  inset-inline-end: 24px;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--color-primary);
  color: white;
  border: none;
  cursor: pointer;
  box-shadow: var(--shadow-primary);
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.25s, transform 0.25s;
  z-index: 70;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover { background: var(--color-primary-hover); transform: translateY(-2px); }

/* ============================================================
   STICKY MOBILE CTA STRIP (article only)
   ============================================================ */
.mobile-cta-strip {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--color-border);
  padding: 0.65rem 1rem;
  display: none; /* enabled on mobile artboard */
  align-items: center;
  gap: 0.6rem;
  z-index: 75;
  box-shadow: 0 -6px 20px -10px rgba(0,0,0,0.15);
}
.mobile-cta-strip .cta-mini-text {
  flex: 1;
  min-width: 0;
}
.mobile-cta-strip .cta-mini-eyebrow {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--color-text-muted);
  line-height: 1;
}
.mobile-cta-strip .cta-mini-title {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text-dark);
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mobile-cta-strip .btn { padding: 0.5rem 1rem; font-size: 0.82rem; flex-shrink: 0; }

/* ============================================================
   ARCHIVE PAGE — hero, filters, grid, pagination, about
   ============================================================ */
.archive-hero {
  background: linear-gradient(135deg, #f3eeff 0%, #f5f3f0 60%, #f9f6f0 100%);
  border-radius: var(--radius-lg);
  padding: 3rem 3rem 2.5rem;
  margin: 1.5rem auto 2rem;
  max-width: 1500px;
  position: relative;
  overflow: hidden;
}
.archive-hero::before {
  content: "";
  position: absolute;
  inset-inline-end: -120px;
  top: -120px;
  width: 380px; height: 380px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(224, 120, 90,0.45) 0%, transparent 70%);
  pointer-events: none;
}
.archive-breadcrumbs { font-size: 0.82rem; color: var(--color-text-muted); margin-bottom: 1.5rem; }
.archive-breadcrumbs a { color: var(--color-text-muted); text-decoration: none; display: inline-flex; align-items: center; min-height: 24px; }
.archive-breadcrumbs span.sep { margin: 0 0.5rem; opacity: 0.5; }

.archive-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  padding: 0.35rem 0.85rem;
  border-radius: var(--radius-pill);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: 1rem;
}
.archive-eyebrow .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-light);
}
.archive-title {
  font-size: clamp(2.5rem, 5vw, 4.25rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1.05;
  margin-bottom: 1rem;
  text-wrap: balance;
}
.archive-title em {
  font-style: normal;
  color: var(--color-primary);
}
.archive-lede {
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  max-width: 640px;
  margin-bottom: 1.75rem;
  text-wrap: pretty;
}
.archive-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 0.55rem 0.55rem 0.55rem 1.1rem;
  max-width: 480px;
  box-shadow: var(--shadow-sm);
  position: relative;
  z-index: 1;
}
.archive-search input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--font-primary);
  font-size: 0.95rem;
  color: var(--color-text-dark);
  padding: 0.25rem 0;
}
.archive-search input::placeholder { color: var(--color-text-muted); }
.archive-search .search-icon { color: var(--color-text-muted); flex-shrink: 0; }
.archive-search button { padding: 0.55rem 1.1rem; font-size: 0.85rem; }

.archive-stats {
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  margin-top: 1.5rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  position: relative; z-index: 1;
}
.archive-stats strong { color: var(--color-text-dark); font-weight: 700; }

/* ----- Filters ----- */
.archive-filters-row {
  max-width: 1500px;
  margin: 0 auto 2rem;
  padding: 0 2rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  justify-content: space-between;
  flex-wrap: wrap;
}
.archive-filters {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem 1rem;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text-dark);
  cursor: pointer;
  text-decoration: none;
  transition: all 0.2s var(--ease-standard);
}
.filter-pill .count {
  font-size: 0.72rem;
  color: var(--color-text-muted);
  font-weight: 600;
}
.filter-pill:hover { border-color: rgba(189, 86, 56, 0.35); color: var(--color-primary); }
.filter-pill.is-active {
  background: var(--color-primary);
  color: white;
  border-color: var(--color-primary);
  box-shadow: var(--shadow-primary);
}
.filter-pill.is-active .count { color: rgba(255,255,255,0.7); }

.archive-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.archive-sort select {
  border: 1px solid var(--color-border);
  background: var(--color-bg-white);
  border-radius: var(--radius-pill);
  padding: 0.5rem 0.85rem;
  font-family: var(--font-primary);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text-dark);
  cursor: pointer;
}

/* ----- Featured (large) card ----- */
.archive-grid-shell {
  max-width: 1500px;
  margin: 0 auto;
  padding: 0 2rem;
}
.featured-card {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 0;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 2.5rem;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s, box-shadow 0.3s;
}
.featured-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}
.featured-img {
  aspect-ratio: 16/10;
  position: relative;
  background: linear-gradient(135deg, #ffd6c2 0%, #f7e3da 100%);
}
.featured-img::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 25% 70%, #ffeacf 0%, transparent 40%),
    radial-gradient(circle at 75% 30%, #f3c9b8 0%, transparent 45%);
}
.featured-badge {
  position: absolute;
  inset-inline-start: 1.25rem;
  top: 1.25rem;
  background: var(--color-primary);
  color: white;
  padding: 0.4rem 0.95rem;
  border-radius: var(--radius-pill);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  box-shadow: var(--shadow-primary);
  z-index: 1;
}
.featured-body {
  padding: 2.5rem 2.75rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.featured-meta {
  display: flex; align-items: center; gap: 0.65rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-bottom: 1rem;
}
.featured-cat {
  background: var(--color-primary-light);
  color: var(--color-primary);
  padding: 0.22rem 0.7rem;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.featured-card h2 {
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.15;
  margin-bottom: 1rem;
  text-wrap: balance;
}
.featured-card p {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--color-text-muted);
  margin-bottom: 1.5rem;
}
.featured-author {
  display: flex; align-items: center; gap: 0.6rem;
  margin-top: auto;
}
.featured-author img { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.featured-author .au-name { font-size: 0.85rem; font-weight: 700; color: var(--color-text-dark); }
.featured-author .au-meta { font-size: 0.75rem; color: var(--color-text-muted); }

/* ----- Article grid ----- */
.articles-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-bottom: 3rem;
}
.article-card {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s, box-shadow 0.25s, border-color 0.25s;
  display: flex;
  flex-direction: column;
}
.article-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: rgba(189, 86, 56, 0.25);
}
.ac-img {
  aspect-ratio: 16/10;
  position: relative;
}
.ac-img--1 { background: linear-gradient(135deg, #f4e8da 0%, #d8c4a8 100%); }
.ac-img--2 { background: linear-gradient(135deg, #ffd0e0 0%, #ffe9b8 100%); }
.ac-img--3 { background: linear-gradient(135deg, #d8e3f2 0%, #b8c8e0 100%); }
.ac-img--4 { background: linear-gradient(135deg, #e8e0d0 0%, #c8b890 100%); }
.ac-img--5 { background: linear-gradient(135deg, #ffd5a8 0%, #ffb878 100%); }
.ac-img--6 { background: linear-gradient(135deg, #d0e8d0 0%, #98c898 100%); }
.ac-body {
  padding: 1.25rem 1.4rem 1.4rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.ac-meta {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-size: 0.7rem;
  color: var(--color-text-muted);
}
.ac-cat {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--color-primary);
}
.ac-body h3 {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  margin-bottom: 0.55rem;
  text-wrap: balance;
}
.ac-body p {
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  margin-bottom: 0.85rem;
  flex: 1;
}
.ac-foot {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--color-primary);
  margin-top: auto;
}

/* ----- Pagination ----- */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 1rem 0;
  margin-bottom: 2.5rem;
}
.pag-btn {
  min-width: 40px; height: 40px;
  border-radius: 10px;
  border: 1px solid var(--color-border);
  background: var(--color-bg-white);
  color: var(--color-text-dark);
  font-family: var(--font-primary);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 0.85rem;
  text-decoration: none;
  transition: all 0.2s var(--ease-standard);
}
.pag-btn:hover { border-color: rgba(189, 86, 56, 0.35); color: var(--color-primary); }
.pag-btn.is-active {
  background: var(--color-primary);
  color: white;
  border-color: var(--color-primary);
  box-shadow: var(--shadow-primary);
}
.pag-btn.is-disabled { opacity: 0.4; pointer-events: none; }
.pag-dots { color: var(--color-text-muted); padding: 0 0.25rem; }
.pag-arrow { gap: 0.35rem; padding: 0 1rem; }

/* ----- About-blog block ----- */
.about-blog {
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2.5rem 2.75rem;
  margin: 1rem 0 4rem;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2.5rem;
  align-items: center;
}
.about-blog .ab-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-eyebrow);
  font-weight: 700;
  color: var(--color-primary);
  margin-bottom: 0.5rem;
}
.about-blog h2 {
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.15;
  margin-bottom: 0.75rem;
  text-wrap: balance;
}
.about-blog p {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--color-text-muted);
  max-width: 640px;
  margin-bottom: 1.25rem;
}
.about-blog-meta {
  display: flex; gap: 1.75rem; flex-wrap: wrap;
  margin-top: 1rem;
}
.about-blog-meta .item strong {
  display: block;
  font-size: 1.45rem;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.025em;
  line-height: 1;
}
.about-blog-meta .item span {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-top: 4px;
  display: block;
}
.about-blog-cta {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  align-items: stretch;
  min-width: 240px;
}
.about-blog-cta .btn { justify-content: center; }
.about-blog-cta .ab-note { font-size: 0.74rem; color: var(--color-text-muted); text-align: center; }

/* ============================================================
   MOBILE artboard overrides — applied inside the iPhone screen
   ============================================================ */
.mobile-shell {
  width: 100%;
  height: 100%;
  background: var(--color-bg-light);
  overflow-y: auto;
  position: relative;
  font-family: var(--font-primary);
  -webkit-font-smoothing: antialiased;
}
.mobile-shell .rp-bar { position: absolute; }

.mobile-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: rgba(245,243,240,0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-border);
  padding: 0.55rem 0.85rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem;
}
.mobile-header .logo-text { font-size: 0.78rem; }
.mobile-header .logo-text em { font-size: 0.5rem; }
.mobile-header .mh-actions { display: flex; gap: 0.4rem; align-items: center; }
.mobile-header .mh-iconbtn {
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-bg-white);
  color: var(--color-text-dark);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}

.mobile-shell .article {
  padding: 0.85rem 1rem 5rem; /* leave space for sticky CTA */
  max-width: 100%;
}
.mobile-shell .article-title {
  font-size: 1.45rem;
  letter-spacing: -0.03em;
}
.mobile-shell .article-lede {
  font-size: 0.95rem;
  margin-bottom: 1rem;
}
.mobile-shell .article-hero {
  border-radius: 14px;
  margin-bottom: 1rem;
}
.mobile-shell .article-author-row { padding-top: 0.85rem; }
.mobile-shell .author-avatar { width: 36px; height: 36px; }
.mobile-shell .author-name { font-size: 0.85rem; }
.mobile-shell .author-role { font-size: 0.72rem; }
.mobile-shell .article-actions { display: none; }

/* ----- Mobile ToC (collapsed by default) ----- */
.mobile-shell .toc-mobile {
  display: block;
  background: var(--color-bg-white);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  margin-bottom: 1rem;
  overflow: hidden;
}
.mobile-shell .toc-mobile summary {
  list-style: none;
  cursor: pointer;
  padding: 0.85rem 1rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.mobile-shell .toc-mobile summary::-webkit-details-marker { display: none; }
.mobile-shell .toc-mobile-label {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--color-text-dark);
  letter-spacing: -0.01em;
  flex: 1;
}
.mobile-shell .toc-mobile-count {
  font-size: 0.72rem;
  color: var(--color-text-muted);
  margin-inline-end: 0.4rem;
}
.mobile-shell .toc-mobile-chev {
  color: var(--color-primary);
  transition: transform 0.25s var(--ease-standard);
}
.mobile-shell .toc-mobile[open] .toc-mobile-chev { transform: rotate(180deg); }
.mobile-shell .toc-mobile[open] summary { border-bottom: 1px solid var(--color-border); }

/* Show mock-open list inside mobile ToC — this artboard renders it open */
.mobile-shell .toc-mobile[open]::after {
  content: "";
  display: block;
}

/* hide desktop ToC sidebar in mobile shell */
.mobile-shell .toc { display: none; }
.mobile-shell .article-grid { grid-template-columns: 1fr; gap: 0; }
.mobile-shell .article-shell { padding: 0; max-width: none; }

/* Tighter cards on mobile */
.mobile-shell .key-takeaways { padding: 1rem 1.15rem 1rem; margin-bottom: 1.25rem; }
.mobile-shell .kt-list li { font-size: 0.86rem; padding-inline-start: 1.4rem; }
.mobile-shell .kt-icon { width: 32px; height: 32px; }
.mobile-shell .kt-sub { font-size: 0.74rem; }

.mobile-shell .article-body h2 { font-size: 1.25rem; margin: 1.5rem 0 0.6rem; scroll-margin-top: 50px; }
.mobile-shell .article-body h3 { font-size: 1.05rem; margin: 1.1rem 0 0.5rem; }
.mobile-shell .article-body p { font-size: 0.95rem; line-height: 1.65; }

.mobile-shell .callout { padding: 1rem 1.15rem; margin: 1.25rem 0; }
.mobile-shell .callout p { font-size: 0.95rem; }
.mobile-shell .callout--quote { padding-inline-start: 3rem; }
.mobile-shell .callout--quote .callout-mark { font-size: 2.5rem; top: 0.25rem; }
.mobile-shell .callout--quote p { font-size: 1rem; }

.mobile-shell .inline-cta {
  grid-template-columns: 1fr;
  padding: 1.5rem 1.35rem;
  margin: 1.75rem 0;
  text-align: center;
}
.mobile-shell .inline-cta h3,
.mobile-shell .inline-cta .cta-title { font-size: 1.15rem; }
.mobile-shell .inline-cta p { font-size: 0.88rem; }
.mobile-shell .inline-cta .btn { width: 100%; justify-content: center; }

.mobile-shell .faq-head h2 { font-size: 1.4rem; }
.mobile-shell .faq-item summary { padding: 0.95rem 1.1rem; font-size: 0.92rem; gap: 0.65rem; }
.mobile-shell .faq-body { padding: 0 1.1rem 1.05rem; font-size: 0.9rem; }

.mobile-shell .tags-section { padding: 1rem 0; gap: 0.6rem; }
.mobile-shell .tag-pills a { font-size: 0.78rem; padding: 0.4rem 0.75rem; }

.mobile-shell .author-bio {
  grid-template-columns: 1fr;
  text-align: center;
  padding: 1.35rem;
  gap: 0.85rem;
}
.mobile-shell .bio-avatar { width: 64px; height: 64px; margin: 0 auto; }
.mobile-shell .bio-stats { justify-content: space-around; gap: 0.85rem; }
.mobile-shell .bio-stat strong { font-size: 1rem; }

.mobile-shell .share-row { gap: 0.5rem; padding: 0.85rem 0; }
.mobile-shell .share-label { font-size: 0.66rem; }
.mobile-shell .share-btns { margin-inline-start: auto; }
.mobile-shell .share-btn { width: 32px; height: 32px; }

.mobile-shell .read-next { margin-bottom: 1.5rem; }
.mobile-shell .rn-head { flex-wrap: wrap; gap: 0.65rem; padding-bottom: 0.75rem; }
.mobile-shell .rn-head h2 { font-size: 1.3rem; }
.mobile-shell .rn-all-btn { font-size: 0.78rem; padding: 0.45rem 0.85rem; }
.mobile-shell .rn-grid { grid-template-columns: 1fr; gap: 0.75rem; }
.mobile-shell .rn-card { display: grid; grid-template-columns: 110px 1fr; }
.mobile-shell .rn-card .rn-img { aspect-ratio: auto; height: 100%; min-height: 100px; }
.mobile-shell .rn-card .rn-body { padding: 0.75rem 0.95rem 0.85rem; }
.mobile-shell .rn-card h3 { font-size: 0.92rem; line-height: 1.3; margin-bottom: 0.4rem; }
.mobile-shell .rn-cat { font-size: 0.6rem; margin-bottom: 0.35rem; letter-spacing: 1.2px; }
.mobile-shell .rn-meta { font-size: 0.7rem; }
.mobile-shell .rn-badge { display: none; }

/* Sticky mobile ToC — collapses on scroll */
.mobile-shell .toc-mobile {
  position: sticky;
  top: 47px; /* below mobile-header */
  z-index: 4;
  box-shadow: 0 4px 14px -10px rgba(0,0,0,0.18);
}

.mobile-shell .mobile-cta-strip { display: flex; position: absolute; }
.mobile-shell .back-to-top { position: absolute; bottom: 70px; inset-inline-end: 14px; width: 38px; height: 38px; opacity: 1; transform: none; pointer-events: auto; }

/* Hide desktop site header/footer inside mobile shell */
.mobile-shell .site-header,
.mobile-shell .site-footer { display: none; }

/* ============================================================
   MOBILE archive — overrides
   ============================================================ */
.mobile-shell .archive-hero {
  border-radius: 0;
  padding: 1rem 1rem 1.25rem;
  margin: 0;
}
.mobile-shell .archive-hero::before { width: 200px; height: 200px; inset-inline-end: -80px; top: -80px; }
.mobile-shell .archive-title { font-size: 2rem; margin-bottom: 0.65rem; }
.mobile-shell .archive-lede { font-size: 0.92rem; margin-bottom: 1rem; }
.mobile-shell .archive-search { padding: 0.4rem 0.4rem 0.4rem 0.85rem; }
.mobile-shell .archive-search input { font-size: 0.88rem; }
.mobile-shell .archive-search button { padding: 0.4rem 0.7rem; font-size: 0.78rem; }
.mobile-shell .archive-search button span { display: none; }
.mobile-shell .archive-stats { font-size: 0.75rem; gap: 0.85rem; margin-top: 0.85rem; }

.mobile-shell .archive-filters-row {
  padding: 0.85rem 1rem 0.5rem;
  gap: 0.5rem;
  flex-direction: column;
  align-items: stretch;
}
.mobile-shell .archive-filters {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 0.25rem;
  margin: 0 -1rem;
  padding-inline-start: 1rem;
  padding-inline-end: 1rem;
}
.mobile-shell .archive-filters::-webkit-scrollbar { display: none; }
.mobile-shell .filter-pill { white-space: nowrap; flex-shrink: 0; padding: 0.45rem 0.85rem; font-size: 0.8rem; }
.mobile-shell .archive-sort { font-size: 0.78rem; align-self: flex-end; }

.mobile-shell .archive-grid-shell { padding: 0 1rem; }

.mobile-shell .featured-card {
  grid-template-columns: 1fr;
  margin-bottom: 1.25rem;
  border-radius: var(--radius-md);
}
.mobile-shell .featured-img { aspect-ratio: 16/10; }
.mobile-shell .featured-body { padding: 1.25rem 1.35rem 1.4rem; }
.mobile-shell .featured-card h2 { font-size: 1.3rem; margin-bottom: 0.6rem; }
.mobile-shell .featured-card p { font-size: 0.88rem; margin-bottom: 1rem; }
.mobile-shell .featured-badge { padding: 0.3rem 0.75rem; font-size: 0.62rem; inset-inline-start: 0.85rem; top: 0.85rem; }

.mobile-shell .articles-grid {
  grid-template-columns: 1fr;
  gap: 0.85rem;
  margin-bottom: 1.5rem;
}
.mobile-shell .article-card { border-radius: var(--radius-md); }
.mobile-shell .ac-body { padding: 1rem 1.15rem 1.15rem; }
.mobile-shell .ac-body h3 { font-size: 1rem; }
.mobile-shell .ac-body p { font-size: 0.82rem; }

.mobile-shell .pagination { flex-wrap: wrap; gap: 0.3rem; margin-bottom: 1.25rem; }
.mobile-shell .pag-btn { min-width: 36px; height: 36px; font-size: 0.85rem; }

.mobile-shell .about-blog {
  grid-template-columns: 1fr;
  padding: 1.5rem 1.35rem;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
  border-radius: var(--radius-md);
}
.mobile-shell .about-blog h2 { font-size: 1.4rem; }
.mobile-shell .about-blog p { font-size: 0.9rem; }
.mobile-shell .about-blog-meta { gap: 1rem; }
.mobile-shell .about-blog-meta .item strong { font-size: 1.15rem; }
.mobile-shell .about-blog-cta { min-width: 0; }

/* ============================================================
   RTL support — flip directional bits.
   We use logical properties almost everywhere. Two visual fixes:
   ============================================================ */
[dir="rtl"] .toc-list ol { border-left: none; border-right: 1px solid var(--color-border); margin-left: 0; margin-right: 1rem; }
[dir="rtl"] .toc-list ol a.is-active { border-left: none; border-right: 2px solid var(--color-primary); padding-left: 0; padding-right: 0.85rem; margin-left: 0; margin-right: -1px; }

/* ============================================================
   CANVAS chrome
   ============================================================ */
body.canvas-host { background: #ececec; font-family: var(--font-primary); color: var(--color-text-dark); }
.canvas-intro { max-width: 1200px; margin: 1.5rem auto 0.5rem; padding: 1.5rem 1.75rem; background: var(--color-bg-white); border: 1px solid var(--color-border); border-radius: 14px; }
.canvas-intro h1 { font-size: 1.4rem; font-weight: 800; letter-spacing: -0.025em; margin-bottom: 0.5rem; }
.canvas-intro p { font-size: 0.92rem; color: var(--color-text-muted); line-height: 1.55; margin-bottom: 0.5rem; }
.canvas-intro ul { font-size: 0.88rem; padding-inline-start: 1.1rem; line-height: 1.7; }
.canvas-intro code { background: var(--color-bg-light); padding: 0.1rem 0.4rem; border-radius: 4px; font-size: 0.84rem; }

.canvas-art-desktop { width: 1500px; height: 1100px; overflow: hidden; background: var(--color-bg-light); }
.canvas-art-desktop--archive { height: 1500px; }
.canvas-art-mobile { width: 390px; height: 844px; }
.mobile-frame-host { width: 390px; height: 844px; display: flex; align-items: center; justify-content: center; }


/* ============================================================
   BLOG REDESIGN — overrides and integration glue.

   blog-redesign.css ships untouched from the design handoff.
   This file holds:
     - Swiper integration for "What to read next" (mobile carousel,
       desktop grid).
     - Bits the design didn't ship explicitly (.rn-controls layout,
       prev/next button skin, mobile-cta-strip text override).
     - Body class overrides that align the design with our existing
       site shell (header / footer / button styles live in main.css).
   ============================================================ */

/* --- Category badge above the H1 should look like a pill, not just a coloured
       caps label. The design's .article-cat is a flat label; we promote it to
       a rounded chip with a soft lilac wash so it reads as a tag. */
.article-head .article-cat,
.article-meta > .article-cat {
  display: inline-flex;
  align-items: center;
  padding: 0.32rem 0.75rem;
  border-radius: 999px;
  background: rgba(189, 86, 56, 0.08);
  color: var(--color-primary, #bd5638);
  text-decoration: none;
  margin-bottom: 0;
  font-weight: 700;
  letter-spacing: 1.4px;
  line-height: 1;
}
.article-head .article-cat:hover {
  background: var(--color-primary, #bd5638);
  color: #fff;
}

/* --- Action icon buttons next to the author row (Save, Share). The design
       ships round 36px icon buttons on a soft background. Our markup uses
       <button class="icon-btn"> — give it the same look. */
.article-actions {
  display: flex;
  gap: 0.5rem;
  margin-inline-start: auto;
}
.icon-btn {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-soft, #f5f3f0);
  border: 1px solid var(--color-border, #e6e2dc);
  border-radius: 999px;
  color: var(--color-text, #313330);
  cursor: pointer;
  padding: 0;
  transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.2s;
}
.icon-btn:hover {
  background: var(--color-primary, #bd5638);
  color: #fff;
  border-color: var(--color-primary, #bd5638);
}
.icon-btn.is-active {
  background: var(--color-primary, #bd5638);
  color: #fff;
  border-color: var(--color-primary, #bd5638);
}
.icon-btn .sr-only {
  position: absolute !important;
  width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* --- Inline CTA — match the design exactly: violet gradient bg, white text,
   white button. The blog-redesign.css rules use --gradient-cta and
   --shadow-primary, which only live in wishes-v2.css and don't load on
   single articles, so we redeclare them here as a fallback. */
:root {
  --gradient-cta: linear-gradient(135deg, #bd5638 0%, #e0785a 100%);
  --shadow-primary: 0 12px 24px -6px rgba(189, 86, 56, 0.35);
  /* Tokens used by blog-redesign.css that only live in wishes-v2.css.
     Redeclared here so single articles render the same as the design. */
  --radius-pill: 999px;
  --color-bg-soft: #f5f3f0;
  --letter-spacing-eyebrow: 0.12em;
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.04), 0 2px 6px rgba(0,0,0,0.06);
  --shadow-md: 0 8px 24px -8px rgba(0,0,0,0.18);
}
.inline-cta {
  background: var(--gradient-cta);
  color: #fff;
  border: none;
  border-radius: var(--radius-lg, 24px);
  padding: 2rem;
  margin-block: 2.5rem;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1.5rem;
  align-items: center;
  box-shadow: var(--shadow-primary);
}
.inline-cta .cta-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-weight: 700;
  color: #fff;
  opacity: 0.85;
  margin-bottom: 0.3rem;
}
/* .cta-title — see the note in blog-redesign.css: the banner headline is no
   longer a heading element, so it stops breaking the article's H1/H2 outline.
   Class selector outranks `.inline-cta p`, so nothing leaks in. */
.inline-cta h3,
.inline-cta .cta-title {
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin: 0 0 0.5rem;
  color: #fff;
  /* See blog-redesign.css: <p> would otherwise inherit .inline-cta p's
     line-height and opacity. */
  line-height: 1.15;
  opacity: 1;
}
.inline-cta p {
  font-size: 0.93rem;
  line-height: 1.5;
  color: #fff;
  opacity: 0.92;
  margin: 0;
}
.inline-cta .btn,
.inline-cta .btn.btn-primary {
  background: #fff;
  color: var(--color-primary, #bd5638);
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,0.25);
  border: none;
}
.inline-cta .btn:hover,
.inline-cta .btn.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -8px rgba(0,0,0,0.3);
  background: #fff;
  color: var(--color-primary, #bd5638);
}

/* --- Plain <blockquote> fallback. Articles use <blockquote class="callout
       callout--before/--after/--quote"> for the design's tinted boxes. Any
       blockquote WITHOUT a .callout class falls back to a neutral, soft-grey
       quote with a side bar. The :not(.callout) guard is critical — without
       it this rule's specificity (0,0,1,1) would beat .callout--before /
       .callout--after (0,0,1,0) and override their per-class backgrounds
       and rounded borders, producing the same beige box for every quote. */
.article-body blockquote:not(.callout) {
  background: var(--color-bg-soft, #f5f3f0);
  border-inline-start: 4px solid var(--color-primary, #bd5638);
  border-radius: 0 var(--radius-md, 16px) var(--radius-md, 16px) 0;
  padding: 1.1rem 1.4rem;
  margin: 1.5rem 0;
  color: var(--color-text, #313330);
  font-style: normal;
  position: relative;
}
.article-body blockquote:not(.callout) p {
  margin: 0;
}
.article-body blockquote:not(.callout) p + p {
  margin-top: 0.6rem;
}
.article-body blockquote:not(.callout) em {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: var(--color-primary, #bd5638);
  font-style: normal;
  font-weight: 700;
  margin-bottom: 0.4rem;
}

/* The .callout-mark is absolutely positioned at top:0.5rem with font-size:3.5rem,
   so the glyph extends ~3rem down into the box. The default .callout padding-top
   (1.25rem) leaves the first line of body text overlapping the bottom of the
   quote mark. Push the body down so the glyph clears it. */
.callout--quote {
  padding-block-start: 2.5rem;
}

/* TOC list / mobile-list styles intentionally not overridden here.
   The design's blog-redesign.css already ships a complete ToC theme:
   numbered ::before counter, primary-light active background, nested
   border-left list, mobile <details> sticky behaviour. Anything we add
   here would either fight the counter (eats the left padding the number
   sits in) or duplicate the active styling and double up on backgrounds.
   We just need to push the auto-built mobile list inside the <details>
   container. */
.toc-mobile-list {
  padding: 0 1rem 1rem;
}
.toc-mobile-list ol {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  counter-reset: toc;
}

/* --- Make sticky actually stick.

   main.css applies `html { overflow-x: hidden }` site-wide, which silently
   turns <html> into a scroll-container and breaks `position: sticky` in every
   descendant on Chromium. `overflow-x: clip` clips the same way visually but
   doesn't create the scroll-container, so children can sticky off the
   document scroll-port again. clip is supported in Chrome/Edge 90+,
   Firefox 90+, Safari 16+ — the main.css `hidden` stays as a fallback for
   older engines. */
html, body {
  overflow-x: clip;
}

/* --- Match the article container to the site shell.
   .site-header .container is 1500/16px; the design's .article-shell ships
   with 32px sides, which makes the article look narrower than header/footer.
   Bring shell padding to 16px so the visible content edges line up. */
.article-shell {
  padding-inline: 1rem;
}
.article-grid {
  /* minmax(0, 1fr) prevents the article cell from expanding to its
     min-content width — without it, an internal Swiper wrapper (which is a
     row of intrinsically-wide slides) pushes the cell wider than the shell. */
  grid-template-columns: 280px minmax(0, 1fr);
}
/* blog-redesign.css ships .article { max-width: 760px } from the design.
   Bump to 780px — same selector, but this file is loaded after the design's,
   so this wins on equal specificity. We don't need a .article-grid > .article
   override: .article-grid above already uses minmax(0, 1fr) to keep the grid
   cell from blowing out, so the cap is enforced from .article alone. */
.article {
  max-width: 780px;
}
.read-next-swiper { overflow: hidden; }

/* Hero figure — the design assumed a 16:9 image, but DALL-E ships our covers
   at 1200×630 (~1.9:1). The 16:9 aspect-ratio left a white strip below the
   image. Match the figure to the actual image ratio and use object-fit:cover
   so any future image of a different aspect still fills cleanly. */
.article-hero {
  aspect-ratio: 1200 / 630;
}
.article-hero img,
.article-hero .hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- Sticky TOC offset: the design assumes a non-sticky site header, but ours
       is position:fixed at the top with --header-height (~84px). Push the
       sticky anchor below it so the TOC card is fully visible while scrolling.
       Same trick for the article body's heading anchors so jump-links don't
       hide their target under the header. */
.toc {
  top: calc(var(--header-height, 84px) + 16px) !important;
}
.article-body :is(h2, h3) {
  scroll-margin-top: calc(var(--header-height, 84px) + 16px);
}
.toc-mobile {
  top: var(--header-height, 84px);
}

/* Read-next sits inside <article> now (not as a sibling of .article-grid),
   so it inherits the article column. Margins keep it visually separate from
   the share-row above. */
.article > .read-next {
  margin-block: 2.5rem 4rem;
}

/* --- Make .rn-img play nicely with real photos.
       The design used CSS gradients (.rn-img--1, --2, --3); we apply
       background-image inline from the WordPress thumbnail. The base
       .rn-img already has aspect-ratio + rounded corners — just clear
       the gradient defaults so background-position centres the photo. */
.rn-img {
  background: var(--color-bg-soft, #f5f3f0);
  background-size: cover;
  background-position: center;
}

/* --- Read-next controls row (prev / next / all-button).
       Aligned to the right of the section heading, vertically centered. */
.rn-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.rn-nav-btn {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-white, #fff);
  border: 1px solid var(--color-border, #e6e2dc);
  border-radius: 999px;
  color: var(--color-text, #313330);
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s, transform 0.2s;
}
.rn-nav-btn:hover {
  background: var(--color-primary, #bd5638);
  border-color: var(--color-primary, #bd5638);
  color: #fff;
}
.rn-nav-btn:disabled,
.rn-nav-btn.swiper-button-disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

/* --- Swiper × Read-next.

   Swiper is active on every breakpoint now — 3 slides on desktop, 1.15 on
   mobile (config in blog.js). Carousel sits inside <article>, so its width
   matches the .article column (max 760px). Cards never grow beyond their
   slide; image keeps its 16/10 aspect ratio. */
.read-next-swiper {
  overflow: hidden;
  /* Bleed slightly past the column on mobile so the peek of slide 2 isn't
     cut off by .article-body padding. */
}
.read-next-swiper .swiper-wrapper {
  /* Reset any inherited grid in case CSS reset libraries set it. */
  display: flex;
}
.read-next-swiper .rn-card {
  height: auto;             /* let Swiper compute slide height */
}
.read-next-swiper .rn-card .rn-img {
  aspect-ratio: 16/10;
  width: 100%;
}

/* Inside the article column, the carousel needs to claim full width and
   ignore the article's max-width 760 limit visually. */
.article > .read-next {
  margin-inline: 0;
  width: 100%;
}

@media (max-width: 767px) {
  .rn-head {
    flex-wrap: wrap;
  }
  .rn-controls {
    width: 100%;
    justify-content: flex-end;
  }
  .read-next-swiper {
    margin-inline: -1rem;
    padding-inline: 1rem;
  }
}

/* Tag pills styling lives in blog-redesign.css (.tags-section, .tags-label,
   .tag-pills, .tag-pills a). Markup is <ul class="tag-pills"><li><a>…</a></li>.
   The design's default puts the label inline (flex row); we stack it above
   the pills, so "ARTICLE TOPICS" sits as an eyebrow over the pill row. */
.tags-section {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

/* --- Visually-hidden helper for icon buttons. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* Share row uses the design's brand-coloured circular buttons (.share-btn,
   .share-btn--li/--tw/--fb/--copy). Styling lives in blog-redesign.css,
   no override needed here. */
.share-btn.is-copied { transform: scale(0.94); }

/* Author bio styling lives in blog-redesign.css (.author-bio, .bio-avatar,
   .bio-body h3, .bio-stats, .bio-stat, .bio-link). The legacy
   .author-bio__avatar / __body / __name / __text / __meta classes were
   replaced with the design's bio-* set — see single.php. */

/* --- Article CTA ("Let's write a wish") ---------------------------------
   Two shapes, one element:
     mobile  - a strip pinned across the bottom of the viewport;
     desktop - a compact pill in the bottom corner.
   Always on screen, never hides on scroll (blog.js#initMobileCtaStrip just
   adds .is-visible once). The strip slides in from below on first paint so
   it does not flash before the stylesheet applies. */
.mobile-cta-strip {
  /* blog-redesign.css sets display:none and only turns it on inside
     .mobile-shell - the design's phone artboard, not an actual phone. So on a
     real device the strip has been shipped-but-invisible all along. Turn it on
     for every viewport here; the desktop block below reshapes it into a pill. */
  display: flex !important;
  transform: translateY(120%);
  transition: transform 0.25s ease;
}
.mobile-cta-strip.is-visible {
  transform: translateY(0);
}
.mobile-cta-strip .btn { flex: 1; text-align: center; }
@media (prefers-reduced-motion: reduce) {
  .mobile-cta-strip { transition: none; }
}

/* Clear the other things that live in the bottom corner. Measured on a 375px
   viewport: the strip is ~59px tall, and both the back-to-top button and the
   accessibility widget (#atx-root, from the vsac plugin) sat underneath it.
   Only lifted on article pages - the rules are scoped to .single-post, so the
   widget keeps its normal position everywhere else. */
@media (max-width: 767px) {
  /* Stack, bottom-up: CTA strip (59px) -> accessibility widget (60px) ->
     back-to-top (44px), 12px between each. All three share the right-hand
     corner on a phone, so they have to queue rather than sit side by side. */
  .single-post #atx-root.atx-pos-br,
  .single-post #atx-root.atx-pos-bl { bottom: calc(59px + 12px); }
  .single-post .back-to-top { bottom: calc(59px + 12px + 60px + 12px); }
}

/* Back-to-top vs the accessibility widget. Both park in the same corner and
   their boxes coincide almost exactly - the 44px button sits entirely inside
   the 60px widget (measured: button 1197-1241, widget 1185-1245). The overlap
   predates the article CTA; it only became visible once the widget was
   installed on production. The widget is always on screen and belongs to a
   plugin, so the theme's own button is the one that moves: 20px (widget
   offset) + 60px (its height) + 12px gap. Only on the wide layout - on phones
   the two are already apart horizontally. */
@media (min-width: 768px) {
  .back-to-top { bottom: 92px; }
}

/* The parcel and its sparkles ride along only in the square variant. In the
   bottom strip there is no vertical room for them and the label alone reads
   fine, so they are dropped rather than shrunk. */
.mobile-cta-strip .cta-gift,
.mobile-cta-strip .cta-sparks { display: none; }

/* ── CTA motion ───────────────────────────────────────────────────────────
   This button never leaves the screen, and per the animation-frequency rule
   that argues for almost no motion at all: anything looping continuously
   becomes noise within a minute of reading, and reads cheap rather than
   premium. So the button is STILL ~85% of the time. Every few seconds a
   single light sweep crosses it, the shadow swells slightly underneath, and
   the icon blinks once. Rare and slow is what reads expensive; fast and
   constant is what reads like an advert.

   Only transform / opacity / box-shadow animate, so it stays on the GPU and
   costs nothing while the reader scrolls. */

.mobile-cta-strip .btn,
.mobile-cta-strip .btn.btn-primary {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* Named properties, never `all`: the layout properties above must not be
     caught by a transition. */
  transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1),
              box-shadow 260ms cubic-bezier(0.23, 1, 0.32, 1);
}

/* The sweep. A soft diagonal highlight that crosses the face and is then
   parked off-screen for the rest of the cycle. translateX only - no layout,
   no paint. */
.mobile-cta-strip .btn::after {
  content: "";
  position: absolute;
  inset: -40%;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    105deg,
    transparent 42%,
    rgba(255, 255, 255, 0.10) 47%,
    rgba(255, 255, 255, 0.38) 50%,
    rgba(255, 255, 255, 0.10) 53%,
    transparent 58%
  );
  transform: translateX(-120%);
  animation: dg-cta-sweep 7s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes dg-cta-sweep {
  0%, 78%   { transform: translateX(-120%); }
  92%, 100% { transform: translateX(120%); }
}

/* The breath. A shadow that swells and settles - the button looks lit from
   within rather than flashing. Deliberately out of phase with the sweep (9s
   against 7s) so the two never quite repeat together and the motion never
   feels metronomic. */
@keyframes dg-cta-breathe {
  0%, 100% { box-shadow: 0 10px 26px -10px rgba(189, 86, 56, 0.75); }
  50%      { box-shadow: 0 16px 38px -10px rgba(189, 86, 56, 1),
                         0 0 0 6px rgba(189, 86, 56, 0.07); }
}

/* Press feedback everywhere - the button must feel like it heard the tap. */
.mobile-cta-strip .btn:active,
.mobile-cta-strip .btn.btn-primary:active {
  transform: scale(0.97);
  transition-duration: 100ms;
}

@media (hover: hover) and (pointer: fine) {
  .mobile-cta-strip .btn:hover,
  .mobile-cta-strip .btn.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 18px 40px -12px rgba(189, 86, 56, 1);
  }
  /* On hover the sweep gets out of the way: the reader is already engaged,
     ambient motion has done its job. */
  .mobile-cta-strip .btn:hover::after { animation-play-state: paused; }
}

/* Motion is a nice-to-have, not the message: anyone who asked for less gets
   a plain, still button that still reads as the primary action.
   !important here, not source order: the square's rules live further down the
   file and would otherwise win. The lid still lifts on hover - that is a
   deliberate response to a deliberate gesture, not ambient motion - it just
   arrives instantly instead of easing. */
@media (prefers-reduced-motion: reduce) {
  .mobile-cta-strip .btn::after { animation: none; opacity: 0; }
  .mobile-cta-strip .btn,
  .mobile-cta-strip .btn.btn-primary,
  .mobile-cta-strip .cta-gift,
  .mobile-cta-strip .cta-spark { animation: none !important; }
  .mobile-cta-strip .cta-gift__lid,
  .mobile-cta-strip .cta-gift__glow { transition: none !important; }
}

/* ── Desktop: the gift square ─────────────────────────────────────────────
   Concept 01 "Magic Gift" from the design project (Gift CTA Button.html):
   a solid violet square carrying a light wrapped parcel - white paper, gold
   ribbon down the front, gold bow on the lid - with sparkles drifting around
   it. The parcel hops gently on a loop; on hover the lid lifts off and warm
   light spills out of the box.

   HOW IT IS SIZED. The parcel is the design's geometry to the pixel, but
   written as multiples of --dg-gift-u so the whole thing scales from one
   number: at --dg-gift-u: 1px it is the design's 68x66 parcel on a 146px
   square.

   ONE SIZE, NOT TWO. A smaller tier for narrower screens was the obvious
   move and it does not work: shrink the square and the Russian label
   ("Давайте напишем поздравление", the longest of the four) no longer fits
   in two lines, and three lines do not fit in a square. Below the width
   where the full-size square fits, the pill is the honest answer.

   HOW MUCH ROOM THERE ACTUALLY IS. Worth writing down, because the previous
   breakpoint got this wrong. .article-shell is max-width 1500 with 16px
   side padding, the grid is 280px ToC + 64px gap, and .article caps at 780px
   and is left-aligned in its cell. So for any viewport between 1156px and
   1500px the text stops at exactly x=1140 and the free gutter is simply
   (viewport - 1140):

       1200px ->  60px     1340px -> 200px
       1280px -> 140px     1440px -> 300px

   The old rule turned the square on at 1200px, where 60px of gutter cannot
   hold a 104px square plus its 12px inset - it had been overlapping the last
   ~56px of every line of body text between 1200px and 1256px. 1340px is the
   first width where the 146px square plus its 12px inset clears the text
   with room to spare (42px). Anything narrower keeps the pill, which is why
   the tablet block below runs up to 1339px. */
@media (min-width: 1340px) {
  .mobile-cta-strip {
    --dg-cta-square: 146px;
    --dg-gift-u: 1px;

    left: auto;
    right: auto;
    inset-inline-end: 12px;
    top: 50%;
    bottom: auto;
    width: var(--dg-cta-square);
    height: var(--dg-cta-square);
    padding: 0;
    border: none;
    border-radius: 20px;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    /* Vertical centring lives here, so .is-visible must restate it or the
       button would jump half its height when the class lands. */
    transform: translateY(-50%) translateX(140%);
  }
  .mobile-cta-strip.is-visible { transform: translateY(-50%) translateX(0); }

  .mobile-cta-strip .btn,
  .mobile-cta-strip .btn.btn-primary {
    position: relative;
    width: var(--dg-cta-square);
    height: var(--dg-cta-square);
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(9 * var(--dg-gift-u));
    /* Tighter than the design's 20/15/16, and the side padding matters more
       than it looks. The square has a fixed height and centres its contents,
       so padding only ever acts as a minimum - shrinking it costs nothing
       visually while there is slack, and it buys both headroom and line
       width. At the design's 15px sides the text column was 116px, and the
       Russian label needs 118px to break after "напишем": it fell to three
       lines, which do not fit a square, and flex-shrink quietly ate the
       third one. 10px sides give a 126px column and a comfortable two-line
       break. */
    padding: calc(14 * var(--dg-gift-u)) calc(10 * var(--dg-gift-u));
    border-radius: 20px;
    /* The design's own gradient, deeper at the far end than the site-wide
       button gradient. .btn-primary fades to #f0b8a4, which is lighter than
       the parcel's own paper - the white box would dissolve into it. */
    background: linear-gradient(135deg, #bd5638 0%, #e0785a 100%);
    box-shadow: 0 12px 24px -6px rgba(189, 86, 56, 0.35),
                0 2px 6px rgba(60, 30, 18, 0.12);
    text-align: center;
    white-space: normal;
    line-height: 1.25;
    /* 0.8rem, not the design's 0.86rem: the design was set in Hebrew, whose
       label is a third shorter than the Russian one. This is the largest
       size at which Russian still breaks into two lines. */
    font-size: 0.8rem;
    font-weight: 700;
    /* The lid leaves the button's box on hover, so nothing here may clip.
       That also retires the sweep, which depended on overflow:hidden to stay
       inside its button - the parcel is the motion now, and stacking a
       highlight sweep on top of a hopping box reads busy rather than rich. */
    overflow: visible;
    isolation: auto;
    animation: none;
    transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
                box-shadow 300ms ease;
  }
  .mobile-cta-strip .btn::after,
  .mobile-cta-strip .btn.btn-primary::after { content: none; }

  .mobile-cta-strip .cta-label {
    position: relative;
    z-index: 5;
    /* flex-shrink: 0 is the important one. In a fixed-height column flex box
       the label is shrinkable by default, so a label one line taller than the
       box does not overflow - it gets squeezed, and with overflow:hidden below
       the last line is silently cut off mid-glyph. That is exactly how the
       clipped Russian label hid itself. Refusing to shrink means any future
       string that genuinely does not fit spills visibly instead, which is a
       bug someone will report rather than one nobody notices. */
    flex-shrink: 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* ── The parcel ── */
  .mobile-cta-strip .cta-gift {
    position: relative;
    display: block;
    flex: 0 0 auto;
    width: calc(68 * var(--dg-gift-u));
    height: calc(66 * var(--dg-gift-u));
    animation: dg-gift-hop 3.4s ease-in-out infinite;
  }

  /* Light trapped inside the box. Sits behind the lid (z-index 1 against the
     lid's 4) so it is invisible until the lid actually lifts away. */
  .mobile-cta-strip .cta-gift__glow {
    position: absolute;
    z-index: 1;
    left: 50%;
    bottom: calc(30 * var(--dg-gift-u));
    width: calc(76 * var(--dg-gift-u));
    height: calc(76 * var(--dg-gift-u));
    border-radius: 50%;
    background: radial-gradient(circle,
      rgba(255, 248, 225, 0.98) 0%,
      rgba(255, 215, 130, 0.70) 30%,
      rgba(255, 198, 105, 0.35) 52%,
      rgba(255, 198, 105, 0) 72%);
    transform: translate(-50%, 0) scale(0.4);
    opacity: 0;
    transition: opacity 0.4s, transform 0.55s;
    pointer-events: none;
  }

  .mobile-cta-strip .cta-gift__box {
    position: absolute;
    z-index: 2;
    left: calc(9 * var(--dg-gift-u));
    bottom: 0;
    width: calc(50 * var(--dg-gift-u));
    height: calc(38 * var(--dg-gift-u));
    border-radius: calc(3 * var(--dg-gift-u)) calc(3 * var(--dg-gift-u))
                   calc(6 * var(--dg-gift-u)) calc(6 * var(--dg-gift-u));
    background: linear-gradient(158deg, #fff 0%, #f0ebff 55%, #ded4fb 100%);
    box-shadow: inset 0 calc(-5 * var(--dg-gift-u)) calc(9 * var(--dg-gift-u)) rgba(189, 86, 56, 0.16),
                0 calc(4 * var(--dg-gift-u)) calc(9 * var(--dg-gift-u)) calc(-2 * var(--dg-gift-u)) rgba(60, 30, 18, 0.35);
  }
  .mobile-cta-strip .cta-gift__lid {
    position: absolute;
    z-index: 4;
    left: calc(1 * var(--dg-gift-u));
    bottom: calc(35 * var(--dg-gift-u));
    width: calc(66 * var(--dg-gift-u));
    height: calc(16 * var(--dg-gift-u));
    border-radius: calc(4 * var(--dg-gift-u));
    background: linear-gradient(158deg, #fff 0%, #f4efff 60%, #e3dafc 100%);
    box-shadow: 0 calc(4 * var(--dg-gift-u)) calc(8 * var(--dg-gift-u)) calc(-2 * var(--dg-gift-u)) rgba(60, 30, 18, 0.32),
                inset 0 calc(-4 * var(--dg-gift-u)) calc(6 * var(--dg-gift-u)) rgba(189, 86, 56, 0.13);
    /* Hinged at the near-left corner, so it swings up and away rather than
       floating straight off the top. */
    transform-origin: 15% 100%;
    transition: transform 0.5s cubic-bezier(0.34, 1.5, 0.64, 1);
  }

  /* Dot texture on the wrapping paper - a printed pattern, not geometry, so
     the dots stay a fixed size instead of scaling with the parcel. */
  .mobile-cta-strip .cta-gift__box::after,
  .mobile-cta-strip .cta-gift__lid::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(circle, rgba(189, 86, 56, 0.2) 1px, transparent 1.3px) 0 0 / 9px 9px;
  }
  .mobile-cta-strip .cta-gift__box::after { opacity: 0.65; }
  .mobile-cta-strip .cta-gift__lid::after { opacity: 0.55; }

  /* Gold ribbon, one band down the box and one across the lid so the two
     line up while the lid is closed. */
  .mobile-cta-strip .cta-gift__rib,
  .mobile-cta-strip .cta-gift__lidrib {
    position: absolute;
    z-index: 1;
    left: 50%;
    top: 0;
    bottom: 0;
    width: calc(12 * var(--dg-gift-u));
    transform: translateX(-50%);
    background: linear-gradient(90deg, #d9a049 0%, #ffdd8f 42%, #f6c76b 62%, #d59c44 100%);
  }

  /* Highlight down the left face - the paper reads glossy, not flat. */
  .mobile-cta-strip .cta-gift__gloss {
    position: absolute;
    z-index: 1;
    left: calc(4 * var(--dg-gift-u));
    top: calc(4 * var(--dg-gift-u));
    width: calc(15 * var(--dg-gift-u));
    height: calc(26 * var(--dg-gift-u));
    border-radius: calc(7 * var(--dg-gift-u));
    background: linear-gradient(158deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 72%);
  }

  /* ── The bow: two loops, two tails, one knot ── */
  .mobile-cta-strip .cta-gift__bow {
    position: absolute;
    z-index: 2;
    left: 50%;
    bottom: calc(12 * var(--dg-gift-u));
    width: calc(40 * var(--dg-gift-u));
    height: calc(22 * var(--dg-gift-u));
    transform: translateX(-50%);
  }
  .mobile-cta-strip .cta-gift__loop {
    position: absolute;
    bottom: calc(3 * var(--dg-gift-u));
    width: calc(18 * var(--dg-gift-u));
    height: calc(17 * var(--dg-gift-u));
    background: linear-gradient(155deg, #fff0cb 0%, #f5c669 62%, #e2a747 100%);
    box-shadow: inset 0 calc(-2 * var(--dg-gift-u)) calc(4 * var(--dg-gift-u)) rgba(150, 100, 20, 0.3);
  }
  /* Lopsided border-radii, mirrored left to right: that asymmetry is what
     makes the loops read as folded ribbon rather than as two circles. */
  .mobile-cta-strip .cta-gift__loop--l {
    left: 0;
    border-radius: 72% 38% 42% 62%;
    transform: rotate(-17deg);
  }
  .mobile-cta-strip .cta-gift__loop--r {
    right: 0;
    border-radius: 38% 72% 62% 42%;
    transform: rotate(17deg);
  }
  .mobile-cta-strip .cta-gift__tail {
    position: absolute;
    bottom: calc(-7 * var(--dg-gift-u));
    width: calc(9 * var(--dg-gift-u));
    height: calc(14 * var(--dg-gift-u));
    background: linear-gradient(180deg, #f3c069, #dfa143);
    /* Notched foot - the V-cut every ribbon end has. */
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 70%, 0 100%);
  }
  .mobile-cta-strip .cta-gift__tail--l { left: calc(9 * var(--dg-gift-u)); transform: rotate(15deg); }
  .mobile-cta-strip .cta-gift__tail--r { right: calc(9 * var(--dg-gift-u)); transform: rotate(-15deg); }
  .mobile-cta-strip .cta-gift__knot {
    position: absolute;
    left: 50%;
    bottom: 0;
    width: calc(12 * var(--dg-gift-u));
    height: calc(12 * var(--dg-gift-u));
    border-radius: 50%;
    transform: translateX(-50%);
    background: radial-gradient(circle at 34% 28%, #fff2d2, #e8ad48 78%);
    box-shadow: inset 0 calc(-2 * var(--dg-gift-u)) calc(3 * var(--dg-gift-u)) rgba(150, 100, 20, 0.38);
  }

  /* ── Sparkles ── */
  .mobile-cta-strip .cta-sparks {
    display: block;
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .mobile-cta-strip .cta-spark {
    position: absolute;
    width: calc(9 * var(--dg-gift-u));
    height: calc(9 * var(--dg-gift-u));
    background: #ffd479;
    clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
    opacity: 0;
  }
  .mobile-cta-strip .cta-spark--w { background: #fff; }
  /* Staggered delays on a shared 2.6s cycle, so they blink in turn instead of
     pulsing together. Physical left/right on purpose: the sparkles are
     decoration scattered over the button face, not part of the reading order,
     so they keep their positions in he/ar rather than mirroring. */
  .mobile-cta-strip .cta-spark--1 {
    top: calc(8 * var(--dg-gift-u));
    right: calc(15 * var(--dg-gift-u));
    animation: dg-gift-twinkle 2.6s ease-in-out infinite;
  }
  .mobile-cta-strip .cta-spark--2 {
    top: calc(27 * var(--dg-gift-u));
    left: calc(11 * var(--dg-gift-u));
    width: calc(7 * var(--dg-gift-u));
    height: calc(7 * var(--dg-gift-u));
    animation: dg-gift-twinkle 2.6s ease-in-out 0.5s infinite;
  }
  .mobile-cta-strip .cta-spark--3 {
    top: calc(57 * var(--dg-gift-u));
    right: calc(9 * var(--dg-gift-u));
    width: calc(6 * var(--dg-gift-u));
    height: calc(6 * var(--dg-gift-u));
    animation: dg-gift-twinkle 2.6s ease-in-out 1.1s infinite;
  }
  .mobile-cta-strip .cta-spark--4 {
    top: calc(45 * var(--dg-gift-u));
    left: calc(19 * var(--dg-gift-u));
    width: calc(7 * var(--dg-gift-u));
    height: calc(7 * var(--dg-gift-u));
    animation: dg-gift-twinkle 2.6s ease-in-out 1.7s infinite;
  }

  /* ── Hover / focus: the box opens ── */
  @media (hover: hover) and (pointer: fine) {
    .mobile-cta-strip .btn:hover,
    .mobile-cta-strip .btn.btn-primary:hover,
    .mobile-cta-strip .btn:focus-visible,
    .mobile-cta-strip .btn.btn-primary:focus-visible {
      transform: translateY(-4px) scale(1.04);
      box-shadow: 0 20px 40px -8px rgba(189, 86, 56, 0.5),
                  0 3px 10px rgba(60, 30, 18, 0.16);
    }
    /* The hop stops the moment the pointer lands: the parcel should hold
       still while the lid comes off, or the two motions fight each other. */
    .mobile-cta-strip .btn:hover .cta-gift,
    .mobile-cta-strip .btn:focus-visible .cta-gift { animation-play-state: paused; }

    .mobile-cta-strip .btn:hover .cta-gift__lid,
    .mobile-cta-strip .btn:focus-visible .cta-gift__lid {
      transform: translateY(calc(-17 * var(--dg-gift-u))) rotate(-19deg);
    }
    .mobile-cta-strip .btn:hover .cta-gift__glow,
    .mobile-cta-strip .btn:focus-visible .cta-gift__glow {
      opacity: 1;
      transform: translate(-50%, calc(-13 * var(--dg-gift-u))) scale(1.05);
    }
    /* Sparkles speed up rather than stop - the button reads "alive" exactly
       when the reader is looking straight at it. */
    .mobile-cta-strip .btn:hover .cta-spark,
    .mobile-cta-strip .btn:focus-visible .cta-spark { animation-duration: 1.1s; }
  }
  .mobile-cta-strip .btn:active,
  .mobile-cta-strip .btn.btn-primary:active {
    transform: translateY(-1px) scale(0.99);
    transition-duration: 120ms;
  }
}

/* A short, slow hop with two settling bounces - the parcel is idling, not
   bouncing. Still for well over half of every cycle, which is what keeps an
   always-on-screen element from turning into noise. */
@keyframes dg-gift-hop {
  0%, 58%, 100% { transform: translateY(0) rotate(0deg); }
  66%           { transform: translateY(calc(-7 * var(--dg-gift-u))) rotate(-5deg); }
  74%           { transform: translateY(0) rotate(4deg); }
  82%           { transform: translateY(calc(-3 * var(--dg-gift-u))) rotate(-2deg); }
  90%           { transform: translateY(0) rotate(0deg); }
}

/* Each sparkle is invisible most of the cycle and turns as it flares, so the
   four of them read as glints catching the light rather than as blinking
   dots. */
@keyframes dg-gift-twinkle {
  0%, 100% { opacity: 0; transform: scale(0.3) rotate(0deg); }
  45%      { opacity: 1; transform: scale(1) rotate(60deg); }
}

@media (min-width: 768px) and (max-width: 1339px) {
  /* Tablet and narrow-laptop width: the gutter beside the article column is
     under 200px here (see the gutter table above), which is not enough for
     the gift square to sit clear of the text. So the strip stays, shrunk to
     its content rather than spanning the whole width. Upper bound tracks the
     1340px breakpoint above - the two must always meet exactly, or the CTA
     would fall back to the full-width mobile strip in the gap between. */
  .mobile-cta-strip {
    left: auto;
    right: auto;
    inset-inline-end: 5.75rem;
    bottom: 1rem;
    width: auto;
    max-width: min(22rem, calc(100vw - 8rem));
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    transform: translateY(150%);
  }
  .mobile-cta-strip.is-visible { transform: translateY(0); }
  .mobile-cta-strip .btn {
    border-radius: 999px;
    padding: 0.7rem 1.4rem;
    white-space: nowrap;
    box-shadow: 0 6px 22px -8px rgba(189, 86, 56, 0.65);
    animation: dg-cta-breathe 9s ease-in-out infinite;
  }
}

/* ============================================================
   ARCHIVE — AJAX loader (mirrors My Wishes loader styling so
   the two pages feel like one product). Scoped to the archive
   wrap so we don't pull all of wishes-v2.css onto /articles/.
   ============================================================ */
/* Wrap covers featured + grid + pagination + load-more + empty-state, so
   the loader overlay drapes the entire content block during AJAX. */
.archive-grid-shell #articles-content-wrap { position: relative; min-height: 200px; }
.archive-grid-shell .wish-grid-loader {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 80px;
  background: rgba(245, 243, 240, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-radius: var(--radius-md, 16px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
  z-index: 2;
}
.archive-grid-shell #articles-content-wrap.is-loading .wish-grid-loader {
  opacity: 1;
  pointer-events: auto;
}

/* Featured slot — collapse the wrapper completely when empty so it never
   leaves a visual gap above the grid. Same trick on .articles-grid for the
   "1 result becomes featured, grid is empty" case (margin-bottom 3rem on
   the grid would otherwise show as a blank band below featured). */
.archive-grid-shell #featured-slot:empty { display: none; }
.archive-grid-shell .articles-grid:empty { display: none; }
.archive-grid-shell .wish-grid-spinner {
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 3px solid rgba(189, 86, 56, 0.18);
  border-top-color: var(--color-primary, #bd5638);
  animation: dg-archive-spin 0.7s linear infinite;
}
@keyframes dg-archive-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .archive-grid-shell .wish-grid-spinner { animation-duration: 1.6s; }
}

/* ============================================================
   ARCHIVE — "Show more" button row.
   ============================================================ */
.archive-grid-shell .load-more-wrap {
  display: flex;
  justify-content: center;
  padding: 0.5rem 0 2rem;
}
.archive-grid-shell .load-more-wrap[hidden] { display: none; }
.archive-grid-shell .load-more-btn {
  padding: 0.85rem 2.25rem;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.archive-grid-shell .load-more-btn:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Empty-state inside the grid (when AJAX returns 0 items). */
.archive-grid-shell .archive-empty {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--color-text-muted, #767672);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* Empty-state component — blog uses the same look as the My Wishes
   no-results block (.empty-state + .empty-icon from wishes-v2.css), but
   wishes-v2.css isn't loaded on /articles/, so we restate the styles here
   scoped under .archive-grid-shell. */
.archive-grid-shell .empty-state {
  text-align: center;
  padding: 4rem 1rem;
}
.archive-grid-shell .empty-state[hidden] { display: none; }
.archive-grid-shell .empty-state .empty-icon {
  width: 80px; height: 80px;
  border-radius: 50%;
  background: var(--color-primary-light, rgba(189, 86, 56, 0.1));
  color: var(--color-primary, #bd5638);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 1.25rem;
}
.archive-grid-shell .empty-state :is(h2, h3) {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
}
.archive-grid-shell .empty-state p {
  color: var(--color-text-muted, #767672);
  font-size: 0.95rem;
  line-height: 1.55;
  max-width: 420px;
  margin: 0 auto;
}

/* Plain `[hidden]` is overridden by display:flex/grid on the grid + featured
   slot — make sure hidden truly hides them. */
.articles-grid[hidden],
.featured-card[hidden],
.load-more-wrap[hidden],
.archive-grid-shell .pagination[hidden] {
  display: none !important;
}

/* Search clear button — small × inside the search field. Mirrors the My
   Wishes clear button so the two pages feel consistent. */
.archive-search { position: relative; }
.archive-search .search-clear {
  background: transparent;
  border: 0;
  cursor: pointer;
  width: 28px; height: 28px;
  display: inline-flex;
  align-items: center; justify-content: center;
  border-radius: 50%;
  color: var(--color-text-muted, #767672);
  margin-inline-start: -0.25rem;
  margin-inline-end: 0.25rem;
  flex-shrink: 0;
  transition: background 0.18s ease, color 0.18s ease;
}
.archive-search .search-clear:hover {
  background: rgba(189, 86, 56, 0.1);
  color: var(--color-primary, #bd5638);
}
.archive-search .search-clear[hidden] { display: none; }

/* ============================================================
   ANIMATIONS — subtle by design, all gated by reduced-motion.
   ============================================================ */

/* Card scroll-reveal убран — пользователи жаловались на «контент
   появляется с задержкой при скролле» на Safari (где IntersectionObserver
   запаздывает или CSP-задержки откладывают `.is-revealed`). Карточки
   теперь рендерятся сразу. blog.js всё ещё навешивает `.is-revealed`,
   но без CSS это no-op. data-reveal атрибуты в template-parts остаются —
   безвредны без сопровождающих стилей. */

/* Eyebrow dot — soft "live" pulse halo. Below 1.6s and 0.5
   max opacity so it reads as ambient, not as flashing UI. */
.archive-eyebrow .dot { position: relative; }
@media (prefers-reduced-motion: no-preference) {
  .archive-eyebrow .dot::after {
    content: "";
    position: absolute;
    inset: -2px;
    border-radius: 50%;
    background: var(--color-primary, #bd5638);
    opacity: 0.45;
    animation: dg-dot-pulse 1.6s ease-in-out infinite;
    pointer-events: none;
  }
  @keyframes dg-dot-pulse {
    0%, 100% { transform: scale(1);   opacity: 0.45; }
    50%      { transform: scale(2.4); opacity: 0;    }
  }
}

/* Card image zoom on hover — overflow:hidden on the parent
   article-card already exists in the design; scaling stays
   contained by the rounded corner. */
@media (prefers-reduced-motion: no-preference) {
  .article-card .ac-img,
  .featured-card .featured-img {
    transition: transform 0.5s var(--ease-standard, cubic-bezier(0.4, 0, 0.2, 1));
    will-change: transform;
  }
  .article-card:hover .ac-img,
  .article-card:focus-visible .ac-img { transform: scale(1.04); }
  .featured-card:hover .featured-img,
  .featured-card:focus-visible .featured-img { transform: scale(1.025); }
}

/* Filter pill — focus ring (a11y). */
.filter-pill:focus-visible {
  outline: 2px solid var(--color-primary, #bd5638);
  outline-offset: 2px;
}

/* === SORT DROPDOWN — match design (pill + custom chevron) ===============
   Chrome/Firefox/Safari render <select> with a wide native arrow that
   doesn't fit the design language. We strip it via -webkit-appearance:none
   + appearance:none and bake a custom chevron SVG into the background.
   Padding-right accounts for the chevron's space.
   ============================================================ */
.archive-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.85rem;
  color: var(--color-text-muted, #767672);
}
.archive-sort > span {
  font-weight: 600;
  color: var(--color-text-muted, #767672);
  white-space: nowrap;
}
.archive-sort select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: 1px solid var(--color-border, #e6e2dc);
  background-color: var(--color-bg-white, #fff);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236050b0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 14px 14px;
  border-radius: var(--radius-pill, 999px);
  padding: 0.55rem 2.1rem 0.55rem 1rem;
  font-family: var(--font-primary, inherit);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text-dark, #313330);
  cursor: pointer;
  line-height: 1.2;
  min-width: 11rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
[dir="rtl"] .archive-sort select {
  background-position: left 0.75rem center;
  padding: 0.55rem 1rem 0.55rem 2.1rem;
}
.archive-sort select:hover,
.archive-sort select:focus {
  border-color: rgba(189, 86, 56, 0.45);
  outline: none;
  box-shadow: 0 0 0 3px rgba(189, 86, 56, 0.12);
}
.archive-sort select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
/* Strip Firefox's dotted text-shadow + inner focus outline */
.archive-sort select::-moz-focus-inner { border: 0; }
.archive-sort select:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--color-text-dark, #313330); }
/* Native option list inherits OS look — there's no cross-browser way to
   skin <option>. Most users see the design's chevron + pill on the trigger,
   which is what the mockup shows; the popup is OS-rendered and acceptable. */

/* ============================================================
   MOBILE — archive overrides — 1:1 mirror of the design's
   .mobile-shell rules from blog-redesign.css (lines 1438-1511).
   The design ships those scoped to its Figma artboard wrapper;
   here we promote them to a real @media query so they apply on
   live phone widths.
   ============================================================ */
@media (max-width: 767px) {
  /* Shell padding tightens so cards reach the edge. */
  .archive-grid-shell { padding: 0 1rem; }

  /* Hero — full-bleed on mobile (no border-radius, no margin). */
  .archive-hero {
    border-radius: 0;
    padding: 1rem 1rem 1.25rem;
    margin: 0;
  }
  .archive-hero::before {
    width: 200px; height: 200px;
    inset-inline-end: -80px; top: -80px;
  }
  .archive-title { font-size: 2rem; margin-bottom: 0.65rem; }
  .archive-lede  { font-size: 0.92rem; margin-bottom: 1rem; max-width: none; }
  .archive-search { padding: 0.4rem 0.4rem 0.4rem 0.85rem; max-width: none; }
  .archive-search input { font-size: 0.88rem; }
  /* Submit button is hidden on mobile entirely — search runs via debounced
     input (AJAX), so an explicit submit is redundant on phones. */
  .archive-search button[type="submit"] { display: none; }
  .archive-stats { font-size: 0.75rem; gap: 0.85rem; margin-top: 0.85rem; flex-wrap: wrap; }

  /* Filters row — pills horizontal-scroll, sort below pills, right-aligned.
     Horizontal padding lives on the shell (1rem); the row itself has 0
     horizontal padding so pills can bleed to the screen edge during scroll. */
  .archive-filters-row {
    padding: 0.85rem 0 0.5rem;
    gap: 0.5rem;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
    max-width: 100%;
    flex-wrap: nowrap;
  }
  .archive-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.25rem;
    /* The shorthand `padding: 0 1rem` wins over padding-left/right:0 — keeps
       a gutter on the leading/trailing pill so it doesn't kiss the edge. */
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding: 0 1rem !important;
    /* Negative margin lets the strip bleed past the shell padding so pills
       can scroll edge-to-edge; the inner padding restores the visual gutter. */
    margin: 0 -1rem;
    /* width:auto + max-width:none + parent's max-width:100%/min-width:0 lets
       the column-flex parent constrain this child to the row width while
       overflow-x:auto handles the pill-strip scroll inside. */
    max-width: none !important;
    width: auto !important;
    min-width: 0;
    box-sizing: border-box;
    scrollbar-width: none;
  }
  .archive-filters::-webkit-scrollbar { display: none; }
  .filter-pill { white-space: nowrap; flex-shrink: 0; padding: 0.45rem 0.85rem; font-size: 0.8rem; }
  .archive-sort { font-size: 0.78rem; }
  .archive-sort select {
    padding: 0.5rem 1.85rem 0.5rem 0.85rem;
    font-size: 0.78rem;
    min-width: 9rem;
  }

  /* Featured card — stacked on mobile (image on top, body below). */
  .featured-card {
    grid-template-columns: 1fr !important;
    margin-bottom: 1.25rem;
    border-radius: var(--radius-md, 16px);
  }
  /* Card meta rows (cat · date · reading-time) wrap on narrow screens
     instead of forcing the row wider than the card. */
  .featured-meta,
  .ac-meta { flex-wrap: wrap; row-gap: 0.35rem; }
  .featured-card .featured-img { aspect-ratio: 16/10; }
  .featured-card .featured-body { padding: 1.25rem 1.35rem 1.4rem; }
  .featured-card h2 { font-size: 1.3rem; margin-bottom: 0.6rem; }
  .featured-card p { font-size: 0.88rem; margin-bottom: 1rem; }
  .featured-badge { padding: 0.3rem 0.75rem; font-size: 0.62rem; inset-inline-start: 0.85rem; top: 0.85rem; }

  /* Articles grid — single column. */
  .archive-grid-shell .articles-grid {
    grid-template-columns: 1fr;
    gap: 0.85rem;
    margin-bottom: 1.5rem;
  }

  /* Pagination — wrap if too many. */
  .archive-grid-shell .pagination { flex-wrap: wrap; gap: 0.3rem; margin-bottom: 1.25rem; }

  /* About-blog — collapse 1fr/auto grid into a single column; remove the
     240px CTA min-width that would squeeze the text into a ~130px ribbon. */
  .about-blog {
    grid-template-columns: 1fr;
    padding: 1.5rem 1.35rem;
    gap: 1.25rem;
    margin-bottom: 1.5rem;
    border-radius: var(--radius-md, 16px);
  }
  .about-blog h2 { font-size: 1.4rem; }
  .about-blog p  { font-size: 0.9rem; max-width: none; }
  .about-blog-meta { gap: 1rem; }
  .about-blog-meta .item strong { font-size: 1.15rem; }
  .about-blog-cta { min-width: 0; }

  /* Loader / empty-state / show-more — fit a phone screen. */
  .archive-grid-shell .wish-grid-loader { padding-top: 40px; }
  .archive-grid-shell #articles-content-wrap { min-height: 320px; }
  .archive-grid-shell .empty-state { padding: 2.5rem 0.5rem; }
  .archive-grid-shell .empty-state .empty-icon { width: 64px; height: 64px; }
  .archive-grid-shell .empty-state :is(h2, h3) { font-size: 1.2rem; }
  .archive-grid-shell .load-more-btn { padding: 0.7rem 1.5rem; font-size: 0.88rem; }
}

/* ============================================================
   SINGLE ARTICLE — clean alignment with Save button hidden.
   When .article-actions has only Share, it should still sit
   right-aligned at the end of .article-author-row.
   ============================================================ */
.article-actions:empty { display: none; }

/* Article-meta row (cat · date · reading-time) wraps onto a new line when
   there isn't enough horizontal room (narrow screens, RU/HE/AR locales
   with longer category names). row-gap keeps vertical spacing consistent
   with the original 0.65rem horizontal gap. */
.article-meta { flex-wrap: wrap; row-gap: 0.35rem; }

/* ============================================================
   SINGLE ARTICLE — mobile layout fixes.
   Breakpoint 1000px (not 767) — the article shell uses a 280px
   sidebar TOC + 1fr article column with 4rem gap; below ~1000px
   the layout cramps. We collapse to single-column earlier so the
   reading width stays comfortable on tablets and small laptops.
   ============================================================ */
@media (max-width: 1000px) {
  .article-shell {
    padding: 0.85rem 1rem 5rem;
    max-width: none;
  }
  .article-grid {
    /* minmax(0, 1fr) prevents the Swiper carousel's intrinsic slide widths
       from blowing the column out. Plain 1fr falls back to min-content. */
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 0;
  }
  .article {
    width: 100%;
    min-width: 0;
    max-width: 100%;
  }
  /* TOC desktop sidebar collapses on mobile — the JS-generated
     mobile <details> ToC takes over (already handled by blog.js#buildToc). */
  .toc { display: none; }

  /* Mobile ToC — promoted from the design's .mobile-shell .toc-mobile rules
     (blog-redesign.css:1317-1349, 1424-1429) into a real media query.
     Sticky below the site header so the user can jump to any heading
     mid-scroll. */
  .toc-mobile {
    display: block;
    background: var(--color-bg-white, #fff);
    border: 1px solid var(--color-border, #e6e2dc);
    border-radius: 12px;
    margin-bottom: 1rem;
    overflow: hidden;
    position: sticky;
    top: var(--header-height, 84px);
    z-index: 4;
    box-shadow: 0 4px 14px -10px rgba(0, 0, 0, 0.18);
  }
  .toc-mobile summary {
    list-style: none;
    cursor: pointer;
    padding: 0.85rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .toc-mobile summary::-webkit-details-marker { display: none; }
  .toc-mobile-label {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--color-text-dark, #313330);
    letter-spacing: -0.01em;
    flex: 1;
  }
  .toc-mobile-count {
    font-size: 0.78rem;
    color: var(--color-text-muted, #767672);
    margin-inline-end: 0.4rem;
  }
  .toc-mobile-chev {
    color: var(--color-primary, #bd5638);
    transition: transform 0.25s var(--ease-standard, cubic-bezier(0.4, 0, 0.2, 1));
    flex-shrink: 0;
  }
  .toc-mobile[open] .toc-mobile-chev { transform: rotate(180deg); }
  .toc-mobile[open] summary { border-bottom: 1px solid var(--color-border, #e6e2dc); }

  .article-title {
    font-size: 1.55rem;
    letter-spacing: -0.03em;
  }
  .article-lede {
    font-size: 0.95rem;
    margin-bottom: 1rem;
  }
  .article-hero {
    border-radius: 14px;
    margin-bottom: 1rem;
  }
  .article-author-row { padding-top: 0.85rem; }
  .author-avatar { width: 36px; height: 36px; }
  .author-name { font-size: 0.85rem; }
  .author-role { font-size: 0.72rem; }

  /* Read-next carousel on mobile — Swiper does its own width math, but
     we cap the column so the wrapper itself doesn't push the page wide. */
  .read-next-swiper { max-width: 100%; overflow: hidden; }
  .rn-card .rn-img { aspect-ratio: 16/10; width: 100%; }
  /* Read-next controls: arrows on the left, "view all" on the right
     so they fill the row evenly instead of clustering. */
  .rn-controls {
    width: 100%;
    justify-content: space-between;
    gap: 0.5rem;
  }
  .rn-all-btn { margin-inline-start: auto; }

  /* Body typography */
  .article-body h2 { font-size: 1.4rem; margin: 1.5rem 0 0.6rem; }
  .article-body h3 { font-size: 1.1rem; margin: 1.1rem 0 0.5rem; }
  .article-body p  { font-size: 0.97rem; line-height: 1.65; }

  .key-takeaways { padding: 1rem 1.15rem; margin-bottom: 1.25rem; }
  .kt-list li     { font-size: 0.88rem; }
  .callout        { padding: 1rem 1.15rem; margin: 1.25rem 0; }
  /* Callout--quote padding bumps come AFTER .callout shorthand so they
     aren't reset back to 1rem. The decorative " mark needs ~3rem clearance
     (mark is absolute-positioned at top:0.25rem, font-size 2.5rem). */
  .callout--quote {
    padding-block-start: 3rem;
    padding-inline-start: 3rem;
  }
  .callout--quote .callout-mark { font-size: 2.5rem; top: 0.25rem; }
  .inline-cta     { grid-template-columns: 1fr; padding: 1.5rem 1.35rem; text-align: center; }
  .inline-cta .btn{ width: 100%; justify-content: center; }
  .faq-item summary { padding: 0.95rem 1.1rem; font-size: 0.92rem; }
  .author-bio     { grid-template-columns: 1fr; text-align: center; padding: 1.35rem; gap: 0.85rem; }
  .bio-avatar     { width: 64px; height: 64px; margin: 0 auto; }
  /* Bio-stats — center horizontally on mobile (was justify-flex-start on
     desktop). align-items:center keeps strong+span vertically aligned. */
  .bio-stats {
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 1.25rem;
  }

  /* Share row — stack label above icons, both centered. The desktop layout
     puts label on the left and icons margin-inline-start:auto on the right;
     on narrow screens the icons would crowd against the label. */
  .share-row {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.75rem;
  }
  .share-row .share-btns {
    margin-inline-start: 0;
    justify-content: center;
  }
}

/* ============================================================
   IN-ARTICLE MEDIA (SCRUM-22) — figures (lightbox images) + process clip.
   Markup is generated by inc/article-render.php → dg_expand_article_media()
   from <!-- dg-media: ... --> tokens. Images open in dg-lightbox; the clip
   plays on scroll-into-view via article-media.js (muted, looped, RM-aware).
   ============================================================ */
.article-body .article-figure {
  margin: 2rem 0;
  text-align: center;
}
.article-body .article-figure picture {
  display: block;
}
.article-body .article-figure img,
.article-body .article-clip {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md, 16px);
  box-shadow: var(--shadow-md, 0 8px 24px -8px rgba(0, 0, 0, 0.18));
}
.article-body .article-figure__link {
  display: block;
  cursor: zoom-in;
  border-radius: var(--radius-md, 16px);
}
.article-body .article-figure__link:focus-visible {
  outline: 2px solid var(--color-primary, #bd5638);
  outline-offset: 3px;
}
.article-body .article-figure__cap {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--color-text-muted, #767672);
  text-align: center;
}
/* Mobile-shot process clip — phone aspect, capped width, centered. The
   width/height attrs on the <video> already reserve space; aspect-ratio
   reinforces it so the poster never causes layout shift. */
.article-body .article-figure--clip {
  max-width: 360px;
  margin-inline: auto;
}
.article-body .article-clip {
  aspect-ratio: 390 / 844;
  background: var(--color-bg-soft, #f5f3f0);
  object-fit: cover;
}
@media (max-width: 1000px) {
  .article-body .article-figure { margin: 1.5rem 0; }
  .article-body .article-figure--clip { max-width: 300px; }
}

/* --- Card thumbnails: real <picture> instead of a CSS background (21.08.2026)
       ------------------------------------------------------------------------
       article-card / featured-card / read-next used to paint the thumbnail with
       inline `background-image:url(...)`. A background cannot carry <source>, so
       the browser was stuck with the JPEG even though AVIF and WebP siblings of
       the very same file were already on disk: /articles/ downloaded 818 KB of
       JPEG where the AVIF set weighs about 130 KB.

       The three <span> boxes stay - they own the aspect-ratio, the rounded
       corners and the hover scale. The image is now a child that fills the box.
       .featured-img additionally has a ::after gradient wash and an absolutely
       positioned badge, so its picture is pinned with position:absolute and sits
       first in the DOM; ::after is generated after the last child and therefore
       still paints on top, exactly as it did over the background. */
.ac-img > picture,
.rn-img > picture,
.featured-img > picture {
  display: block;
  width: 100%;
  height: 100%;
}

.ac-img img,
.rn-img img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.featured-img > picture,
.featured-img > img {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.featured-img > img,
.featured-img > picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The mobile read-next card drops aspect-ratio for a 110px grid column
   (blog-redesign.css:1433) and stretches the box by height instead. Without
   min-height:0 the image's intrinsic height wins the grid sizing and the row
   grows past the design's 100px. */
@media (max-width: 700px) {
  .mobile-shell .rn-card .rn-img { min-height: 0; }
  .mobile-shell .rn-card .rn-img img { height: 100%; }
}
