/* ============================================================
   JZ CREATES — SINGLE WORK + BLOG TEMPLATES (2026)
   Loaded after styles.css and pages.css. `.jzw` is a work post,
   `.jzb` is an article.
   ============================================================ */

/* the theme prints its own wrapper padding on singular views */
.jzp .site-main,
.jzp .page-content { padding: 0; margin: 0; max-width: none; }
body.jzc-2026 { background: var(--bg); }

/* ============================================================
   WORK — hero
   The backdrop is FIXED and fades out as you scroll (pages.js writes
   the opacity), so the image stays put behind the opening instead of
   scrolling away with the title.
   ============================================================ */
.whero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 12rem var(--pad) 6rem;
  background: #000;
}
.whero--flat { min-height: 56vh; }
/* Starts hidden and fades up once the image has actually decoded, so the
   hero resolves out of black rather than snapping in. pages.js takes over the
   opacity from the first scroll onwards. */
.whero__media--fixed {
  position: fixed;
  inset: 0;
  z-index: 0;
  opacity: 0;
  transition: opacity 1.4s var(--ease-out);
  will-change: opacity, filter;
}
/* pages.js drives --wblur alongside the opacity, so the backdrop softens as
   it goes rather than simply dimming */
.whero__media--fixed img { filter: blur(var(--wblur, 0px)); transform: scale(1.04); }
.whero__media img { width: 100%; height: 100%; object-fit: cover; }
.whero__media .whero__scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 6, 7, 0.45);
}
.whero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
}
.whero h1 {
  font-size: clamp(2.6rem, 6.4vw, 5.6rem);
  line-height: 1.03;
  font-weight: 500;
}
.whero__sub {
  margin: 1.6rem auto 0;
  max-width: 60ch;
  color: var(--muted);
  font-size: clamp(1.08rem, 1.3vw, 1.28rem);
  line-height: 1.6;
}
.whero__tags { margin-bottom: 1.6rem; display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: center; }
a.wtag { transition: color 0.3s, border-color 0.3s; }
a.wtag:hover { color: var(--ink); border-color: rgba(214, 0, 237, 0.5); }

/* Everything after the hero rides over the fixed backdrop, so it needs its
   own opaque ground rather than letting the image show through. */
.wsec { position: relative; z-index: 1; background: var(--bg); }

@media (max-width: 767px) { .whero { min-height: 88vh; padding: 9rem var(--pad) 4rem; } }

/* ============================================================
   WORK BODY — re-skin, never restructure
   Each piece is authored per project in Elementor with its own layout,
   deliverables and sizes, so Elementor's own CSS is left enqueued for
   work posts. What follows only changes colour and type over the top of
   it; no layout properties are touched.
   ============================================================ */
.jzw .wbody { color: var(--muted); }
.jzw .wbody h1, .jzw .wbody h2, .jzw .wbody h3,
.jzw .wbody h4, .jzw .wbody h5, .jzw .wbody h6,
.jzw .wbody .elementor-heading-title {
  font-family: var(--font-display) !important;
  font-weight: 500 !important;
  color: var(--ink) !important;
  line-height: 1.12 !important;
  letter-spacing: 0;
}
.jzw .wbody p,
.jzw .wbody li,
.jzw .wbody .elementor-widget-text-editor {
  font-family: var(--font-body) !important;
  color: var(--muted) !important;
  line-height: 1.7;
}
.jzw .wbody strong, .jzw .wbody b { color: var(--ink) !important; }

/* ---------- the four heading levels inside a portfolio piece ----------
   h2  section header      Playfair, cream, full scale
   h3  sub-header          Playfair, crimson, smaller  ("Step 1.", "The Vision")
   h4  description text    Inter, muted                (a line under a header)
   h5  meta label          Inter, uppercase, small     ("Client", "Platform")
   Heading levels were normalised in the Elementor data so this scale applies
   by tag, rather than guessing at the markup of each individual piece. */
.jzw .wbody h2,
.jzw .wbody h2.elementor-heading-title,
.jzw .wbody h2 .elementor-heading-title {
  font-family: var(--font-display) !important;
  font-style: normal !important;
  font-size: clamp(2rem, 3.6vw, 3.2rem) !important;
  line-height: 1.08 !important;
  background: none !important;
  -webkit-text-fill-color: var(--ink) !important;
  color: var(--ink) !important;
}

.jzw .wbody h3,
.jzw .wbody h3.elementor-heading-title,
.jzw .wbody h3 .elementor-heading-title {
  font-family: var(--font-display) !important;
  font-style: normal !important;
  font-size: clamp(1.2rem, 1.6vw, 1.5rem) !important;
  font-weight: 500 !important;
  line-height: 1.25 !important;
  background: none !important;
  -webkit-text-fill-color: var(--gold) !important;
  color: var(--gold) !important;
}

