/* =====================================================================
   Shared article page — Company News + Mining Hub Insights (MHD-1674)

   Chrome stack (top → bottom):
     breadcrumb → banner ad → company header → tab nav →
     2-col article+sidebar grid → full-width "More from {Company}" section

   The article is rendered directly on the page canvas — NOT inside a
   bordered/rounded card. Separation from the sidebar comes from the grid
   gap (whitespace), which is deliberately wider than the tile gap.

   The sidebar stickies under the site nav at desktop widths. Its travel is
   bounded by its grid area inside `.cpn-grid`, so it releases naturally at
   the bottom of the grid and the full-width section below flows past it —
   no JS and no structural change needed for that section to work.

   At <= 899px the sidebar drops under the article and the tiles stack.
   ===================================================================== */

:root {
  --cpn-max-width: 1200px;
  --cpn-gap: 24px;
  /* Article ↔ sidebar separation. Wider than --cpn-gap on purpose: with no
     card border around the article, whitespace is the only thing dividing
     the reading column from the sidebar. */
  --cpn-grid-gap: 56px;
  --cpn-side-pad: 24px;
  --cpn-border: #e5e7eb;
  --cpn-border-soft: #eef0f3;
  --cpn-muted: #6b7280;
  --cpn-text: #111827;
  /* Sidebar/section headings — dark semibold, sentence case. */
  --cpn-heading: #0f172a;
  --cpn-accent: #1d4ed8;
  --cpn-card-bg: #ffffff;
  --cpn-nav-offset: 65px; /* matches body padding-top from /css/style.css */
}

.cpn-article {
  max-width: var(--cpn-max-width);
  margin: 0 auto;
  padding: 24px var(--cpn-side-pad) 80px;
  color: var(--cpn-text);
  font-family: 'Inter', system-ui, -apple-system, Segoe UI, sans-serif;
}

/* --- Breadcrumb ----------------------------------------------------- */
.cpn-breadcrumb {
  font-size: 13px;
  color: var(--cpn-muted);
  margin-bottom: 16px;
  line-height: 1.4;
  word-break: break-word;
}
.cpn-breadcrumb ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.cpn-breadcrumb li { display: inline-flex; align-items: center; gap: 6px; }
.cpn-breadcrumb a { color: var(--cpn-muted); text-decoration: none; }
.cpn-breadcrumb a:hover { color: var(--cpn-accent); text-decoration: underline; }
.cpn-breadcrumb [aria-current="page"] { color: var(--cpn-text); font-weight: 600; }
.cpn-breadcrumb .cpn-sep { color: #d1d5db; }

/* --- Sponsor strip -------------------------------------------------
   Sits between the breadcrumb and the company header. Spacing and the
   rounded-corner treatment mirror `.ins-feature-row` on /insights so the
   two surfaces read identically; the widget itself supplies the width and
   the 700/115 aspect ratio (see /components/Ads/ads-widget.css), so this
   stays responsive with no per-breakpoint rules. Generic naming is
   deliberate — see the host markup comment.

   Gap above comes from the breadcrumb's own margin-bottom rather than a
   margin-top here: at <= 899px `.cpn-article` is a flex column, where
   adjacent margins do NOT collapse, so a margin-top would add to it and
   the strip would sit lower on mobile than it does on desktop and on
   /insights. */
.cpn-feature-row {
  width: 100%;
  margin: 0 0 20px;
}
/* Reserve the banner slot's height while empty so the ad's arrival doesn't
   push the whole article down. Same reasoning + same collapse contract as
   `.lp-feature-row:empty` in landing.css — read the long note there. The
   700/115 ratio is the banner aspect contract from root CLAUDE.md and matches
   `.mh-rotator` in ads-widget.css, so the swap is a no-shift replacement; the
   widget adds `.mh-rotator` BEFORE writing innerHTML, so the height is
   continuous across the moment `:empty` stops matching.

   The reservation MUST be collapsible — an empty slot is a normal outcome,
   not a failure, since ads are audience-targeted. Collapse paths:
     1. Plan-gated viewer -> the [data-mh-no-ads] rule below (server-set).
     2. Widget ran, found nothing -> AdsWidget._hideQuietly sets INLINE
        display:none, which beats this rule.
     3. Widget never ran, admin plan emulation, or embedded mode ->
        renderBanner() in article.js / tab-shell.js collapses explicitly.
        Embedded mode matters MORE here than on the other surfaces: the
        article shell has no `html.mh-embedded #cpn-feature-row` rule (that
        exists only on the tab page), so before this change the drawer relied
        entirely on the `:empty` collapse that this rule replaces. */
html:not([data-mh-no-ads]) .cpn-feature-row:empty {
  aspect-ratio: 700 / 115;
  border-radius: 8px;
  background: linear-gradient(90deg, #f1f1f1 0%, #e5e7eb 50%, #f1f1f1 100%);
  background-size: 200% 100%;
  animation: cpn-skel-shimmer 1.4s linear infinite;
}
/* Plan-gated viewers (basic/core/explorer) never get an ad, so they must not
   get the reservation either: reserving space for a banner that is never
   coming, then collapsing it from JS, is the same shift inverted. */
[data-mh-no-ads] .cpn-feature-row:empty { display: none; }
/* Reduced-motion users keep the reserved box without the shimmer — the point
   of the reservation is the space, not the animation. */
@media (prefers-reduced-motion: reduce) {
  .cpn-feature-row:empty { animation: none; }
}
.cpn-feature-row.mh-rotator { border-radius: 8px; }

/* --- Company header -----------------------------------------------
   Deliberately understated: on an article page the headline is the
   subject and the company is context, so this sits below the article
   title in the visual hierarchy (see .cpn-body__title). */
.cpn-company-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 12px;
  margin-bottom: 0;
}
/* Height-driven, not a fixed square: logos now come from S3 at their real
   aspect ratio, so a wordmark gets its natural width up to the cap instead
   of being letterboxed inside a 46px box. No background here — a grey plate
   behind a transparent logo reads as a bug; it belongs to the placeholder
   below, which IS a square. Height matches --placeholder and --skel--logo,
   so keep all three in step. */
.cpn-company-header__logo {
  height: 46px;
  width: auto;
  max-width: 240px;
  border-radius: 8px;
  object-fit: contain;
  flex: 0 0 auto;
}
.cpn-company-header__logo--placeholder {
  width: 46px;
  min-width: 46px;
  flex: 0 0 46px;
  background: #f3f4f6;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--cpn-muted);
  font-size: 18px;
}
.cpn-company-header__text { display: flex; flex-direction: column; min-width: 0; }
.cpn-company-header__ticker {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--cpn-muted);
  text-transform: uppercase;
}
.cpn-company-header__name {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  color: var(--cpn-text);
  margin: 2px 0 0;
  word-break: break-word;
}
/* Add to watchlist (company-header.js, MHD-2577): right-hand end of the row. */
.cpn-company-header__add { margin-left: auto; flex: none; }
@media (max-width: 600px) {
  .cpn-company-header__add { width: 40px; height: 40px; padding: 0; }
  .cpn-company-header__add span { display: none; }
}
.cpn-company-header__link { text-decoration: none; color: inherit; }
.cpn-company-header__link:hover .cpn-company-header__name { color: var(--cpn-accent); }
/* Listed/active dot beside the company name, matching the mockup. */
.cpn-company-header__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #10b981;
  margin-left: 8px;
  vertical-align: middle;
}

