/* Ported from Code Snippets: "JD: Components" (id 35), pulled fresh from production 2026-08-24. */

/* ======================================================================
   JD: Components - the shared library.  Requires "JD: Design tokens".

   SCOPING: everything is scoped to .jd-scope, and the page ground to
   body.jd-converted, so this snippet is INERT until a template opts in.
   Convert one template at a time without risking the other nine.

   Do NOT add the ground without the card layer: the warm ground only
   reads correctly when main-column sections are white cards. Applying
   body.jd-converted before .jd-section leaves content floating on grey.

   TYPOGRAPHY CAVEAT: the current templates set font-family/size/weight
   in the Elementor WIDGET settings, which Elementor emits as per-element
   CSS that outranks these class rules. Section-heading type will not
   change until those per-widget settings are cleared. Colour and spacing
   land fine; type does not.
   ====================================================================== */

body.jd-converted{ background:var(--jd-ground); }
.jd-scope{ font-family:var(--jd-font); color:var(--jd-text); line-height:var(--jd-lh); }

/* 1 - Layout */
.jd-scope .jd-layout{ display:grid; grid-template-columns:1fr var(--jd-rail); gap:var(--jd-gap); align-items:start; }
.jd-scope .jd-main{ display:flex; flex-direction:column; gap:var(--jd-gap); min-width:0; }
.jd-scope .jd-rail{ display:flex; flex-direction:column; gap:20px; }

/* 2 - Section card: THE missing layer. The mockup's defining move is
   "every section is a white card on a warm ground"; only the sidebar
   ever got it.
   Compound form (.jd-scope.jd-section) added in Phase 3 (Book template):
   a new top-level container can carry both classes on the SAME element
   when there is no separate .jd-scope ancestor to nest under - mirrors
   the #15 .jd-surface-card pattern below. Purely additive; does not
   change any selector that already matched. */
.jd-scope.jd-section,
.jd-scope .jd-section{ background:var(--jd-surface); border:1px solid var(--jd-rule); border-radius:var(--jd-r-lg); padding:var(--jd-pad); }

/* 3 - Section header */
.jd-scope .jd-section-head{ display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:15px; }
.jd-scope .jd-section-head h2,
.jd-scope .jd-section-label{ font-size:var(--jd-fs-label); text-transform:uppercase; letter-spacing:var(--jd-ls-label); color:var(--jd-navy-dark); font-weight:700; margin:0; }
.jd-scope .jd-view-all{ font-size:var(--jd-fs-meta); font-weight:600; color:var(--jd-navy); text-decoration:none; white-space:nowrap; }
.jd-scope .jd-view-all:hover{ text-decoration:underline; }

/* 4 - Record header band */
.jd-scope .jd-record-head{ background:var(--jd-surface); border:1px solid var(--jd-rule); border-radius:var(--jd-r-lg); padding:var(--jd-pad-lg); display:flex; gap:26px; align-items:flex-start; }
.jd-scope .jd-record-logo{ width:92px; height:92px; flex-shrink:0; border:1px solid var(--jd-rule); border-radius:var(--jd-r-md); background:linear-gradient(135deg,var(--jd-accent-soft),var(--jd-surface)); display:flex; align-items:center; justify-content:center; overflow:hidden; font-weight:700; color:var(--jd-accent); font-size:24px; letter-spacing:.5px; }
.jd-scope .jd-record-logo img{ width:100%; height:100%; object-fit:contain; display:block; }
.jd-scope .jd-record-body{ flex:1; min-width:0; }
.jd-scope .jd-record-parent{ font-size:var(--jd-fs-meta); color:var(--jd-text-muted); margin-bottom:5px; }
.jd-scope .jd-record-titlerow{ display:flex; align-items:center; gap:11px; flex-wrap:wrap; margin-bottom:9px; }
.jd-scope .jd-record-title,
.jd-scope .jd-record-title .elementor-heading-title{ font-family:var(--jd-font); font-size:var(--jd-fs-h1); font-weight:700; margin:0; color:var(--jd-navy-dark); letter-spacing:-.2px; }
.jd-scope .jd-record-summary{ font-size:var(--jd-fs-body); max-width:72ch; margin:0; }
.jd-scope .jd-abbr{ font-size:var(--jd-fs-micro); font-weight:700; letter-spacing:.6px; color:var(--jd-navy); background:var(--jd-tint); border:1px solid var(--jd-rule); padding:3px 9px; border-radius:var(--jd-r-pill); }