/* The value under a meta label (the client name, the platform) is the thing
   the reader actually wants, so it is set in the display face in cream rather
   than as muted body copy. */
.jzw .wbody h4,
.jzw .wbody h4.elementor-heading-title,
.jzw .wbody h4 .elementor-heading-title,
.jzw .wbody h4 span,
.jzw .wbody h4 mark {
  font-family: var(--font-display) !important;
  font-size: clamp(1.25rem, 1.7vw, 1.6rem) !important;
  font-weight: 500 !important;
  font-style: normal !important;
  line-height: 1.35 !important;
  color: var(--ink) !important;
  -webkit-text-fill-color: var(--ink) !important;
  /* several of these lines were authored with a coloured highlight behind them */
  background: none !important;
  padding: 0 !important;
  box-shadow: none !important;
}

.jzw .wbody h5,
.jzw .wbody h5.elementor-heading-title,
.jzw .wbody h5 .elementor-heading-title {
  font-family: var(--font-body) !important;
  font-size: 0.78rem !important;
  font-weight: 600 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  line-height: 1.3 !important;
  background: none !important;
  -webkit-text-fill-color: var(--muted) !important;
  color: var(--muted) !important;
  margin-bottom: 0.2rem !important;
}

/* A column holding a sub-header plus its copy reads as a card, which is how
   the Vision / Concept / Execution / Results sets were designed. */
.jzw .wbody .elementor-column:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .e-con.e-child:has(h3):has(.elementor-widget-text-editor) {
  padding: 2.2rem 2rem 2.8rem !important;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.025);
}

/* lists inside a piece keep their markers */
.jzw .wbody ul { list-style: disc outside !important; padding-left: 1.4rem !important; }
.jzw .wbody ol { list-style: decimal outside !important; padding-left: 1.4rem !important; }
.jzw .wbody li { display: list-item !important; }
.jzw .wbody li::marker { color: var(--gold); }
/* a list butting straight up against the paragraph above it read as one block */
.jzw .wbody ul, .jzw .wbody ol { margin-top: 1rem !important; margin-bottom: 1.4rem !important; }
.jzw .wbody li + li { margin-top: 0.45rem; }
/* bullets stay left-aligned even inside a centred section */
.jzw .wbody ul, .jzw .wbody ol { text-align: left !important; }
.jzw .wbody li { text-align: left !important; }
/* a list whose items already carry a tick uses the tick as the marker */
.jzw .wbody li.jzc-ticked { list-style: none !important; }

.jzw .wbody a { color: var(--ink); }
.jzw .wbody a:hover { color: var(--crimson); }
.jzw .wbody img, .jzw .wbody video { border-radius: 14px; }
/* Elementor sections default to a white ground on some widgets */
.jzw .wbody .elementor-section,
.jzw .wbody .e-con,
.jzw .wbody .elementor-widget-container { background-color: transparent !important; }
.jzw .wbody blockquote {
  border-left: 2px solid var(--crimson);
  padding-left: 1.6rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  color: var(--ink);
}

.pcta__wide { max-width: 74ch !important; }

/* ============================================================
   SHARE
   ============================================================ */
.share {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.jzw .share {
  margin-top: 3.4rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
  justify-content: center;
}
.jzw .share__label { width: 100%; text-align: center; margin: 0 0 0.4rem; }
.share__label {
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 0.4rem;
}
.share__btn {
  display: inline-grid;
  place-items: center;
  min-width: 2.6rem;
  height: 2.6rem;
  padding: 0 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.9rem;
  cursor: pointer;
  transition: color 0.3s, border-color 0.3s, transform 0.3s var(--ease-out);
}
.share__btn:hover { color: var(--ink); border-color: rgba(214, 0, 237, 0.5); transform: translateY(-2px); }
.share__btn.is-done { color: var(--crimson); border-color: var(--crimson); }

/* ============================================================
   BLOG — LIGHT BY DEFAULT
   Long-form on a dark ground is hard work, so the reading surface has
   its own palette. Tokens are re-pointed on the article wrapper and
   `data-read="dark"` on <html> swaps them for night reading. The nav,
   footer and closing CTA stay dark in both modes, so an article reads
   as a page inside the site rather than a different site.
   ============================================================ */
.jzb .post {
  --paper: #fbfaf8;
  --paper-2: #f2efea;
  --pink: #16161a;
  --pink-soft: #55524d;
  --rule: rgba(20, 20, 24, 0.12);
  background: var(--paper);
  color: var(--pink);
  padding: 8rem 0 5rem;
}
html[data-read="dark"] .jzb .post {
  --paper: #0f0f12;
  --paper-2: #17171c;
  --pink: #f2efeb;
  --pink-soft: #b3aea6;
  --rule: rgba(246, 243, 239, 0.12);
}

.jzb .post h1, .jzb .post h2, .jzb .post h3,
.jzb .post h4, .jzb .post strong { color: var(--pink); }
.jzb .post a { color: var(--pink); }

/* ---------- layout: article left, sidebar right ---------- */
.post__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 4rem;
  align-items: start;
}
@media (max-width: 1024px) { .post__layout { grid-template-columns: 1fr; gap: 3rem; } }
.post__main { min-width: 0; }