/* --- Tab nav ------------------------------------------------------- */
.cpn-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--cpn-border);
  overflow-x: auto;
  scrollbar-width: none;
  margin: 0 0 32px;
}
.cpn-tabs::-webkit-scrollbar { display: none; }
.cpn-tabs a {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 600;
  color: var(--cpn-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}
.cpn-tabs a:hover { color: var(--cpn-text); }
.cpn-tabs a.is-active {
  color: var(--cpn-accent);
  border-bottom-color: var(--cpn-accent);
}
.cpn-tabs .material-symbols-outlined {
  font-size: 18px;
  font-variation-settings: 'FILL' 0, 'wght' 500;
}

/* --- Chrome skeleton placeholders ---------------------------------- */
/* Reserve the chrome's final dimensions at first paint so the breadcrumb,
   company header, and tab strip don't jump as JS hydrates. JS replaces the
   skeleton markup via innerHTML in the existing render functions. */
.cpn-skel {
  display: inline-block;
  background: linear-gradient(90deg, #f3f4f6 0%, #e5e7eb 50%, #f3f4f6 100%);
  background-size: 200% 100%;
  animation: cpn-skel-shimmer 1.4s ease-in-out infinite;
  border-radius: 4px;
  vertical-align: middle;
}
.cpn-skel--text   { height: 12px; width: 80px; }
.cpn-skel--logo {
  width: 46px;
  height: 46px;
  border-radius: 8px;
  flex: 0 0 46px;
}
.cpn-skel--ticker { display: block; height: 10px; width: 64px; margin-bottom: 7px; }
.cpn-skel--title  { display: block; height: 18px; width: 220px; max-width: 80%; }
.cpn-skel--tab    { height: 18px; width: 84px; }
.cpn-tabs__skel {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 14px;
  border-bottom: 2px solid transparent;
  pointer-events: none;
}
@keyframes cpn-skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cpn-skel { animation: none; }
}

/* --- 2-col grid (article + sticky sidebar) ------------------------- */
.cpn-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--cpn-grid-gap);
  align-items: start;
}
/* The article sits directly on the page canvas — no border, no rounded
   card, no shadow, no inner padding. Whitespace does the separating. */
.cpn-body {
  min-width: 0;
  /* Comfortable measure. The grid column is already ~776px at the 1200px
     container, so this only bites on wider custom containers. */
  max-width: 780px;
}
.cpn-body-loading {
  color: var(--cpn-muted);
  font-size: 14px;
  padding: 24px 0;
  text-align: center;
}