/* 5 - Status badge */
.jd-scope .jd-badge{ display:inline-block; font-size:var(--jd-fs-micro); font-weight:600; padding:4px 12px; border-radius:var(--jd-r-pill); margin-bottom:14px; }
.jd-scope .jd-badge.is-full{ background:var(--jd-navy); color:var(--jd-text-invert); }
.jd-scope .jd-badge.is-member{ background:var(--jd-success-soft); color:var(--jd-success); }
.jd-scope .jd-badge.is-developing{ background:var(--jd-caution-soft); color:var(--jd-caution); }

/* 6 - Buttons */
.jd-scope .jd-actions{ display:flex; gap:9px; margin-top:17px; flex-wrap:wrap; }
.jd-scope .jd-btn{ font-size:var(--jd-fs-meta); font-weight:600; padding:8px 14px; border-radius:var(--jd-r-sm); border:1px solid var(--jd-rule); background:var(--jd-surface); color:var(--jd-navy-dark); text-decoration:none; display:inline-flex; align-items:center; gap:6px; }
.jd-scope .jd-btn:hover{ border-color:var(--jd-navy); }
.jd-scope .jd-btn.is-primary{ background:var(--jd-navy); border-color:var(--jd-navy); color:var(--jd-text-invert); }
.jd-scope .jd-btn.is-accent{ background:var(--jd-accent); border-color:var(--jd-accent); color:var(--jd-text-invert); }
.jd-scope .jd-btn.is-accent:hover{ background:#c66f24; border-color:#c66f24; }

/* 7 - Ruled metadata block. For facts present on nearly every record.
   53% of organisation pages have no related content at all, so this is
   what stops those pages reading as broken. */
.jd-scope .jd-meta{ display:grid; grid-template-columns:auto 1fr; gap:0 22px; margin:16px 0 0; max-width:62ch; }
.jd-scope .jd-meta dt{ padding:7px 0; border-top:1px solid var(--jd-rule-soft); font-size:var(--jd-fs-micro); text-transform:uppercase; letter-spacing:var(--jd-ls-label); color:var(--jd-text-muted); font-weight:600; }
.jd-scope .jd-meta dd{ padding:7px 0; border-top:1px solid var(--jd-rule-soft); margin:0; font-size:var(--jd-fs-meta); }

/* 8 - Person */
.jd-scope .jd-person-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
.jd-scope .jd-person{ text-align:center; }
.jd-scope .jd-person-avatar{ width:54px; height:54px; border-radius:50%; overflow:hidden; margin:0 auto 8px; display:flex; align-items:center; justify-content:center; }
.jd-scope .jd-person-avatar--initials{ background:var(--jd-navy); }
.jd-scope .jd-person-avatar--initials span{ color:var(--jd-text-invert); font-weight:700; font-size:15px; }
.jd-scope .jd-person-avatar img{ width:100%; height:100%; object-fit:cover; display:block; filter:grayscale(100%); transition:filter .25s ease; }
.jd-scope .jd-person-avatar--photo:hover img{ filter:grayscale(0); }
.jd-scope .jd-person-name{ display:block; font-size:var(--jd-fs-meta); font-weight:600; color:var(--jd-text); text-decoration:none; line-height:1.3; }
.jd-scope .jd-person-name:hover{ text-decoration:underline; }
.jd-scope .jd-person-role{ display:block; font-size:var(--jd-fs-micro); color:var(--jd-text-muted); }

/* 9 - Event row */
.jd-scope .jd-event{ display:flex; gap:14px; align-items:center; border:1px solid var(--jd-rule); border-radius:var(--jd-r-md); padding:13px; }
.jd-scope .jd-event + .jd-event{ margin-top:var(--jd-gap-sm); }
.jd-scope .jd-event-chip{ background:var(--jd-accent-soft); color:var(--jd-accent); border-radius:var(--jd-r-sm); padding:8px 10px; text-align:center; min-width:58px; flex-shrink:0; font-weight:700; font-size:var(--jd-fs-meta); line-height:1.2; text-transform:uppercase; }
.jd-scope .jd-event-chip .jd-event-day{ display:block; font-size:19px; }
.jd-scope .jd-event-title{ font-size:var(--jd-fs-h3); font-weight:700; color:var(--jd-text); text-decoration:none; }
.jd-scope .jd-event-title:hover{ text-decoration:underline; }
.jd-scope .jd-event-meta{ display:block; font-size:var(--jd-fs-meta); color:var(--jd-text-muted); margin-top:3px; }

/* 10 - Course entry */
.jd-scope .jd-course{ border:1px solid var(--jd-rule); border-radius:var(--jd-r-md); padding:14px; }
.jd-scope .jd-course + .jd-course{ margin-top:var(--jd-gap-sm); }
.jd-scope .jd-course-title{ display:block; font-size:var(--jd-fs-h3); font-weight:700; color:var(--jd-text); text-decoration:none; }
.jd-scope .jd-course-title:hover{ text-decoration:underline; }
.jd-scope .jd-course-meta{ display:block; font-size:var(--jd-fs-meta); color:var(--jd-text-muted); margin-top:4px; }
.jd-scope .jd-pill{ display:inline-block; margin-top:8px; padding:3px 10px; border-radius:var(--jd-r-pill); background:var(--jd-success-soft); color:var(--jd-success); font-size:var(--jd-fs-micro); font-weight:700; text-transform:uppercase; letter-spacing:.04em; }

/* 11 - Article / news row */
.jd-scope .jd-article{ display:flex; gap:16px; padding:12px 0; border-bottom:1px solid var(--jd-rule); }
.jd-scope .jd-article:last-child{ border-bottom:none; }
.jd-scope .jd-article-date{ flex-shrink:0; width:80px; font-size:var(--jd-fs-meta); color:var(--jd-text-muted); }
.jd-scope .jd-article-title{ font-size:var(--jd-fs-body); font-weight:600; color:var(--jd-text); text-decoration:none; }
.jd-scope .jd-article-title:hover{ text-decoration:underline; }

/* 12 - Rail cards */
.jd-scope .jd-card{ background:var(--jd-surface); border:1px solid var(--jd-rule); border-radius:var(--jd-r-lg); padding:24px; width:100%; }
.jd-scope .jd-card-heading{ font-size:var(--jd-fs-meta); font-weight:700; letter-spacing:var(--jd-ls-label); text-transform:uppercase; color:var(--jd-navy-dark); margin:0 0 16px; }
.jd-scope .jd-social a{ display:inline-flex; align-items:center; justify-content:center; width:31px; height:31px; border-radius:50%; background:var(--jd-tint); color:var(--jd-navy-dark); font-size:12px; font-weight:600; text-decoration:none; margin-right:8px; }
.jd-scope .jd-social a:hover{ background:var(--jd-accent-soft); color:var(--jd-accent); }

/* 13 - Authority block */
.jd-scope .jd-authority{ display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:var(--jd-fs-meta); font-weight:600; color:var(--jd-text-muted); text-decoration:none; }
.jd-scope .jd-authority a,
.jd-scope .jd-authority .jd-authority-link{ color:var(--jd-accent); font-weight:600; }

@media(max-width:900px){
  .jd-scope .jd-layout{ grid-template-columns:1fr; }
  .jd-scope .jd-person-grid{ grid-template-columns:repeat(2,1fr); }
  .jd-scope .jd-record-head{ flex-direction:column; }
}

/* 15 - Chrome-only surface. Same card treatment as .jd-section but with NO
   layout properties, for containers whose flex-direction is breakpoint
   dependent (the record header band sets row on desktop, column on mobile
   via its own Elementor style class). Adding .jd-section there would pin it
   to one direction at every breakpoint and break the mobile stack. */
.jd-scope.jd-surface-card,
.jd-scope .jd-surface-card{ background:var(--jd-surface); border:1px solid var(--jd-rule); border-radius:var(--jd-r-lg); padding:var(--jd-pad-lg); }

/* 16 - Section headings. Elementor puts the text in an inner
   .elementor-heading-title, so a rule on the widget wrapper alone would be
   inherited-away by any colour set on that inner element. Target both. */
.jd-scope .jd-section-label,
.jd-scope .jd-section-label .elementor-heading-title{
	font-family:var(--jd-font); font-size:var(--jd-fs-label); font-weight:700;
	text-transform:uppercase; letter-spacing:var(--jd-ls-label);
	color:var(--jd-navy-dark); margin:0;
}

/* 17 - "View all N ..." links. The class is emitted by
   jd_org_subview_link_shortcode(), hence the jd-org- prefix. Element
   selector included so it ties with .elementor-kit-NNN a - see phase-0 notes. */
.jd-scope a.jd-org-view-all{ font-size:var(--jd-fs-meta); font-weight:600; color:var(--jd-navy); text-decoration:none; white-space:nowrap; }
.jd-scope a.jd-org-view-all:hover{ text-decoration:underline; }

/* 18 - Gap-only stacks. Same spacing as .jd-main / .jd-rail but with NO
   display or flex-direction, for containers that already set those per
   breakpoint (RelatedOrg's main column carries a breakpoint-specific
   display prop). gap works because the container is already a flexbox.
   Same principle as .jd-surface-card versus .jd-section. */
.jd-scope .jd-stack{ gap:var(--jd-gap); }
.jd-scope .jd-stack-tight{ gap:20px; }

/* ======================================================================
   19 - Book template additions (Phase 3, Single Post Book / 31231).
   ====================================================================== */

/* Cover + purchase-button column. Fixed width rather than a percentage so
   a portrait book cover doesn't scale up on wide screens the way the old
   30% column did. */
.jd-scope .jd-record-media{ display:flex; flex-direction:column; gap:14px; }
.jd-scope .jd-record-cover-img img,
.jd-scope .jd-record-cover-img{ border:1px solid var(--jd-rule); border-radius:var(--jd-r-sm); box-shadow:0 6px 16px rgba(18,37,60,0.12); }

/* Author byline under the title. Muted rather than the kit's default link
   colour so it reads as caption text, not as a click target - it isn't
   one today (book_author is plain text, no relationship field yet). */
.jd-scope .jd-record-byline{ font-size:var(--jd-fs-body); color:var(--jd-text-muted); margin:4px 0 0; display:block; }

/* Citation box. A tinted, bordered block so the APA citation reads as a
   distinct, copyable unit rather than another paragraph of body text. */
.jd-scope .jd-cite-block{ background:var(--jd-rule-soft); border:1px solid var(--jd-rule); border-radius:var(--jd-r-sm); padding:14px 16px; margin-top:18px; }
.jd-scope .jd-cite-block p{ margin:0; }

/* Book description prose. */
.jd-scope .jd-body-text p{ font-size:var(--jd-fs-body); line-height:var(--jd-lh); margin:0 0 16px; }
.jd-scope .jd-body-text p:last-child{ margin-bottom:0; }

/* ======================================================================
   20 - Page-width fix, classic (non-atomic) top-level containers.

   The organisation templates are built from Elementor v4 atomic
   e-flexbox elements, which take an explicit `width` STYLE (e.g. 1100px)
   plus `margin-inline:auto` directly on the element - a real box-model
   width, so the visible card IS 1140/1100px wide.

   The book template's top-level containers are classic (v3, is_atomic:
   false) Elementor containers. Classic containers implement "boxed
   width" completely differently: `content_width:boxed` + `boxed_width`
   only constrains an INNER `.e-con-inner` wrapper via `max-width:
   var(--content-width)` - the OUTER .e-con element (the one carrying our
   background/border/padding via .jd-surface-card / .jd-section) stays
   full-bleed regardless. Setting boxed_width therefore does nothing
   visible when the card chrome lives on the outer element, which is why
   this template rendered edge-to-edge instead of boxed to 1140px like
   the organisation pages.

   Fix: bypass Elementor's boxed/full mechanism entirely for these
   elements and size the outer .e-con directly, same as the manual
   Header-width fix documented for the organisation templates. If a
   template's top-level element ids ever change (deleted and rebuilt in
   the editor), the matching selectors below need updating.

   CORRECTION (Phase 2, Analyst template, 5 August 2026): this block
   originally claimed the analyst template (216, template_type
   "single-post") didn't need this fix, on the theory that a single-post
   template renders inside the theme's own boxed content wrapper. That
   was wrong - screenshotted proof from Stephen showed the header band's
   white background bleeding edge to edge, with only the boxed_width
   setting's inner-wrapper effect (see above) keeping the TEXT centred
   inside it. The theme's single-post wrapper is not boxed on this site;
   nothing was actually constraining the outer .e-con. Root-caused by
   re-reading this exact comment block, which already explained the
   mechanism correctly for Book - it just wasn't applied to Analyst too.
   Lesson: don't assume a template class ("single-post") implies a theme
   behaviour ("boxed wrapper") without checking the rendered page itself.
   ====================================================================== */
.elementor-element-2f8c6e8.e-con,
.elementor-element-c7e9f5b.e-con,
.elementor-element-2b3c4d5.e-con,
.elementor-element-a4b5c6d.e-con,
.elementor-element-b77ef8d.e-con{
	max-width:1140px;
	width:100%;
	margin-left:auto;
	margin-right:auto;
}

/* The analyst header (b0bad39) is a direct child of the document, same as
   the organisation header bands in Phase 1 - its own visible edges get no
   inset at all. The About/Contact cards below it are nested TWO levels
   deep (b77ef8d -> 7c46314 or jd-analyst-rail -> card), and Elementor adds
   its own ~10px default inline padding at each nesting level, so their
   visible edges sit 20px in from the 1140px row on each side (measured:
   402.5-1502.5 against the row's 382.5-1522.5). A header boxed to the same
   1140 therefore overhangs the cards below by 20px per side - exactly the
   'Header width' finding from Phase 1, applied here: a card placed as a
   direct child of the document must be row-width minus 40px to line up
   with cards nested inside the row. */
.elementor-element-b0bad39.e-con{
	max-width:1100px;
	width:100%;
	margin-left:auto;
	margin-right:auto;
}

/* Course template (Phase 4, Courses single post / 7863). Same shape as
   the analyst header: jd-course-head is a direct child of the document,
   while the About/Contact-equivalent cards below it (jd-course-overview,
   jd-course-enrol-card, etc.) are nested two levels deep
   (jd-course-body -> jd-course-main/jd-course-rail -> card), picking up
   the same 20px-per-side Elementor default padding. Row-width minus 40. */
body.single-courses .jd-record-head.e-con{
	max-width:1100px;
	width:100%;
	margin-left:auto;
	margin-right:auto;
}
body.single-courses .jd-record-body.e-con{
	max-width:1140px;
	width:100%;
	margin-left:auto;
	margin-right:auto;
}

/* ======================================================================
   21 - Book template "about the author" text-only state (Phase 3
   revision - bottom-of-page actions block). Same rationale as
   .jd-record-byline: muted caption styling, not a link, because
   book_author has no relationship field to the analyst CPT yet.
   ====================================================================== */
.jd-scope .jd-author-textonly{ font-size:var(--jd-fs-meta); color:var(--jd-text-muted); line-height:var(--jd-lh); margin:0; }
.jd-scope .jd-author-textonly strong{ color:var(--jd-text); font-weight:600; }

/* ======================================================================
   22 - Analyst template additions (Phase 2, Analyst single post / 216).
   ====================================================================== */

/* Hero avatar in the record header. Named jd-record-avatar (not
   .jd-analyst-avatar, which is sized for the 64px organisation Members
   Loop Grid tile, and not .jd-record-media, which the Book template
   already uses for an unrelated cover+button flex column) to avoid
   colliding with either existing component. */
.jd-record-avatar{
	width:128px; height:128px; flex:0 0 128px; border-radius:50%; overflow:hidden;
	display:flex; align-items:center; justify-content:center; background:var(--jd-navy);
}
.jd-record-avatar--photo{ background:linear-gradient(160deg,#3a4f66,var(--jd-navy)); }
.jd-record-avatar-img{ width:100%; height:100%; object-fit:cover; display:block; }
.jd-record-avatar--initials span{
	color:var(--jd-text-invert); font-family:var(--jd-font); font-weight:700;
	font-size:36px; letter-spacing:.02em;
}

/* Header subtitle - the affiliation link. a{} selector included per the
   Phase 0 specificity rule: a bare .jd-record-subtitle class on an <a>
   loses to .elementor-kit-NNN a (0,1,1) without it. */
.jd-scope a.jd-record-subtitle,
a.jd-record-subtitle{
	display:inline-block; font-style:italic; color:var(--jd-navy);
	text-decoration:none; font-size:var(--jd-fs-body); margin-top:2px;
}
.jd-scope a.jd-record-subtitle:hover,
a.jd-record-subtitle:hover{ text-decoration:underline; }

/* Availability status pill. current_availability is filled on 100% of
   published analysts. Moved out of the header and into the rail, directly above the Contact
   card, per Stephen's request - see
   "JD: Analyst header & sidebar metadata". Same success/caution/muted
   triad as the Course pill and the organisation status badge, not a
   fourth palette. */
.jd-availability-pill{
	display:inline-flex; align-items:center; gap:6px; padding:5px 14px;
	border-radius:var(--jd-r-pill); font-family:var(--jd-font); font-size:var(--jd-fs-meta);
	font-weight:700; letter-spacing:.02em; white-space:nowrap;
}
.jd-availability-pill::before{ content:''; width:7px; height:7px; border-radius:50%; background:currentColor; }
.jd-availability-pill.is-open{ background:var(--jd-success-soft); color:var(--jd-success); }
.jd-availability-pill.is-waiting{ background:var(--jd-caution-soft); color:var(--jd-caution); }
.jd-availability-pill.is-closed{ background:var(--jd-rule-soft); color:var(--jd-text-muted); }

/* Small print under the Location card's placeholder map - reuses the
   caption tone already established for the author text-only state (#21)
   rather than inventing a third muted-caption rule. */
.jd-empty-note{ font-size:var(--jd-fs-meta); color:var(--jd-text-muted); font-style:italic; margin-top:8px; }

/* ======================================================================
   23 - Course template additions (Phase 4, Courses single post / 7863).
   ====================================================================== */

/* Cover. A distinct name from .jd-record-media on purpose - that class is
   already taken by the Book template's cover+purchase-button FLEX COLUMN
   (display:flex; flex-direction:column), a different shape entirely. This
   is a fixed-size landscape image box, closer to the organisation map's
   140px treatment than to Book's portrait cover. Hidden outright (not just
   collapsed to zero width) when the shortcode returns no <img> - 48% of
   courses have no featured image, and the header reflows to text-only
   rather than leaving an empty gutter, the same discipline already applied
   to the sparse organisation page. */
body.single-courses .elementor-element.jd-course-cover{ width:300px; flex:0 0 300px; align-self:stretch; min-height:200px; padding:0; border-radius:var(--jd-r-md); overflow:hidden; display:flex; }
body.single-courses .elementor-element.jd-course-cover .elementor-widget-container,
body.single-courses .elementor-element.jd-course-cover .elementor-shortcode{ height:100%; }
body.single-courses .elementor-element.jd-course-cover img{ width:100%; height:100%; object-fit:cover; display:block; }
body.single-courses .jd-course-cover:not(:has(img)){ display:none; }
@media (max-width:900px){ body.single-courses .elementor-element.jd-course-cover{ width:100%; flex:none; align-self:auto; height:220px; min-height:0; padding:0; } }

/* Status / format pills. A second pill family alongside the existing
   #10 .jd-pill (the single-purpose success-only chip already used on the
   organisation page's Course Loop Grid tiles) - that one has no modifier
   classes and changing it would ripple onto every org page course tile.
   Reuses the same success/caution/muted triad as the analyst availability
   pill and the organisation status badge, not a fourth palette. */
.jd-status-pill{ display:inline-flex; align-items:center; padding:4px 13px; border-radius:var(--jd-r-pill); font-size:var(--jd-fs-meta); font-weight:700; letter-spacing:.01em; }
.jd-status-pill.is-independent{ background:var(--jd-success-soft); color:var(--jd-success); }
.jd-status-pill.is-scheduled{ background:var(--jd-caution-soft); color:var(--jd-caution); }
.jd-status-pill.is-unconfirmed{ background:var(--jd-rule-soft); color:var(--jd-text-muted); }
.jd-status-pill.is-format{ background:var(--jd-tint); color:var(--jd-navy-dark); }

/* Speaker mini-avatar, inline inside a .jd-meta <dd>. Scaled down from the
   128px analyst hero avatar (.jd-record-avatar), which would overpower a
   meta row. Initials fallback used whenever speaker_image is empty OR is
   the site's generic stock-photo placeholder (attachment id 27979) - see
   the shortcode-level finding: that placeholder currently renders on 57%
   of course pages as if it were a real photo of the speaker. */
.jd-speaker-avatar{ width:24px; height:24px; border-radius:50%; overflow:hidden; display:inline-flex; align-items:center; justify-content:center; background:var(--jd-navy); margin-right:9px; vertical-align:middle; }
.jd-speaker-avatar img{ width:100%; height:100%; object-fit:cover; display:block; }
.jd-speaker-avatar--initials span{ color:var(--jd-text-invert); font-size:10px; font-weight:700; }

/* Enrolment card rows - a simpler, two-column fact list than .jd-meta,
   used only in the rail. */
.jd-enrol-row{ display:flex; justify-content:space-between; gap:12px; font-size:var(--jd-fs-body); color:var(--jd-text); padding:9px 0; border-bottom:1px solid var(--jd-rule-soft); }
.jd-enrol-row:last-child{ border-bottom:none; }
.jd-enrol-row dt{ color:var(--jd-text-muted); font-weight:600; margin:0; }
.jd-enrol-row dd{ margin:0; font-weight:700; text-align:right; }

/* Provider card - reuses the initials-circle-fallback contract already
   established for the related-organisation logo (.jd-relorg-logo-fallback)
   and the analyst avatar, applied here at rail-card scale. */
.jd-provider-row{ display:flex; align-items:center; gap:14px; }
.jd-provider-logo{ width:52px; height:52px; border-radius:50%; background:var(--jd-navy); display:flex; align-items:center; justify-content:center; flex:0 0 52px; overflow:hidden; }
.jd-provider-logo span{ color:var(--jd-text-invert); font-weight:700; font-size:16px; letter-spacing:.02em; }
.jd-provider-logo--img{ background:var(--jd-surface); border:1px solid var(--jd-rule); }
.jd-provider-logo--img img{ width:100%; height:100%; object-fit:contain; }
a.jd-provider-name,
.jd-scope a.jd-provider-name{ font-weight:700; font-size:var(--jd-fs-body); color:var(--jd-text); text-decoration:none; display:block; }
a.jd-provider-name:hover{ color:var(--jd-accent); text-decoration:underline; }
.jd-provider-type{ font-size:var(--jd-fs-meta); color:var(--jd-text-muted); margin-top:2px; }
a.jd-provider-link,
.jd-scope a.jd-provider-link{ display:block; margin-top:14px; font-size:var(--jd-fs-meta); font-weight:600; color:var(--jd-accent); text-decoration:none; }
a.jd-provider-link:hover{ text-decoration:underline; }

/* Full-width CTA button, styled directly rather than via the native
   Button widget's own colour controls - those bind to the kit's `accent`
   global (#1887A0 cyan, deliberately left unrepointed per the Phase 0
   kit-safety decision), which would render the wrong colour here. */
a.jd-cta-button,
.jd-scope a.jd-cta-button{ display:flex; align-items:center; justify-content:center; width:100%; margin-top:16px; padding:12px 18px; background:var(--jd-accent); color:var(--jd-text-invert); font-weight:700; font-size:var(--jd-fs-body); text-decoration:none; border-radius:var(--jd-r-md); box-sizing:border-box; }
a.jd-cta-button:hover{ background:#c76f24; }

/* Element-ID-scoped fallback for the Enrolment CTA button - guarantees
   styling regardless of where the native Button widget's _css_classes
   control attaches the class (wrapper div vs the <a> itself). */
body.single-courses .jd-cta-button .elementor-button{ display:flex; align-items:center; justify-content:center; width:100%; background:var(--jd-accent); border-color:var(--jd-accent); color:var(--jd-text-invert); font-weight:700; }
body.single-courses .jd-cta-button .elementor-button:hover{ background:#c76f24; border-color:#c76f24; }
/* Course Schedule card - the date rendered as a display line rather than a
   labelled .jd-meta row. There is only ever one date on this card, so the old
   "Ran" dt carried no information the "Schedule" heading had not already
   given; dropping it lets the date itself be the thing the eye lands on. The
   upcoming / in progress / concluded qualifier sits underneath in small caps
   so it reads as a footnote to the date, not as a competing fact. */
.jd-course-dates{ margin:0; font-size:17px; font-weight:700; line-height:1.3; color:var(--jd-navy-dark); }
.jd-course-dates-note{ margin:5px 0 0; font-size:var(--jd-fs-micro); text-transform:uppercase; letter-spacing:var(--jd-ls-label); font-weight:600; color:var(--jd-text-muted); }
	
	
	
	/* ======================================================================
   24 — Post template additions (Phase 5, single-post / 71302, 109531).
   ====================================================================== */

/* Header restructure (Stephen's revision, 21 Aug 2026): the cover image
   now spans the full header width, stacked BETWEEN the title and the
   subtitle — title, then image, then subtitle, then byline — rather than
   sitting beside a text column. jd-post-head's native flex_direction was
   flipped from row to column for this element only (same per-element
   override technique as the Course cover fix); align-items:stretch below
   makes every child (eyebrow pill, title, cover, subheading, byline) span
   the full row width, and gap does the vertical spacing so the old
   per-child top/bottom margins (which existed for a two-column layout)
   are zeroed out here rather than compounding with it. */
body.single-post .elementor-element-jd-post-head.jd-record-head{ align-items:stretch; gap:16px; }

/* Cover — full-width band. Featured-image aspect ratio on this CPT ranges
   from ~1:1 (custom graphics) to 3:1 (wide banners) to 16:9 (YouTube
   thumbnails on Video-category posts) — aspect-ratio + object-fit:cover
   handles all three from one box rather than the header reflowing height
   per post. Hidden outright, same discipline as the Course cover, on the
   ~15% of posts with no featured image — no gutter left behind. The
   .elementor-widget-container height rule and native padding:0 on the
   container settings are both required for the image to actually fill
   the box — see the Course template's three-round cover-sizing fix (§5,
   phase-4-course-template.md) for why: without them the box sizes
   correctly but the <img> inside stays at its intrinsic height. */
.jd-post-cover{ width:100%; padding:0; }
.jd-post-cover .elementor-widget-container,
.jd-post-cover .elementor-shortcode{ width:100%; }
.jd-post-cover img{ display:block; margin:0 auto; width:auto; height:auto; max-width:100%; max-height:320px; object-fit:contain; border-radius:var(--jd-r-md); }
.jd-post-cover:not(:has(img)){ display:none; }
@media (max-width:600px){ .jd-post-cover img{ max-height:220px; } }

/* Eyebrow — category pill(s) above the title. Reuses .jd-abbr rather than
   inventing a new pill — category is 100% filled, unlike the other post
   fields. Margin zeroed: the parent's flex gap (above) now supplies the
   space beneath it. */
.jd-post-eyebrow{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:0; }

/* Byline — text-only, same pattern as the Book template's author line
   (.jd-record-byline). No avatar, no bio card: author bio is 0% filled
   across all 3 accounts that have ever published a post (Newsfeed Web
   Sources, Buranee Haupt, stephengarratt), so a bio component would be
   permanently empty chrome. Top margin zeroed for the same reason as the
   eyebrow above. */
.jd-post-byline{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:0; font-size:var(--jd-fs-meta); color:var(--jd-text-muted); }
.jd-post-byline strong{ color:var(--jd-text); font-weight:600; }
.jd-post-byline .jd-dot{ opacity:.5; }

/* Tag row — bottom of the article body. 47% of posts carry tags; the
   shortcode returns '' when there are none, and the generic empty-
   shortcode-widget suppression rule (see "JD: Empty rail suppression")
   hides the row entirely rather than leaving an empty bordered strip. */
.jd-post-tags{ display:flex; gap:6px; flex-wrap:wrap; margin-top:18px; padding-top:18px; border-top:1px solid var(--jd-rule-soft); }
.jd-post-tags .jd-abbr{ color:var(--jd-navy); }

/* Adjacent-post navigation. Visually matches the MEC single-event
   template's already-approved Previous/Next pattern (Round 7, 6 Aug) —
   same bordered-tile family, redeclared here since that CSS lives scoped
   to single-mec-events.php, not in this shared component snippet.
   Unrestricted chronological adjacency (no shared-category requirement),
   same reasoning as that round: the native post-navigation widget's
   in_same_term restriction frequently leaves one side blank. */
.jd-post-adjacent{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.jd-post-adjacent-link{ display:block; border:1px solid var(--jd-rule); border-radius:var(--jd-r-md); padding:14px 16px; text-decoration:none; background:var(--jd-surface); }
.jd-post-adjacent-link:hover{ border-color:var(--jd-navy); }
.jd-post-adjacent-label{ display:block; font-size:var(--jd-fs-micro); font-weight:700; text-transform:uppercase; letter-spacing:var(--jd-ls-label); color:var(--jd-accent); margin-bottom:5px; }
.jd-post-adjacent-title{ display:block; font-size:var(--jd-fs-body); font-weight:600; color:var(--jd-text); line-height:1.35; }
.jd-post-adjacent-link--next{ grid-column:2; text-align:right; }
.jd-post-adjacent--single .jd-post-adjacent-link--next{ grid-column:1; text-align:left; }
@media (max-width:600px){ .jd-post-adjacent{ grid-template-columns:1fr; } .jd-post-adjacent-link--next{ grid-column:1; text-align:left; } }

/* Sidebar "View all news" link — sits under the Recent News list inside
   its card, right-aligned, its own top rule so it reads as a card footer
   rather than another list row. */
.jd-view-all-row{ display:block; text-align:right; margin-top:14px; padding-top:14px; border-top:1px solid var(--jd-rule-soft); }

/* Recent-News sidebar list — restyles Elementor's native Posts widget
   (classic skin) to the .jd-article look without rebuilding the query.
   The widget's own per-widget colour/typography settings (Phase 0
   caveat) are cleared in the template rebuild; these rules are what
   actually paint it. */
body.single-post .elementor-posts--skin-classic .elementor-post{ border-bottom:1px solid var(--jd-rule); padding:12px 0; margin:0; }
body.single-post .elementor-posts--skin-classic .elementor-post:first-child{ padding-top:0; }
body.single-post .elementor-posts--skin-classic .elementor-post:last-child{ border-bottom:none; padding-bottom:0; }
body.single-post .elementor-posts--skin-classic .elementor-post__title{ font-size:var(--jd-fs-body); font-weight:600; margin:0 0 4px; line-height:1.4; }
body.single-post .elementor-posts--skin-classic .elementor-post__title a{ color:var(--jd-text); text-decoration:none; }
body.single-post .elementor-posts--skin-classic .elementor-post__title a:hover{ text-decoration:underline; }
body.single-post .elementor-posts--skin-classic .elementor-post__meta-data{ font-size:var(--jd-fs-meta); color:var(--jd-text-muted); font-style:normal; }