.post__topics { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.jzb .post .wtag { color: var(--pink-soft); border-color: var(--rule); }
.post__head h1 {
  font-size: clamp(2.2rem, 4vw, 3.6rem);
  line-height: 1.08;
  font-weight: 500;
}
.post__meta {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin-top: 1.4rem;
  font-size: 0.95rem;
  color: var(--pink-soft);
}
.post__dot { opacity: 0.5; }

.post__hero {
  margin: 2rem 0 2.6rem;
  border-radius: 20px;
  overflow: hidden;
  background: var(--paper-2);
}
.post__hero img { width: 100%; height: auto; display: block; }

/* ---------- article body ----------
   Section headings are crimson for colour and set tighter than the body,
   which previously read as loose next to the old article. */
.post__body { font-size: 1.12rem; line-height: 1.72; color: var(--pink); }
.post__body > * + * { margin-top: 1.35rem; }
.jzb .post__body h2,
.jzb .post__body h3,
.jzb .post__body h4 {
  color: var(--crimson) !important;
  font-weight: 500;
  line-height: 1.18;
}
.post__body h2 { font-size: clamp(1.7rem, 2.6vw, 2.2rem); margin-top: 2.8rem; }
.post__body h3 { font-size: clamp(1.35rem, 2vw, 1.7rem); margin-top: 2.2rem; }
.post__body h4 { font-size: 1.2rem; margin-top: 1.8rem; }
.post__body h2 + p, .post__body h3 + p, .post__body h4 + p { margin-top: 0.8rem; }
.post__body a { border-bottom: 1px solid rgba(255, 36, 56, 0.55); }
.post__body a:hover { color: var(--crimson); }
.post__body img, .post__body video, .post__body iframe { max-width: 100%; border-radius: 14px; }
.post__body img { height: auto; display: block; }
.post__body figure { margin-block: 2.2rem; }
.post__body figcaption { margin-top: 0.7rem; font-size: 0.9rem; color: var(--pink-soft); }
/* Markers were being stripped by the reset, which flattened Key Takeaways
   and every other list into loose paragraphs. */
.post__body ul { list-style: disc outside !important; padding-left: 1.4rem; }
.post__body ol { list-style: decimal outside !important; padding-left: 1.4rem; }
.post__body li { display: list-item !important; }
.post__body li::marker { color: var(--crimson); }
.post__body li + li { margin-top: 0.5rem; }
.post__body blockquote {
  border-left: 2px solid var(--crimson);
  padding-left: 1.6rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1.4;
}
.post__body table { width: 100%; border-collapse: collapse; font-size: 0.98rem; }
.post__body th, .post__body td { border: 1px solid var(--rule); padding: 0.7rem 0.9rem; text-align: left; }
/* wide content scrolls inside itself rather than pushing the page sideways */
.post__body pre, .post__body table { display: block; overflow-x: auto; }

/* ---------- author ---------- */
.post__author {
  display: grid;
  grid-template-columns: 108px 1fr;
  gap: 1.6rem;
  align-items: center;
  margin-top: 3.4rem;
  padding-top: 2.4rem;
  border-top: 1px solid var(--rule);
}
.post__author-pic { width: 108px; height: 108px; border-radius: 50%; object-fit: cover; }
.post__author h3 { font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; color: var(--crimson); margin-bottom: 0.6rem; }
.post__author p { color: var(--pink-soft); line-height: 1.65; }
@media (max-width: 560px) { .post__author { grid-template-columns: 1fr; } }

/* ---------- follow + share ---------- */
.post__foot {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.4rem;
  margin-top: 2.6rem;
  padding-top: 2.2rem;
  border-top: 1px solid var(--rule);
}
@media (max-width: 700px) { .post__foot { grid-template-columns: 1fr; gap: 1.8rem; } }
.post__foot h3 { font-family: var(--font-display); font-size: 1.25rem; font-weight: 500; color: var(--crimson); margin-bottom: 1rem; }
.post__follow { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.post__follow a {
  padding: 0.5rem 1rem;
  border-radius: 999px;
  border: 1px solid var(--rule);
  color: var(--pink-soft);
  font-size: 0.88rem;
  transition: color 0.3s, border-color 0.3s;
}
.post__follow a:hover { color: var(--crimson); border-color: var(--crimson); }
.jzb .share__label { display: none; }
.jzb .share__btn { color: var(--pink-soft); border-color: var(--rule); }
.jzb .share__btn:hover { color: var(--crimson); border-color: var(--crimson); }

/* ---------- sidebar ---------- */
/* Deliberately NOT sticky. Pinning it meant the column sat still until the
   article ran out, which read as broken; it now scrolls with the page. */
.post__side { display: grid; gap: 1.2rem; align-content: start; }

.side-card {
  padding: 1.8rem 1.6rem;
  border-radius: 16px;
  border: 1px solid var(--rule);
  background: var(--paper-2);
}
.side-card h3 {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 500;
  margin-bottom: 0.7rem;
}
.side-card > p { color: var(--pink-soft); font-size: 0.98rem; line-height: 1.6; margin-bottom: 1.2rem; }
.side-card__alt {
  display: inline-block;
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--pink-soft);
  border-bottom: 1px solid transparent;
  transition: color 0.3s, border-color 0.3s;
}
.side-card__alt:hover { color: var(--crimson); border-color: var(--crimson); }

/* the newsletter form posts its own height; the min-height is the fallback */
.side-card--form { background: linear-gradient(160deg, rgba(255, 0, 0, 0.06), rgba(214, 0, 237, 0.06)); }
.side-card--form iframe { width: 100%; border: 0; min-height: 430px; display: block; }

.side-card__label {
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pink-soft);
  margin-bottom: 0.8rem;
}
.side-card--ad { text-align: center; }
.side-card--ad img, .side-card--ad iframe, .side-card--ad ins { max-width: 100%; border-radius: 10px; }