.cpn-sidebar {
  position: sticky;
  top: calc(var(--cpn-nav-offset) + 16px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* --- Article header ------------------------------------------------ */
/* No divider between the metadata and the article body — separation is
   spacing only (explicit design requirement). */
.cpn-body__header {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
}
.cpn-body__title {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 800;
  font-size: 36px;
  line-height: 1.18;
  letter-spacing: -0.015em;
  color: var(--cpn-text);
  margin: 0 0 18px;
  word-break: break-word;
}
/* Interview-type pill rendered above the title on /interview/{slug}-{id}.
   Matches the corner tag styling used on the /insights/interviews cards. */
.cpn-body__interview-tag {
  display: inline-block;
  padding: 4px 10px;
  margin: 0 0 12px;
  background: #30a5bf;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border-radius: 3px;
}

/* Two-line metadata block, shared by Company News and Insights:
     line 1 — authorship / source     ("Company news release · Source: Newsfile")
     line 2 — timestamp + supporting  ("31 July 2026, 8:47 a.m. EDT")
   Share sits to the right of the block as a quiet icon+text action. */
.cpn-body__meta-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0 0 32px;
}
.cpn-body__meta {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.cpn-body__meta-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  line-height: 1.4;
}
.cpn-body__meta-source {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cpn-accent);
}
.cpn-body__meta-time {
  font-size: 13px;
  color: var(--cpn-muted);
}
.cpn-body__meta-sep { color: #cbd5e1; }

/* --- Share control -------------------------------------------------
   Quiet icon + text, not a filled pill. */
.cpn-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  border-radius: 6px;
  padding: 4px 6px;
  margin: -4px -6px 0 0;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--cpn-muted);
  cursor: pointer;
  flex: 0 0 auto;
  transition: color 0.15s;
}
.cpn-share-btn:hover { color: var(--cpn-accent); }
.cpn-share-btn:focus-visible {
  outline: 2px solid var(--cpn-accent);
  outline-offset: 2px;
}
.cpn-share-icon {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

/* --- Interview video block ----------------------------------------- */
.cpn-body__video {
  margin: 0 0 24px;
}
.cpn-body__video-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
}
.cpn-body__video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.cpn-body__video--external {
  padding: 12px 0;
}
.cpn-body__video-link {
  display: inline-block;
  padding: 10px 18px;
  background: var(--cpn-accent, #30a5bf);
  color: #fff;
  text-decoration: none;
  border-radius: 6px;
  font-size: 14px;
}

/* --- Article body content ------------------------------------------ */
/* CONTAINMENT. Everything below `font-size` exists to stop imported newswire
   HTML widening the page. The body is arbitrary third-party markup — the
   ingest pipeline does not sanitise widths or nowrap styles — and the two
   things that reliably escaped were bare full-length asset URLs
   (`https://images.newsfilecorp.com/files/9148/312784_…_002full.jpg`, which
   the wires print in full under every figure) and wide tables. On a phone
   either one makes the whole PAGE scroll sideways; on desktop they run under
   the sticky sidebar, whose opaque cards then hide the content.

   `overflow-wrap: break-word` and NOT `anywhere`/`break-all`: break-word only
   breaks a word that cannot fit on a line of its own, so a long URL wraps
   while `CD-26-054` and `12.5 g/t` are left intact. It also leaves min-content
   sizing alone, so it cannot quietly squeeze a table column.

   Tables are the other half and cannot be solved in CSS — each one is moved
   into its own scroll container at runtime by enhanceBodyTables() in
   article.js. See static/components/article-tables.css. */
.cpn-body__content {
  font-size: 16px;
  line-height: 1.75;
  color: #1f2937;
  min-width: 0;
  max-width: 100%;
  overflow-wrap: break-word;
}
/* Wire bodies occasionally ship preformatted assay dumps. Scroll them for the
   same reason tables scroll — reflowing a monospaced column destroys it. */
.cpn-body__content pre {
  overflow-x: auto;
  max-width: 100%;
}
/* Newswire markup carries its own inline styles (nothing in the ingest
   pipeline strips them), including the occasional fixed-pixel wrapper around
   a figure. Capping the top-level blocks REFLOWS those rather than hiding
   them, so nothing becomes unreachable — the img/iframe/table rules below
   already cover the elements that carry intrinsic width. */
.cpn-body__content > * {
  max-width: 100%;
}

/* PDF-backed providers (ASX, SEDAR) — replace body_html text dump with an
   inline iframe of the source PDF. The iframe needs a fixed numeric height
   (browsers won't size an iframe via flex/aspect-ratio alone). Set tall
   enough for comfortable reading on a desktop monitor without relying on
   the viewport-relative units that produced a too-short box previously. */
.cpn-body__content--pdf {
  padding: 0;
}
.cpn-body__pdf-frame {
  display: block;
  width: 100%;
  height: 1200px;
  background: #f3f4f6;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
}
.cpn-body__pdf-frame iframe {
  width: 100%;
  height: 100% !important;
  border: 0;
  display: block;
}
@media (max-width: 899px) {
  .cpn-body__pdf-frame { height: 700px; }
}

/* --- Inline renderer variant -------------------------------------------
   The document is now rendered page-by-page into the flow by
   static/components/pdf-inline-viewer.js, so the frame must NOT impose a
   height: the article grows with the PDF and the page's own scrollbar is
   the only one. That is the whole point of the treatment — reinstating a
   height here silently restores the nested-scrollbar behaviour the inline
   renderer replaced.

   The fixed-height rules above still apply to the iframe FALLBACK, which is
   rendered inside this same frame when a document cannot be fetched (an
   unmirrored row, whose serve URL 302s off-origin into a CORS failure). The
   fallback carries its own `.mh-pdfdoc-fallback` height, so both paths are
   correct within one wrapper. */
.cpn-body__pdf-frame--inline,
.cpn-body__pdf-frame--inline.cpn-body__pdf-frame--filing {
  height: auto;
  overflow: visible;
  background: transparent;
  border-radius: 0;
}

@media (max-width: 899px) {
  .cpn-body__pdf-frame--inline { height: auto; }
}

/* The control strip is still a bar above the document; without a rounded,
   clipped parent it needs its own top corners and a hairline all round. */
.cpn-body__pdf-frame--inline .cpn-filing-controls {
  border: 1px solid var(--cpn-border);
  border-radius: 6px 6px 0 0;
  margin-bottom: 12px;
}

/* Fullscreen is the ONE place this variant needs its own scroller: the
   element becomes viewport-sized, so its auto-height content has nowhere
   else to go. Everywhere else, `overflow: visible` above is load-bearing. */
.cpn-body__pdf-frame--inline:fullscreen {
  overflow-y: auto;
  background: #f3f4f6;
  padding: 16px;
}

/* --- SEDAR filing viewer variant ---------------------------------------
   Rendered when article.article_subtype === 'sedar-filing'. Adds a
   control strip (PDF/HTML switcher + Download + Fullscreen) above the
   iframe, and enables the native Fullscreen API on the wrapping frame
   so the browser's PDF viewer can fill the whole viewport.

   The control strip is a flex row; on narrow viewports it wraps to a
   second line. `.cpn-filing-controls__spacer` uses `margin-left: auto`
   to push Download+Fullscreen to the right without breaking wrap. */
.cpn-filing-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: #f9fafb;
  border-bottom: 1px solid var(--cpn-border);
}
.cpn-filing-controls__spacer { flex: 1 1 auto; }