.side-rel { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.side-rel li + li { border-top: 1px solid var(--rule); padding-top: 1rem; }
.side-rel a { display: grid; grid-template-columns: 84px 1fr; gap: 0.9rem; align-items: center; }
.side-rel__thumb { border-radius: 10px; overflow: hidden; aspect-ratio: 1 / 1; background: var(--paper); }
.side-rel__thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease-out); }
.side-rel a:hover .side-rel__thumb img { transform: scale(1.08); }
.side-rel time { display: block; font-size: 0.76rem; color: var(--pink-soft); letter-spacing: 0.05em; }
.side-rel strong {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.98rem;
  font-weight: 500;
  line-height: 1.3;
}
.side-rel a:hover strong { color: var(--crimson); }

/* ---------- reading mode: pinned, reachable at any scroll position ---------- */
.readtoggle {
  position: fixed;
  left: 1.4rem;
  bottom: 1.4rem;
  z-index: 260;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem 1.2rem;
  border-radius: 999px;
  border: 1px solid rgba(246, 243, 239, 0.16);
  background: rgba(14, 14, 17, 0.88);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  transition: color 0.3s, border-color 0.3s, transform 0.3s var(--ease-out);
}
.readtoggle:hover { color: var(--ink); border-color: rgba(214, 0, 237, 0.5); transform: translateY(-2px); }
.readtoggle__ico {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: currentColor;
  /* a crescent; the cut-out fills in when night mode is on */
  box-shadow: inset -4px -1px 0 0 rgba(14, 14, 17, 0.95);
}
html[data-read="dark"] .readtoggle__ico { box-shadow: none; }
@media (max-width: 560px) { .readtoggle { left: 0.9rem; bottom: 0.9rem; padding: 0.6rem 1rem; } }

/* the CTA stays on the dark ground in both reading modes */
.jzb .pcta { background: var(--bg); color: var(--ink); }
.jzb .pcta h2 { color: var(--ink); }
.jzb .pcta p { color: var(--muted); }

/* ---------- carousel dots inside a portfolio piece ---------- */
/* Inactive dots were nearly invisible against the dark ground, so there was
   no way to tell how many slides a carousel had. */
.jzw .swiper-pagination-bullet,
.jzw .elementor-pagination .swiper-pagination-bullet {
  background: rgba(246, 243, 239, 0.28) !important;
  border: 1px solid rgba(246, 243, 239, 0.5);
  opacity: 1 !important;
  width: 9px;
  height: 9px;
  margin: 0 5px !important;
  transition: background 0.3s, transform 0.3s var(--ease-out);
}
.jzw .swiper-pagination-bullet:hover { background: rgba(246, 243, 239, 0.6) !important; }
.jzw .swiper-pagination-bullet-active,
.jzw .elementor-pagination .swiper-pagination-bullet-active {
  background: var(--crimson) !important;
  box-shadow: 0 0 12px rgba(255, 36, 56, 0.8);
}

/* ---------- ad units ---------- */
.jzad { margin: 2.2rem 0; text-align: center; }
/* An unfilled unit used to leave an orphan "Sponsored" label floating in the
   page. The label is hidden by default and only appears once AdSense reports
   the unit as filled, so an empty slot shows nothing at all. */
.jzad .jzad__label { display: none; }
.jzad:has(ins[data-ad-status="filled"]) .jzad__label { display: block; }
.jzad:has(ins[data-ad-status="unfilled"]) { display: none; }
ins.adsbygoogle[data-ad-status="unfilled"] { display: none !important; }
.jzad.is-empty { display: none !important; }
/* affiliate banners always render, so their label always shows */
.side-card--aff .jzad__label { display: block !important; }
.jzad ins { display: block; }
.jzad__label {
  margin-top: 0.35rem;
  font-size: 0.55rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pink-soft, #8a857e);
  opacity: 0.65;
}
.jzad--desktop { display: block; }
.jzad--mobile { display: none; }
@media (max-width: 767px) {
  .jzad--desktop { display: none; }
  .jzad--mobile { display: block; }
}

/* ---------- affiliate cards ---------- */
/* Affiliate creatives are banners: no card chrome, just the image with a
   very small label beneath it. */
.side-card--aff { padding: 0; border: 0; background: none; }
.side-card--aff a { display: block; border-radius: 14px; overflow: hidden; }
.side-card--aff img { display: block; width: 100%; height: auto; }
/* `.side-card > p` is a class plus an element, which out-specified the label
   class and sized it at body copy. Matched on the element here so it wins. */
.side-card p.jzad__label,
.jzad p.jzad__label {
  font-size: 0.55rem;
  line-height: 1;
  letter-spacing: 0.16em;
  margin: 0.35rem 0 0;
  text-align: center;
  opacity: 0.55;
}

/* ---------- dark reading mode: neutralise light blocks from the article ----------
   Some articles carry inline light backgrounds (call-out boxes such as
   "Related from JZ Creates"), which stayed white in night mode. */
/* A block with its own gradient keeps its original dark text: inverting it
   put white type on a pale gradient, which was unreadable. */
html[data-read="dark"] .jzb .post__body [style*="gradient"],
html[data-read="dark"] .jzb .post__body [style*="gradient"] * {
  color: #16161a !important;
  -webkit-text-fill-color: #16161a !important;
}
html[data-read="dark"] .jzb .post__body [style*="background"]:not([style*="gradient"]),
html[data-read="dark"] .jzb .post__body .wp-block-group,
html[data-read="dark"] .jzb .post__body table,
html[data-read="dark"] .jzb .post__body th,
html[data-read="dark"] .jzb .post__body td {
  background-color: rgba(246, 243, 239, 0.05) !important;
  color: var(--pink) !important;
}
html[data-read="dark"] .jzb .post__body [style*="color"]:not([style*="gradient"]) { color: var(--pink) !important; }
html[data-read="dark"] .jzb .post__body a[style*="color"],
html[data-read="dark"] .jzb .post__body a { color: var(--pink) !important; }
html[data-read="dark"] .jzb .post__body h2,
html[data-read="dark"] .jzb .post__body h3,
html[data-read="dark"] .jzb .post__body h4 { color: var(--crimson) !important; }

/* ---------- accordions (FAQ) follow the reading mode ---------- */
html[data-read="dark"] .jzb .post__body details,
html[data-read="dark"] .jzb .post__body summary,
/* Only the panel itself takes a background. Painting every descendant put a
   grey plate behind the question text inside each row. */
html[data-read="dark"] .jzb .post__body [class*="accordion"] {
  background-color: rgba(246, 243, 239, 0.04) !important;
  border-color: var(--rule) !important;
}
html[data-read="dark"] .jzb .post__body [class*="accordion"] * {
  background-color: transparent !important;
  color: var(--pink) !important;
  border-color: var(--rule) !important;
}
html[data-read="dark"] .jzb .post__body summary,
html[data-read="dark"] .jzb .post__body [class*="accordion"] [class*="title"],
html[data-read="dark"] .jzb .post__body [class*="accordion"] [class*="header"] {
  color: var(--crimson) !important;
}
.jzb .post__body details,
.jzb .post__body [class*="accordion"] { border-radius: 12px; }