.cpn-body__pdf-frame--filing .cpn-body__pdf-frame__iframe,
.cpn-body__pdf-frame--filing > iframe {
  /* Frame height is minus the control strip; iframe is sized by parent
     flex/absolute rules below rather than the fixed height above. */
}
.cpn-body__pdf-frame--filing {
  display: flex;
  flex-direction: column;
}
.cpn-body__pdf-frame--filing > iframe { flex: 1 1 auto; }

/* Fullscreen: drop the frame's radius/border so the browser's PDF
   viewer fills the viewport cleanly; hide the fullscreen button once
   we're already in fullscreen (Esc / native chrome is the way out). */
.cpn-body__pdf-frame:fullscreen { border-radius: 0; }
.cpn-body__pdf-frame:fullscreen .cpn-filing-controls { display: none; }
.cpn-body__pdf-frame:fullscreen > iframe { height: 100vh !important; }

/* Format switcher — PDF | HTML segmented control. Active button is the
   accent colour; inactive is a plain outline anchor. */
.cpn-filing-switcher {
  display: inline-flex;
  border: 1px solid var(--cpn-border);
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
}
.cpn-filing-switcher__btn {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--cpn-muted);
  background: #fff;
  text-decoration: none;
  border-right: 1px solid var(--cpn-border);
  transition: background-color 0.15s, color 0.15s;
}
.cpn-filing-switcher__btn:last-child { border-right: none; }
.cpn-filing-switcher__btn:hover { background: #f5f7fb; color: var(--cpn-text); }
.cpn-filing-switcher__btn.is-active {
  background: var(--cpn-accent);
  color: #fff;
  cursor: default;
}
.cpn-filing-switcher__btn.is-active:hover { background: var(--cpn-accent); color: #fff; }

/* Download + Fullscreen buttons — same visual weight as each other,
   sit to the right of the switcher via the spacer. */
.cpn-filing-download,
.cpn-filing-open,
.cpn-filing-fullscreen {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font: 600 12px/1 'Inter', system-ui, sans-serif;
  color: var(--cpn-text);
  background: #fff;
  border: 1px solid var(--cpn-border);
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s;
}
.cpn-filing-download:hover,
.cpn-filing-open:hover,
.cpn-filing-fullscreen:hover { background: #f5f7fb; }
.cpn-filing-download .material-symbols-outlined,
.cpn-filing-open .material-symbols-outlined,
.cpn-filing-fullscreen .material-symbols-outlined { font-size: 14px; }
.cpn-body__content > * + * { margin-top: 1.15em; }
.cpn-body__content p { margin: 0 0 1.15em; }
.cpn-body__content h1,
.cpn-body__content h2,
.cpn-body__content h3,
.cpn-body__content h4 {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.3;
  color: var(--cpn-text);
  margin: 1.8em 0 0.6em;
}
.cpn-body__content h2 { font-size: 23px; }
.cpn-body__content h3 { font-size: 19px; }
.cpn-body__content h4 { font-size: 17px; }
.cpn-body__content a { color: var(--cpn-accent); }
.cpn-body__content img,
.cpn-body__content video,
.cpn-body__content iframe {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  margin: 0;
}
/* Figures fill the reading column. The class is set by fillBodyImages() in
   article.js, which gates on INTRINSIC size — most <img> elements in a press
   release are tracking pixels, Cision favicons or the 200px-wide Newsfile
   corporate logo, and stretching any of those would be worse than the gap this
   closes. See that function for the threshold and the full-resolution upgrade
   that keeps the stretch from going soft.

   `.cpn-body__imglink--fill` is not optional. Both the wire's own anchor and
   the one enhanceBodyImages() adds are inline-block, and an inline-block box
   shrink-wraps to its content's intrinsic width — so a `width: 100%` image
   inside one resolves to 100% of its own natural width and never grows. */
.cpn-body__content img.cpn-body__img--fill {
  width: 100%;
  height: auto;
}
.cpn-body__content a.cpn-body__imglink--fill {
  display: block;
  width: 100%;
}

/* Click-to-enlarge affordance. The anchor is either the wire release's own
   link to the full-resolution asset or one added by enhanceBodyImages() in
   article.js — both carry this class. */
.cpn-body__content .cpn-lightbox-link {
  display: inline-block;
  max-width: 100%;
}
.cpn-body__content .cpn-lightbox-link img {
  cursor: zoom-in;
}
.cpn-body__content table {
  border-collapse: collapse;
  width: 100%;
  margin: 1.4em 0;
  font-size: 14px;
}
.cpn-body__content th,
.cpn-body__content td {
  padding: 8px 10px;
  border: 1px solid var(--cpn-border);
  text-align: left;
}
.cpn-body__content th { background: #f9fafb; font-weight: 600; }
/* Company News quotations keep a neutral, non-editorial treatment. Wire
   releases quote their CEO constantly, and the Insight styling below must
   NOT bleed onto them — the two article types are meant to be tellable
   apart at a glance. */
.cpn-body__content blockquote {
  border-left: 3px solid var(--cpn-border);
  background: #f9fafb;
  margin: 1.4em 0;
  padding: 12px 16px;
  color: var(--cpn-muted);
  font-style: italic;
  border-radius: 0 6px 6px 0;
}
.cpn-body__content blockquote p:last-child { margin-bottom: 0; }

/* --- Insight quote treatment ---------------------------------------
   Open layout: no grey box, blue accent rule, oversized quote glyph, and
   the speaker beneath. Scoped to .cpn-body--insights (set in renderBody)
   so it can never apply to a company announcement. The glyph is supplied
   here rather than in the content — the pipeline's blockquote markup
   carries no glyph of its own. */
.cpn-body--insights .cpn-body__content blockquote {
  position: relative;
  border-left: 3px solid var(--cpn-accent);
  background: none;
  border-radius: 0;
  margin: 2em 0;
  padding: 2px 0 2px 26px;
  color: #1f2937;
  font-style: italic;
  font-size: 16.5px;
  line-height: 1.7;
}
.cpn-body--insights .cpn-body__content blockquote::before {
  content: '\201C';
  position: absolute;
  left: 20px;
  top: -6px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 40px;
  line-height: 1;
  color: var(--cpn-accent);
  pointer-events: none;
}
/* The glyph occupies the start of the first line, so indent only that one
   — subsequent paragraphs sit flush against the rule. */
.cpn-body--insights .cpn-body__content blockquote > p:first-child {
  text-indent: 26px;
}
.cpn-body--insights .cpn-body__content blockquote p {
  margin: 0 0 0.9em;
}
.cpn-body--insights .cpn-body__content blockquote p:last-of-type {
  margin-bottom: 0;
}

/* Speaker block, built by enhanceBlockquotes() from the pipeline's
   "— Name, Role" trailing paragraph. Upright, not italic — it is
   attribution, not speech. */
.cpn-quote__attrib {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 14px;
  font-style: normal;
}
.cpn-quote__name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--cpn-text);
}
.cpn-quote__role {
  font-size: 13px;
  color: var(--cpn-muted);
}
.cpn-body__content ul,
.cpn-body__content ol { padding-left: 24px; }
.cpn-body__content li + li { margin-top: 0.35em; }
.cpn-body__empty { color: var(--cpn-muted); font-style: italic; }

/* About-company boilerplate at the foot of the body. */
.cpn-about {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--cpn-border);
}
.cpn-about__heading {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 700;
  font-size: 16px;
  margin: 0 0 8px;
  color: var(--cpn-text);
}
.cpn-about__text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--cpn-muted);
  margin: 0 0 8px;
}
.cpn-about__link {
  font-size: 14px;
  font-weight: 600;
  color: var(--cpn-accent);
  text-decoration: none;
}
.cpn-about__link:hover { text-decoration: underline; }