/* ---------- sidebar spreads down the article ----------
   Everything used to stack at the top and leave the column empty for most of
   the read. A flex column with space-between distributes the cards down the
   full height, which also parks the last newsletter form at the very bottom. */
.post__layout { align-items: stretch; }
.post__side {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2.4rem;
  height: 100%;
}
@media (max-width: 1024px) {
  .post__side { display: grid; gap: 1.2rem; height: auto; }
}

/* ---------- rounded corners on every image and video in a piece ---------- */
.jzw .wbody img,
.jzw .wbody video,
.jzw .wbody iframe,
.jzw .wbody .elementor-widget-image img,
.jzw .wbody .elementor-widget-video,
.jzw .wbody .elementor-wrapper,
.jzw .wbody .elementor-fit-aspect-ratio {
  border-radius: 16px;
  overflow: hidden;
}
/* the play overlay has to follow the same corner or it squares off the frame */
.jzw .wbody .elementor-custom-embed-image-overlay { border-radius: 16px; overflow: hidden; }

/* ---------- drop the outer stroke around a group of cards ----------
   A bordered container wrapped around bordered cards read as a double frame. */
.jzw .wbody .elementor-column:has(.elementor-column h3),
.jzw .wbody .e-con:has(> .e-con.e-child h3) {
  border: 0 !important;
  background: none !important;
}

/* ---------- trial: gradient accent on the closing word of a section header ----------
   Live on Nocteur only. The wrapper carries the gradient and nothing else
   transforms it, which is the only way background-clip:text survives.
   Needs the padding or the italic overhang and descenders clip. */
.jzw .wbody h2 .grad.jzc-lastword {
  font-style: italic;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent !important;
  color: transparent !important;
  padding-right: 0.08em;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  display: inline-block;
}

/* ============================================================
   STRUCTURE — applies to every portfolio piece
   ============================================================ */

/* ---------- headings are Title Case ----------
   `capitalize` only raises the first letter of each word and leaves existing
   capitals alone, so acronyms like AI and CGI survive intact. */
.jzw .wbody h2,
.jzw .wbody h3,
.jzw .wbody h2.elementor-heading-title,
.jzw .wbody h3.elementor-heading-title { text-transform: capitalize !important; }

/* ---------- no strokes anywhere except the cards below ----------
   Borders are cleared from every Elementor container, then put back only on
   the cards this stylesheet creates. Background images are deliberately NOT
   touched: clearing them is what wiped the full-width section artwork. */
.jzw .wbody .elementor-section,
.jzw .wbody .elementor-container,
.jzw .wbody .elementor-widget-wrap,
.jzw .wbody .elementor-column,
.jzw .wbody .e-con,
.jzw .wbody .e-con-inner,
.jzw .wbody .elementor-widget-container {
  border: none !important;
  box-shadow: none !important;
}

/* ---------- one measure, matching the nav exactly ----------
   `.nav__inner` is max-width 1600 with 5% side padding, so a piece lines up
   with the logo and the Book a Call button. Only the OUTERMOST container is
   padded; nested ones are reset, because padding both was what squeezed the
   content inwards. */
.jzw .wbody > .elementor > .elementor-section > .elementor-container,
.jzw .wbody > .elementor > .e-con > .e-con-inner,
.jzw .wbody > .elementor > .elementor-section.elementor-section-boxed > .elementor-container {
  max-width: var(--maxw) !important;
  margin-inline: auto !important;
  padding-inline: var(--pad) !important;
  width: 100% !important;
}
.jzw .wbody .elementor-column .elementor-container,
.jzw .wbody .e-con.e-child > .e-con-inner,
.jzw .wbody .elementor-widget-wrap > .elementor-container {
  max-width: none !important;
  padding-inline: 0 !important;
}

/* ---------- a heading beside media reads left, not centred ---------- */
.jzw .wbody .elementor-container:has(> .elementor-column :is(img, iframe, video)) > .elementor-column:has(h2),
.jzw .wbody .elementor-container:has(> .elementor-column :is(img, iframe, video)) > .elementor-column:has(h2) h2,
.jzw .wbody .e-con-inner:has(> .e-con :is(img, iframe, video)) > .e-con:has(h2),
.jzw .wbody .e-con-inner:has(> .e-con :is(img, iframe, video)) > .e-con:has(h2) h2,
.jzw .wbody .e-con:has(> .e-con :is(img, iframe, video)) > .e-con:has(h2) h2 {
  text-align: left !important;
}