/* --- Sidebar cards ------------------------------------------------- */
.cpn-card {
  background: var(--cpn-card-bg);
  border: 1px solid var(--cpn-border);
  border-radius: 12px;
  padding: 18px;
  display: flex;
  flex-direction: column;
}
.cpn-card__head {
  margin-bottom: 14px;
}
/* Sentence case, dark semibold — NOT an uppercase eyebrow. Shared by the
   "Company snapshot", "Related project" and "3D model" cards. */
.cpn-card__heading {
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--cpn-heading);
}

/* Company snapshot card */
.cpn-card__identity {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.cpn-card__logo {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  object-fit: contain;
  background: #f3f4f6;
  flex: 0 0 40px;
}
.cpn-card__logo--placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--cpn-muted);
  font-size: 15px;
}
.cpn-card__identity-text { min-width: 0; }
.cpn-card__name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cpn-card__name {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 700;
  font-size: 14.5px;
  line-height: 1.25;
  margin: 0;
  color: var(--cpn-text);
  word-break: break-word;
}
.cpn-card__status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #10b981;
  flex: 0 0 8px;
}
.cpn-card__sub {
  margin-top: 3px;
  font-size: 12px;
  color: var(--cpn-muted);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.cpn-card__ticker { font-weight: 600; color: var(--cpn-muted); }
.cpn-card__sub-sep { color: #d1d5db; }

/* Metrics: clean two-column label/value rows. No grey tiles, no dividers. */
.cpn-card__stats {
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.cpn-stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
}
.cpn-stat__label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--cpn-muted);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin: 0;
  flex: 0 0 auto;
  white-space: nowrap;
}
.cpn-stat__value {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cpn-text);
  line-height: 1.3;
  text-align: right;
  min-width: 0;
  word-break: break-word;
}
.cpn-stat__change {
  font-size: 12px;
  font-weight: 600;
  margin-left: 4px;
}
.cpn-stat__change--up { color: #10b981; }
.cpn-stat__change--down { color: #ef4444; }

/* Related project card */
.cpn-card__project-name {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 700;
  font-size: 15px;
  margin: 0 0 3px;
  color: var(--cpn-text);
}
.cpn-card__project-jurisdiction {
  font-size: 12px;
  color: var(--cpn-muted);
  margin-bottom: 12px;
}
.cpn-card__project-thumb-link {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 8px;
  overflow: hidden;
  background: #f3f4f6;
  margin-bottom: 12px;
}
.cpn-card__project-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.cpn-card__project-thumb--missing { object-fit: contain; padding: 16px; opacity: 0.5; }
.cpn-card__project-cta {
  align-self: flex-start;
  font-size: 13px;
  font-weight: 600;
  color: var(--cpn-accent);
  text-decoration: none;
}
.cpn-card__project-cta:hover { text-decoration: underline; }

/* --- Full-width end-of-article section ------------------------------
   "More from {Company}" — sits below BOTH the article and the sidebar.
   Column count is driven by --cpn-tile-count, set inline by article.js
   from the number of cards that actually had content, so hidden empty
   cards reflow the remainder across the available width. */
.cpn-tiles {
  margin-top: 56px;
  padding-top: 32px;
  border-top: 1px solid var(--cpn-border);
}
.cpn-tiles:empty { display: none; }

/* --- Insight email CTA (MHD-1986) ------------------------------------
   Sibling of .cpn-grid and #cpn-tiles, so it spans the full content width
   on desktop; mobile order puts it between the article and the sidebar. */
.cpn-email-cta {
  margin-top: 48px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 500px);
  gap: 20px 48px;
  align-items: center;
  padding: 22px 28px;
  background: #f6f9fd;
  border: 1px solid #dfe7f1;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(15, 30, 55, 0.06);
}
.cpn-email-cta + .cpn-tiles { margin-top: 40px; }
.cpn-email-cta--done { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); }
.cpn-email-cta__intro { display: flex; gap: 18px; align-items: flex-start; }
.cpn-email-cta__icon { flex: 0 0 auto; color: #2563eb; line-height: 0; }
.cpn-email-cta__label {
  margin: 0 0 6px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #1d4ed8;
}
.cpn-email-cta__title {
  margin: 0 0 8px;
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 19px;
  font-weight: 700;
  color: var(--cpn-heading);
}
.cpn-email-cta__desc { margin: 0; font-size: 13.5px; line-height: 1.55; color: #374151; }
.cpn-email-cta__form { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.cpn-email-cta__form[hidden] { display: none; }
.cpn-email-cta__row { display: flex; gap: 10px; }
.cpn-email-cta__sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.cpn-email-cta__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 14px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  background: #fff;
  font: inherit;
  font-size: 14px;
  color: var(--cpn-text);
}
.cpn-email-cta__input:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15); }
.cpn-email-cta__input[aria-invalid="true"] { border-color: #c53030; }
.cpn-email-cta__submit {
  flex: 0 0 auto;
  padding: 10px 18px;
  border: 0;
  border-radius: 6px;
  background: #0f1e37;
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.cpn-email-cta__submit:hover:not(:disabled) { background: #1c2f52; }
.cpn-email-cta__submit:disabled { background: #6b7280; cursor: wait; }
.cpn-email-cta__error { margin: -4px 0 0; font-size: 13px; color: #c53030; }
.cpn-email-cta__error:empty { display: none; }
.cpn-email-cta__disclosure { font-size: 12px; line-height: 1.5; color: var(--cpn-muted); }
.cpn-email-cta__success[hidden] { display: none; }
.cpn-email-cta__success-title { margin: 0 0 4px; font-weight: 700; font-size: 16px; color: #15803d; }
.cpn-email-cta__success-msg { margin: 0; font-size: 14px; line-height: 1.5; color: #1f2937; }
.cpn-tiles__heading {
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 20px;
  font-weight: 700;
  color: var(--cpn-heading);
  margin: 0 0 20px;
}
.cpn-tiles__grid {
  display: grid;
  grid-template-columns: repeat(var(--cpn-tile-count, 3), minmax(0, 1fr));
  gap: var(--cpn-gap);
  align-items: start;
}

/* --- Related Insights cards (Insight articles) ----------------------
   Richer treatment than the Company News context row: thumbnail left,
   category + headline + excerpt right, meta line spanning underneath.
   Borderless — the thumbnails carry the visual weight. */
/* Column count follows the number of cards that actually cleared the
   relevance floor (--cpn-rel-count, set in renderTiles), so one or two
   matches spread across the full width instead of leaving a dead third. */
.cpn-rel-grid {
  display: grid;
  grid-template-columns: repeat(var(--cpn-rel-count, 3), minmax(0, 1fr));
  gap: 28px;
  align-items: start;
}
.cpn-rel {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  grid-template-areas:
    "thumb text"
    "meta  meta";
  gap: 12px 14px;
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.cpn-rel:hover .cpn-rel__title { color: var(--cpn-accent); }
.cpn-rel__thumb {
  grid-area: thumb;
  /* Positioning context for the "Stock image" pill — required by
     /components/article-thumb.css. */
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  background: #f3f4f6;
}
.cpn-rel__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* A card whose image failed to load drops the thumb entirely (see the
   onerror in article.js); the text then spans the full card width rather
   than sitting beside an empty grey box. */
.cpn-rel__text {
  grid-area: text;
  min-width: 0;
}
/* Thumb absent (image 404'd, or no URL resolved) — the text takes the whole
   card rather than leaving a 132px gutter. */
.cpn-rel > .cpn-rel__text:first-child { grid-column: 1 / -1; }
.cpn-rel__eyebrow {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--cpn-accent);
  margin-bottom: 4px;
}
.cpn-rel__title {
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--cpn-text);
  margin: 0 0 6px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s;
}
.cpn-rel__excerpt {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--cpn-muted);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cpn-rel__meta {
  grid-area: meta;
  font-size: 11.5px;
  color: #9ca3af;
  padding-top: 2px;
}
.cpn-rel__meta-sep { color: #d1d5db; margin: 0 2px; }

.cpn-tile {
  background: var(--cpn-card-bg);
  border: 1px solid var(--cpn-border);
  border-radius: 12px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.cpn-tile__head {
  margin-bottom: 10px;
}
.cpn-tile__title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--cpn-muted);
  margin: 0;
}
.cpn-tile__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 2px;
}
.cpn-tile__foot {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--cpn-border-soft);
}
.cpn-tile__viewall {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--cpn-accent);
  text-decoration: none;
  white-space: nowrap;
}
.cpn-tile__viewall:hover { text-decoration: underline; }

/* Rows: leading icon, then title over date. Shared shape across the news,
   filing and insider tiles so the three cards read as one system. */
.cpn-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 7px 6px;
  margin: 0 -6px;
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
  transition: background 0.12s;
}
a.cpn-row:hover { background: #f8fafc; }
.cpn-row__icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  color: #9ca3af;
  fill: currentColor;
}
.cpn-row__text { min-width: 0; flex: 1; }
.cpn-row__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--cpn-text);
  line-height: 1.4;
  /* Two-line clamp: filing descriptions and headlines are long, and a
     single-line ellipsis loses too much of them at tile width. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cpn-row__date {
  font-size: 11.5px;
  color: var(--cpn-muted);
  margin-top: 3px;
}
.cpn-row__pdf {
  flex: 0 0 auto;
  align-self: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--cpn-muted);
  background: transparent;
  border: 1px solid var(--cpn-border);
  padding: 3px 7px;
  border-radius: 4px;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.cpn-row__pdf:hover {
  border-color: var(--cpn-muted);
  color: var(--cpn-text);
  background: #f3f4f6;
}
/* Filing rows carry a second anchor (the PDF badge) beside the main link, so
   the outer element is a <div> — nesting anchors is invalid HTML and the
   browser would auto-close the outer one. */
.cpn-row--filing { align-items: center; }
.cpn-row--filing:hover { background: #f8fafc; }
.cpn-row__main {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex: 1;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}

/* --- Lead capture ---------------------------------------------------
   "Stay Updated" card appended to the end of the article body by
   renderLeadCapture(). Card chrome comes from
   /components/LeadCapture/lead-capture.css; this only places it. */
.cpn-lead-capture {
  margin-top: 40px;
  padding-top: 28px;
  border-top: 1px solid var(--cpn-border);
}

/* --- Responsive ----------------------------------------------------- */
@media (max-width: 1099px) {
  :root { --cpn-grid-gap: 36px; }
  .cpn-grid { grid-template-columns: minmax(0, 1fr) 300px; }
  .cpn-body__title { font-size: 32px; }
}

@media (max-width: 899px) {
  /* Mobile section order: chrome (breadcrumb, banner, header, tabs) →
     article → related project card → company snapshot → full-width
     section. The desktop DOM order is article+sidebar in a grid followed
     by the section; `display: contents` on the grid promotes article and
     sidebar to direct children of the flex article so `order` can
     interleave them. */
  .cpn-article {
    display: flex;
    flex-direction: column;
    padding: 16px 16px 60px;
  }
  .cpn-grid { display: contents; }
  .cpn-body { order: 1; max-width: none; }
  .cpn-sidebar {
    order: 2;
    position: static;
    top: auto;
    margin-top: 32px;
    gap: 12px;
  }
  .cpn-tiles {
    order: 3;
    margin-top: 32px;
    padding-top: 24px;
  }
  /* Same order as .cpn-body and later in the DOM, so it lands right after
     the article and before the sidebar (Related project). */
  .cpn-email-cta {
    order: 1;
    margin-top: 32px;
    grid-template-columns: minmax(0, 1fr);
    padding: 22px 20px;
  }
  .cpn-email-cta__form,
  .cpn-email-cta__success { padding-left: 52px; }
  .cpn-email-cta + .cpn-tiles { margin-top: 32px; }
  /* Empty cards are removed from the DOM, so the remaining ones still
     fill the row on tablet widths. */
  .cpn-tiles__grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
  .cpn-rel-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 22px; }
  .cpn-card--project { order: 1; }
  .cpn-card--3d { order: 2; }
  .cpn-card--company { order: 3; }
  .cpn-company-header__logo {
    height: 42px;
    max-width: 200px;
  }
  .cpn-company-header__logo--placeholder,
  .cpn-skel--logo {
    width: 42px; height: 42px; flex-basis: 42px; min-width: 42px;
  }
  .cpn-company-header__name { font-size: 18px; }
  .cpn-body__title { font-size: 28px; }
  /* Make the top tab nav sticky so users can switch tabs without scrolling
     back to the top of long articles. Sits under the fixed site nav. */
  .cpn-tabs {
    position: sticky;
    top: var(--cpn-nav-offset);
    z-index: 5;
    background: #fff;
    margin: 0 -16px 24px;
    padding-left: 16px;
    padding-right: 16px;
  }
}

@media (max-width: 599px) {
  .cpn-breadcrumb { font-size: 12px; }
  .cpn-tabs a { padding: 10px 12px; font-size: 13px; }
  .cpn-company-header__name { font-size: 17px; }
  .cpn-body__title { font-size: 24px; }
  .cpn-body__content { font-size: 15.5px; }
  .cpn-tiles__heading { font-size: 18px; }
  .cpn-tiles__grid { grid-template-columns: 1fr; }
  .cpn-rel-grid { grid-template-columns: 1fr; gap: 20px; }
  .cpn-rel { grid-template-columns: 104px minmax(0, 1fr); }
  /* Share drops under the metadata rather than squeezing beside it. */
  .cpn-body__meta-row { flex-direction: column; align-items: flex-start; gap: 12px; }
  .cpn-share-btn { margin: 0 0 0 -6px; }
  /* Stacked: full-width field and CTA, controls span the card. */
  .cpn-email-cta__form,
  .cpn-email-cta__success { padding-left: 0; }
  .cpn-email-cta__row { flex-direction: column; }
  .cpn-email-cta__submit { width: 100%; padding: 12px 18px; }
  .cpn-email-cta__disclosure { text-align: center; }
  .cpn-email-cta .mh-ns-option { flex: 1 1 auto; padding: 7px 10px; }
}

/* --- SEO hub back-links (MHD-2143, MHSEO-11) -------------------------
   Drawn by /components/hub-links.js. The strip sits AFTER #cpn-tab-mount on
   the company + project pages so it cannot move content already painted;
   on the article shell it is a sidebar card (.cpn-card). */
.mh-hublinks:not(.mh-hublinks--card) {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--cpn-border);
}
.mh-hublinks__heading {
  margin: 0 0 12px;
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: var(--cpn-heading);
}
.mh-hublinks--card .cpn-card__head { margin-bottom: 10px; }
.mh-hublinks__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.mh-hublinks--card .mh-hublinks__list { flex-direction: column; }
.mh-hublinks__link {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  max-width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--cpn-border);
  border-radius: 8px;
  color: var(--cpn-text);
  text-decoration: none;
  font-size: 14px;
  line-height: 1.3;
}
.mh-hublinks--card .mh-hublinks__link { display: flex; }
.mh-hublinks__link:hover,
.mh-hublinks__link:focus-visible { border-color: var(--cpn-accent); color: var(--cpn-accent); }
.mh-hublinks__type {
  font-size: 12px;
  color: var(--cpn-muted);
  white-space: nowrap;
}
.mh-hublinks__name { font-weight: 600; overflow-wrap: anywhere; }