/* ---------- Elementor icon lists ----------
   These are FLEX rows carrying their own tick. Forcing `display: list-item`
   on them stacked the tick above the text; forcing a disc gave every row two
   markers. Both are undone here. */
.jzw .wbody .elementor-icon-list-items,
.jzw .wbody ul.elementor-icon-list-items {
  list-style: none !important;
  padding-left: 0 !important;
}
.jzw .wbody .elementor-icon-list-item,
.jzw .wbody li.elementor-icon-list-item {
  display: flex !important;
  align-items: flex-start;
  gap: 0.6rem;
  list-style: none !important;
}
.jzw .wbody .elementor-icon-list-item::marker { content: none !important; }
.jzw .wbody .elementor-icon-list-icon { flex: none; line-height: 1.6; }

/* ---------- rounded corners, wherever the media actually lives ---------- */
.jzw .wbody .elementor-widget-image,
.jzw .wbody .elementor-widget-image a,
.jzw .wbody .elementor-image,
.jzw .wbody figure,
.jzw .wbody .elementor-widget-video .elementor-widget-container,
.jzw .wbody .elementor-carousel-image,
.jzw .wbody .swiper-slide img {
  border-radius: 16px;
  overflow: hidden;
}

/* ============================================================
   CARDS — the only things in a piece that carry a border
   ============================================================ */
.jzw .wbody .elementor-column:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .e-con.e-child:has(h3):has(.elementor-widget-text-editor) {
  padding: 2.2rem 2rem 2.8rem !important;
  border-radius: 16px;
  border: 1px solid var(--line) !important;
  background: rgba(255, 255, 255, 0.025);
}
/* ---------- a row of cards ----------
   One flex line, so four boxes stay four across instead of breaking into a
   row of three with a lone fourth stranded underneath. A child carrying the
   section heading takes the full width; the cards divide what is left, and a
   flex-basis of zero keeps them equal however much text each one holds. This
   replaces an auto-fit grid, which fought Elementor's own container display
   and lost, leaving the boxes on Elementor's stock 33% widths. */
.jzw .wbody .elementor-container:has(> .elementor-column h3),
.jzw .wbody .e-con-inner:has(> .e-con.e-child h3) {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: stretch !important;
  justify-content: center !important;
  gap: 1.2rem !important;
}
/* an intro block sharing the row with the cards */
.jzw .wbody .elementor-container:has(> .elementor-column h3) > .elementor-column:has(h2),
.jzw .wbody .e-con-inner:has(> .e-con.e-child h3) > .e-con.e-child:has(h2) {
  flex: 0 0 100% !important;
  width: 100% !important;
  max-width: 100% !important;
  margin: 0 !important;
}
/* the cards themselves */
.jzw .wbody .elementor-container:has(> .elementor-column h3) > .elementor-column:has(h3),
.jzw .wbody .e-con-inner:has(> .e-con.e-child h3) > .e-con.e-child:has(h3) {
  flex: 1 1 0 !important;
  width: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  margin: 0 !important;
}
/* four narrow columns stop being readable on a phone, so they pair up */
@media (max-width: 700px) {
  .jzw .wbody .elementor-container:has(> .elementor-column h3) > .elementor-column:has(h3),
  .jzw .wbody .e-con-inner:has(> .e-con.e-child h3) > .e-con.e-child:has(h3) {
    flex: 1 1 calc(50% - 0.6rem) !important;
  }
}
@media (max-width: 430px) {
  .jzw .wbody .elementor-container:has(> .elementor-column h3) > .elementor-column:has(h3),
  .jzw .wbody .e-con-inner:has(> .e-con.e-child h3) > .e-con.e-child:has(h3) {
    flex: 1 1 100% !important;
  }
}

/* ============================================================
   STAT COUNTERS
   The BOX is the column, not the widget: the widget was drawing a small
   inner panel inside a much larger column. Sizes are fixed because the
   number animates up from zero and its text width changes every frame.
   ============================================================ */
.jzw .wbody .elementor-column:has(.elementor-widget-counter),
.jzw .wbody .e-con:has(> .elementor-widget-counter) {
  border: 1px solid var(--line) !important;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.025);
  padding: 2.4rem 1.6rem !important;
  min-height: 190px;
  display: flex !important;
  align-items: center;
  justify-content: center;
}
.jzw .wbody .elementor-widget-counter {
  border: 0 !important;
  background: none !important;
  padding: 0 !important;
  min-height: 0;
  height: auto;
  width: 100%;
  text-align: center;
}
.jzw .wbody .elementor-counter-number-wrapper {
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  justify-content: center;
  width: 100%;
}
.jzw .wbody .elementor-container:has(> .elementor-column .elementor-widget-counter),
.jzw .wbody .e-con-inner:has(> .e-con > .elementor-widget-counter) {
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.4rem !important;
}
@media (max-width: 820px) {
  .jzw .wbody .elementor-container:has(> .elementor-column .elementor-widget-counter),
  .jzw .wbody .e-con-inner:has(> .e-con > .elementor-widget-counter) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- trial: gradient accent on the closing word of a section header ----------
   The wrapper carries the gradient and nothing else transforms it, which is
   the only way background-clip:text survives. Needs the padding or the
   italic overhang and descenders clip. */
.jzw .wbody h2 .grad.jzc-lastword {
  font-style: italic;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent !important;
  color: transparent !important;
  padding-right: 0.08em;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  display: inline-block;
}

/* ---------- strokes: nothing but the cards ----------
   Elementor writes its border onto whichever element the editor was pointed
   at, which varies by widget and section age, so the border is cleared from
   every element inside a piece and then put back on the cards below. */
.jzw .wbody [class*="elementor-element"],
.jzw .wbody [class*="elementor-section"],
.jzw .wbody [class*="e-con"],
.jzw .wbody [class*="elementor-column"],
.jzw .wbody [class*="elementor-widget"] {
  border: none !important;
  box-shadow: none !important;
}
.jzw .wbody .elementor-column:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .e-con.e-child:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .elementor-column:has(.elementor-widget-counter),
.jzw .wbody .e-con:has(> .elementor-widget-counter) {
  border: 1px solid var(--line) !important;
}

/* ---------- a heading BESIDE MEDIA reads left ----------
   Left alignment is for a genuine two-column layout: text on one side, an
   image or a video on the other. Anything wider than that is a heading
   sitting above a row of cards, and those headings stay centred, which is
   what the earlier "more than one column" test got wrong. */
.jzw .wbody .elementor-container:has(> .elementor-column:nth-of-type(2)):not(:has(> .elementor-column:nth-of-type(3))):has(> .elementor-column :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .elementor-column:not(:has(img, iframe, video)),
.jzw .wbody .e-con-inner:has(> .e-con:nth-of-type(2)):not(:has(> .e-con:nth-of-type(3))):has(> .e-con :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .e-con:not(:has(img, iframe, video)),
.jzw .wbody .e-con:has(> .e-con:nth-of-type(2)):not(:has(> .e-con:nth-of-type(3))):has(> .e-con :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .e-con:not(:has(img, iframe, video)),
.jzw .wbody .elementor-container:has(> .elementor-column:nth-of-type(2)):not(:has(> .elementor-column:nth-of-type(3))):has(> .elementor-column :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .elementor-column:not(:has(img, iframe, video)) :is(h2, h3, h4, h5, p, ul, ol),
.jzw .wbody .e-con-inner:has(> .e-con:nth-of-type(2)):not(:has(> .e-con:nth-of-type(3))):has(> .e-con :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .e-con:not(:has(img, iframe, video)) :is(h2, h3, h4, h5, p, ul, ol),
.jzw .wbody .e-con:has(> .e-con:nth-of-type(2)):not(:has(> .e-con:nth-of-type(3))):has(> .e-con :is(img, iframe, video, .elementor-widget-image, .elementor-widget-video, .elementor-widget-media-carousel)) > .e-con:not(:has(img, iframe, video)) :is(h2, h3, h4, h5, p, ul, ol) {
  text-align: left !important;
}

/* A row of cards is always left-aligned inside each card, regardless. */
.jzw .wbody .elementor-column:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .elementor-column:has(h3):has(.elementor-widget-text-editor) :is(h3, p, ul, ol, li),
.jzw .wbody .e-con.e-child:has(h3):has(.elementor-widget-text-editor),
.jzw .wbody .e-con.e-child:has(h3):has(.elementor-widget-text-editor) :is(h3, p, ul, ol, li) {
  text-align: left !important;
}

/* ---------- stat figures: bigger, and in the brand gold ---------- */
.jzw .wbody .elementor-counter-number,
.jzw .wbody .elementor-counter-number-prefix,
.jzw .wbody .elementor-counter-number-suffix {
  font-family: var(--font-display) !important;
  font-size: clamp(3rem, 4.4vw, 4.4rem) !important;
  line-height: 1 !important;
  color: var(--gold) !important;
  -webkit-text-fill-color: var(--gold) !important;
}
.jzw .wbody .elementor-counter-title {
  font-family: var(--font-body) !important;
  font-size: 0.82rem !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  margin-top: 0.6rem;
}
