/* ============================================================
   single-post.css  —  Single Blog Post
   Figma node  : 1963-6303
   Template    : single.php  (WordPress standard single post)
   Deps        : intone-design-system + intone-theme-tokens
   Version     : 1.0.0

   Sections
   ────────
   1.  Page wrapper
   2.  Breadcrumb
   3.  Post header (author · title · share bar)
   4.  Share bar
   5.  Featured image
   6.  Post body layout (2-col: sidebar | content)
   7.  TOC sidebar
   8.  EagleEye365 promo card
   9.  Article content typography
   10. Related articles (gold sidebar + carousel)
   11. Responsive
   12. Dark mode overrides
   ============================================================ */


/* ── 1. Page wrapper ──────────────────────────────────────────
   .ihn (site header) is `position:fixed; top:0` (72px tall) — single.php
   isn't hero-led, so its first element (the breadcrumb) rendered in
   normal flow starting at y=0, sitting BEHIND/overlapping the fixed
   header. padding-top clears it, same clamp() already used for this
   exact purpose on the sibling archive templates (archive-case-study.css
   / archive-whitepaper.css's `.intone-case-study-page` /
   `.intone-whitepaper-page`) — reusing it here keeps all three
   content-led templates consistent. Because this is normal-flow spacing
   (not the absolute-positioned --over-hero variant Pages use), a
   wrapping breadcrumb or long title just grows the page height like any
   other block content — nothing can overlap the header or the title
   below it regardless of how many lines either one takes. */
.intone-single-post {
  padding-top: clamp(80px, 12vw, 80px);
  background: #fff;
  /* Restore .post-sidebar's position:sticky. .intone-page (this element
     also carries that class) sets `overflow-x: hidden` sitewide as an
     anti-bleed guard; per spec, a non-visible value on ONE axis forces the
     other to `overflow-y: auto`, silently turning this wrapper into the
     nearest scroll container — so the sidebar's sticky bound to it (which
     never scrolls) instead of the viewport, and just scrolled away. Same
     fix already used on .intone-jobs-page: `overflow-x: clip` clips
     horizontally WITHOUT triggering the overflow-y:auto quirk, so sticky
     binds to the real viewport again and stays smooth (native, compositor-
     driven — no JS/transition needed). */
  overflow-x: clip;
  overflow-y: visible;
}


/* ── 2. Breadcrumb ──────────────────────────────────────────
   single.php renders the SHARED .intone-breadcrumb component (see
   template-parts/breadcrumbs.php) — not a template-local one — so its
   typography/colors/dark-mode already come from intone-design-system.css.
   Single posts aren't hero-led (breadcrumbs.php only floats --over-hero
   on Pages), so it stays in normal flow full-width by default; scoped
   here to the same 1440px/44px stage as .post-hero-image and .post-body
   below, matching how .intone-breadcrumb--over-hero centers itself
   "the same way .ihn-inner does" — so the crumb trail lines up with the
   hero and article edges instead of running edge-to-edge. ── */
.intone-single-post .intone-breadcrumb {
  margin: 0 auto;
  box-sizing: border-box;
}


/* ── 3. Post header ─────────────────────────────────────── */
.post-header {
  padding: 48px 44px 40px;
}

.post-header__inner {
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.post-header__meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.post-header__author {
  display: flex;
  align-items: center;
  gap: 16px;
}

.post-header__avatar {
  width: 40px;
  height: 40px;
  /* No border-radius:50% — the brand favicon/squircle used as an avatar has
     its OWN shape (rounded on 3 corners, squared top-right); a circular mask
     clipped that corner so it read as a plain circle. object-fit:contain
     shows the whole image edge-to-edge instead of cropping it. Real square
     photo thumbnails still fill the 1:1 box. */
  object-fit: contain;
  flex-shrink: 0;
  /* SVG avatars (allowed + sanitized via the Safe SVG plugin) can report a
     0×0 intrinsic size in some browsers; the explicit box + aspect-ratio
     keeps them sized correctly rather than collapsing. */
  aspect-ratio: 1 / 1;
}

.post-header__author-name {
  font-family: 'Public Sans', sans-serif;
  font-size: 18px;
  font-weight: 500;
  color: #141414;
  line-height: 24px;
}

.post-header__date {
  font-family: 'Public Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #818994;
  line-height: 24px;
}

.post-header__title {
  font-family: 'Public Sans', sans-serif;
  font-size: 40px;
  font-weight: 500;
  line-height: 48px;
  color: #141414;
  margin: 0;
}


/* ── 4. Share bar ────────────────────────────────────────── */
.post-share-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  background: #ebeef2;
  padding: 10px 12px;
  gap: 12px;
}

.post-share-bar__reading-time {
  font-family: 'Public Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #818994;
  line-height: 24px;
  white-space: nowrap;
}

.post-share-bar__icons {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* Plain icon style (this bar's own original look — NOT the footer's
   circular black badge). Only the SVG glyphs + links were matched to
   .intone-footer-social__icon (same LinkedIn/Facebook/Instagram artwork
   and profile URLs); the visual treatment here stays a bare icon. */
.post-share-bar__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  color: #1e2e4c;
  text-decoration: none;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: opacity 0.2s;
  line-height: 0;
}

.post-share-bar__icon:hover { opacity: 0.6; }

.post-share-bar__icon svg {
  width: 20px;
  height: 20px;
}


/* ── 5. Featured image ───────────────────────────────────────
   Reference size: ~1080×560 at a 1440px screen — 1080/1440 = 75vw exactly,
   so `clamp(…, 75vw, 1080px)` reproduces that ratio fluidly below 1440px
   and holds flat at 1080px above it (was `max-width:1440px` — nearly
   edge-to-edge of the whole stage; this is deliberately narrower and
   centered within it). aspect-ratio (1080:560 ≈ 1.93:1) replaces the old
   fixed height (624px desktop / 260px mobile via a media-query override)
   so the image scales proportionally at every width instead of jumping
   between two hardcoded heights. */
.post-hero-image {
  width: clamp(320px, 75vw, 1080px);
  aspect-ratio: 1080 / 560;
  margin: 0 auto;
  overflow: hidden;
  background: #f6f6f6;
}

.post-hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


/* ── 6. Post body layout ─────────────────────────────────────
   justify-content:center balances the sidebar+content pair as a unit
   inside the padded stage: post-content is intentionally capped at a
   640px reading width (below), so on wide viewports the pair (max
   ~1055px: 375 sidebar + 40 gap + 640 content) is narrower than the
   1352px inner track — flex-start left the leftover space stacked
   entirely on the right, reading as "shoved left" instead of centered. */
.post-body {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
  padding: 64px 44px 96px;
  max-width: 1440px;
  margin: 0 auto;
}

/* Left sidebar — sticks to the viewport while .post-content scrolls past it,
   then releases naturally once .post-content (the taller flex sibling) runs
   out, since a sticky element can never scroll past the bottom of its own
   flex-item box. No max-height/overflow-y here on purpose: those forced the
   sidebar into its OWN internal scrollbar instead of letting native sticky
   positioning track the page scroll, which is what made it feel disconnected
   from .post-content rather than "attached" to it while scrolling. Native
   `position: sticky` is already compositor-driven and smooth in both scroll
   directions — no transition/JS is added on top of it, since animating
   `top`/`position` would only introduce lag behind the real scroll offset. */
.post-sidebar {
  width: 375px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 56px;
  position: sticky;
  top: 100px;
  align-self: flex-start;
}

/* Main content */
.post-content {
  flex: 1;
  max-width: 740px;
  min-width: 0;
}

/* No sidebar rendered at all (Post Layout meta box — Sidebar off, or
   both TOC and Promo Card off): widen the reading column since there's
   no 300-375px sidebar competing for space. No Figma spec for this
   state exists yet — 820px is a comfortable reading width between the
   640px two-column case and the 1440px page container. */
.post-body--full .post-content {
  max-width: 820px;
  margin: 0 auto;
}

/* Defensive nets — single.php already omits .post-sidebar entirely
   when both TOC and Promo Card are off, and .post-promo-card__content
   when both heading and body are off, but these guard against any
   future caller leaving one in the DOM empty. */
.post-sidebar:empty,
.post-promo-card__content:empty {
  display: none;
}


/* ── 7. Table of contents ────────────────────────────────── */
.post-toc {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.post-toc__title {
  font-family: 'Public Sans', sans-serif;
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: #1e2e4c;
  line-height: 1.35;
  margin: 0;
}

.post-toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* Each item gets its OWN left guide bar (was one bar shared across the
   whole list) so it can carry read-progress state independently, matching
   the reference site's TOC: bars fill in one by one as their section is
   scrolled past, instead of a single static line. State toggled by
   initTocScrollSpy() in single.php. */
.post-toc__item {
  margin: 0;
  border-left: 2px solid #d3dae4;
  padding-left: 12px;
  transition: border-color 0.25s ease;
}

.post-toc__item.is-read {
  border-left-color: #233963;
}

.post-toc__link {
  font-family: 'Public Sans', sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: #1e2e4c;
  text-decoration: none;
  line-height: 24px;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 300px;
  transition: color 0.2s;
}

.post-toc__link:hover { color: #233963; }

/* Currently-in-view section (scroll-spy) — text weight/color on top of
   the .post-toc__item.is-read guide-bar progress above. */
.post-toc__link.is-active {
  color: #233963;
  font-weight: 600;
}


/* ── 8. EagleEye365 promo card ─────────────────────────────
   Figma node 1963:6828 ("Eagle Eye365"). Card is 375×549 with 3
   decorative layers behind the text (bottom → top):
     1. white base + 1px #a5abb3 border (the card itself)
     2. a #f4f6f9 tint covering the top ~61% of the card height
     3. a rotated-square "notched" blob (#ffca6e) — the fill path is
        two straight bevels cutting the top-left and bottom-right
        corners of a square at its 25/50/75% marks, which is exactly
        representable as a clip-path polygon (no curves in the
        original vector), so it's reproduced as CSS rather than an
        image and stays crisp/scalable at any card size
     4. the EagleEye365 cutout photo, anchored bottom-right
   ─────────────────────────────────────────────────────────────── */
.post-promo-card {
  border: 1px solid #a5abb3;
  background: #fff;
  overflow: hidden;
  position: relative;
  min-height: 549px;
}

/* Layer 2 — tint covering the top 61% of the card */
.post-promo-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 61.2%;
  /* background: #f4f6f9; */
  pointer-events: none;
}

/* Layer 3 — decorative blob, sized/positioned as % of the card so it
   scales correctly at every breakpoint instead of only fitting 375px */
.post-promo-card__blob {
  position: absolute;
  left: -19%;
  top: 55%;
  width: 172%;
  height: 118%;
  background: #ffca6e;
  clip-path: polygon(50% 0%, 100% 0%, 100% 50%, 75% 75%, 50% 100%, 0% 100%, 0% 50%, 25% 25%);
  pointer-events: none;
}

/* Layer 4 — EagleEye365 cutout photo */
.post-promo-card__photo {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 58%;
  height: auto;
  display: block;
  pointer-events: none;
}

.post-promo-card__inner {
  position: relative;
  z-index: 1;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  min-height: 100%;
}

.post-promo-card__content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.post-promo-card__heading {
  font-family: 'Public Sans', sans-serif;
  font-size: 32px;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.36;
  color: #141414;
  margin: 0;
}

.post-promo-card__body {
  font-family: 'Public Sans', sans-serif;
  font-size: 18px;
  font-weight: 400;
  line-height: 1.6;
  color: #000;
  margin: 0;
}

/* Constrained so it wraps clear of the photo, matching Figma (~64% of
   the card's content width) instead of running full-width underneath it */
.post-promo-card__tagline {
  font-family: 'Public Sans', sans-serif;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.6;
  color: #000;
  margin: 0;
  max-width: 64%;
}

.post-promo-card__btn {
  display: block;
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 12px 16px;
  border: 2px solid #233963;
  background: #fff;
  color: #233963;
  font-family: 'Public Sans', sans-serif;
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 24px;
  transition: background 0.2s ease, color 0.2s ease;
}

.post-promo-card__btn:hover {
  background: #233963;
  color: #fff;
}

/* Two-button layout (Promo Card Content meta box — Button 2 filled in) */
.post-promo-card__btns {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.post-promo-card__btns .post-promo-card__btn {
  margin: 0;
}

/* Second button — filled by default, inverts on hover — so two stacked
   buttons read as primary/secondary instead of two identical outlines */
.post-promo-card__btn--secondary {
  background: #233963;
  color: #fff;
}

.post-promo-card__btn--secondary:hover {
  background: #fff;
  color: #233963;
}


/* ── 9. Article content typography ──────────────────────── */
.post-content {
  font-family: 'Public Sans', sans-serif;
  font-size: 16px;
  line-height: 24px;
  color: #1e2e4c;
}

.post-content > * + * { margin-top: 24px; }

.post-content p {
  font-size: 16px;
  line-height: 24px;
  color: #1e2e4c;
  margin: 0 0 24px;
}

.post-content h2 {
  font-family: 'Public Sans', sans-serif;
  font-size: 20px;
  font-weight: 600;
  line-height: 24px;
  color: #1e2e4c;
  margin: 40px 0 12px;
}

.post-content h3 {
  font-family: 'Public Sans', sans-serif;
  font-size: 18px;
  font-weight: 600;
  line-height: 24px;
  color: #1e2e4c;
  margin: 32px 0 12px;
}

.post-content h4 {
  font-family: 'Public Sans', sans-serif;
  font-size: 16px;
  font-weight: 600;
  color: #1e2e4c;
  margin: 24px 0 8px;
}

.post-content ol,
.post-content ul {
  margin: 0 0 24px;
  padding-left: 24px;
}

/* No `.post-content ul { list-style: disc }` here — content-body.css's
   .intone-content-body ul already sets list-style:none + a custom gold
   ::before dot (both classes are on the same element); re-declaring disc
   at equal specificity won this tie by loading later, rendering BOTH the
   native browser bullet and the custom gold dot on every <li>. */
.post-content ol { list-style: decimal; }

.post-content li {
  font-size: 16px;
  line-height: 24px;
  color: #1e2e4c;
  margin-bottom: 4px;
}

.post-content a {
  color: #233963;
  text-decoration: underline;
  transition: color 0.2s;
}

.post-content a:hover { color: #b07613; }

/* Blockquote — left border highlight (from Figma article-summary design) */
.post-content blockquote,
.post-content .wp-block-quote {
  border-left: 4px solid #233963;
  padding: 0 0 0 24px;
  margin: 40px 0;
  font-weight: 500;
  font-size: 16px;
  color: #1e2e4c;
}

.post-content blockquote p,
.post-content .wp-block-quote p {
  margin: 0;
}

.post-content img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 24px 0;
}

.post-content figure { margin: 24px 0; }

.post-content figcaption {
  font-size: 14px;
  color: #818994;
  margin-top: 8px;
}

.post-content pre,
.post-content code {
  font-family: 'Courier New', monospace;
  font-size: 14px;
  background: #f4f6f9;
  border-radius: 4px;
  padding: 2px 6px;
}

.post-content pre {
  padding: 20px 24px;
  overflow-x: auto;
  margin: 0 0 24px;
}

.post-content pre code {
  background: none;
  padding: 0;
}


/* ── 10. Related articles ──────────────────────────────────
   Removed: this page now reuses the "Articles" component
   (.res-* classes) from resources-page.css instead of
   maintaining a second, near-identical carousel build. ──── */


/* ── 11. Responsive ──────────────────────────────────────── */
@media (max-width: 1200px) {
  .post-sidebar {
    width: 300px;
  }
  .post-promo-card__heading {
    font-size: 24px;
  }
}

@media (max-width: 1024px) {
  .post-body {
    flex-direction: column;
  }
  /* Below the 2-column breakpoint, Figma wants TOC above the article and
     the EagleEye365 CTA below it — not grouped together as a sidebar unit.
     `display: contents` unwraps .post-sidebar so its two children become
     direct flex items of .post-body alongside .post-content, and `order`
     places them where Figma shows them, with no HTML restructuring needed. */
  .post-sidebar {
    display: contents;
  }
  .post-toc {
    order: 1;
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
  }
  .post-content {
    order: 2;
  }
  .post-promo-card {
    order: 3;
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
    /* The card's own width grows a lot at this tier (up to 640px, vs the
       375px-wide column Figma designed it at) — a shorter min-height keeps
       it from looking flat/stubby relative to its new width. */
    min-height: 460px;
  }
  /* Gated Download Form (.rdf-card) — the OTHER selectable promo-card
     template (see intone_promo_card_templates() in functions.php) — had no
     order assigned here, so it defaulted to order:0 and rendered BEFORE
     the TOC instead of after the article like .post-promo-card above.
     Same order:3/width/centering treatment; no min-height override since
     the form's height is already driven by its own fields, not a
     decorative card that needs padding out. */
  .rdf-card {
    order: 3;
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
  }
  .post-toc__link {
    max-width: 480px;
    white-space: normal;
  }
}

@media (max-width: 768px) {
  .intone-single-post .intone-breadcrumb {
    padding-left: 20px;
    padding-right: 20px;
  }
  .post-header { padding: 32px 20px 24px; }
  .post-header__title {
    font-size: 28px;
    line-height: 36px;
  }
  /* No .post-hero-image override needed here — its clamp(320px, 75vw,
     1080px) width + aspect-ratio already scale down smoothly on their
     own; a fixed height override here would fight the aspect-ratio. */
  .post-body { padding: 40px 20px 64px; }
  /* Card width now tracks the viewport (≤768px, under the 640px cap), close
     to the 375px column Figma designed the card at — restore most of the
     full-height treatment instead of the wider tablet tier's shorter one. */
  .post-promo-card {
    min-height: 500px;
  }
}

/* Same bounded-scrollable-trail technique already used for
   .intone-breadcrumb--over-hero on hero-led Pages (intone-design-system.css,
   same 640px cutoff) — single.php isn't hero-led so it never got that
   variant, but the underlying problem is identical: a long parent/title
   chain (Home / Resources / Case Studies / {long post title}) has an
   unpredictable wrapped height at narrow widths, and can wrap across 2-3
   cramped lines. Keeping it to one line that scrolls horizontally instead
   holds it to a single, predictable height and reads as an intentional
   swipeable trail rather than a layout break. */
@media (max-width: 640px) {
  .intone-single-post .intone-breadcrumb {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .intone-single-post .intone-breadcrumb::-webkit-scrollbar {
    display: none;
  }

  .intone-single-post .intone-breadcrumb .intone-breadcrumb__link,
  .intone-single-post .intone-breadcrumb .intone-breadcrumb__current {
    white-space: nowrap;
    flex: 0 0 auto;
  }
}


/* ── 12. Dark mode overrides ─────────────────────────────── */
[data-theme="dark"] .intone-single-post {
  background: var(--t-bg);
}

/* No dark override needed for .intone-breadcrumb here — it's the shared
   component (intone-design-system.css), which already handles dark mode
   for every other page that renders it. */

[data-theme="dark"] .post-header__author-name,
[data-theme="dark"] .post-header__title {
  color: var(--t-text);
}

[data-theme="dark"] .post-share-bar {
  background: var(--t-surface);
}

[data-theme="dark"] .post-share-bar__icon {
  color: var(--t-text);
}

[data-theme="dark"] .post-hero-image {
  background: var(--t-surface);
}

[data-theme="dark"] .post-toc__title {
  color: var(--t-text);
}

[data-theme="dark"] .post-toc__link {
  color: var(--t-text-muted);
}

[data-theme="dark"] .post-toc__link:hover {
  color: var(--ds-gold, #f6b43f);
}

[data-theme="dark"] .post-toc__item {
  border-left-color: var(--t-border-strong);
}

[data-theme="dark"] .post-toc__item.is-read {
  border-left-color: var(--ds-gold, #f6b43f);
}

[data-theme="dark"] .post-promo-card {
  background: var(--t-surface-raised);
  border-color: var(--t-border-strong);
}

[data-theme="dark"] .post-promo-card::before {
  display: none;
}

[data-theme="dark"] .post-promo-card__blob {
  opacity: 0.5;
}

[data-theme="dark"] .post-promo-card__heading {
  color: var(--t-text);
}

[data-theme="dark"] .post-promo-card__body,
[data-theme="dark"] .post-promo-card__tagline {
  color: var(--t-text-muted);
}

[data-theme="dark"] .post-promo-card__btn {
  background: var(--t-surface);
  border-color: var(--t-text);
  color: var(--t-text);
}

[data-theme="dark"] .post-promo-card__btn:hover {
  background: var(--t-text);
  color: var(--t-bg);
}

[data-theme="dark"] .post-content,
[data-theme="dark"] .post-content p,
[data-theme="dark"] .post-content h2,
[data-theme="dark"] .post-content h3,
[data-theme="dark"] .post-content h4,
[data-theme="dark"] .post-content li,
[data-theme="dark"] .post-content blockquote,
[data-theme="dark"] .post-content .wp-block-quote {
  color: var(--t-text);
}

[data-theme="dark"] .post-content a {
  color: var(--ds-gold, #f6b43f);
}

[data-theme="dark"] .post-content pre,
[data-theme="dark"] .post-content code {
  background: var(--t-surface);
}

/* .res-* dark-mode handling lives in resources-page.css, reused as-is */


/* ═══════════════════════════════════════════════════════════
   GATED DOWNLOAD FORM  (.rdf-*)
   Sidebar CTA "template" — one of the promo-card templates
   (template-parts/promo-cards/download-form.php). Sits in the same
   .post-sidebar slot as .post-promo-card, so it inherits the column
   width; fields stack full-width to read in the narrow column.
   ═══════════════════════════════════════════════════════════ */
.rdf-card {
  border: 1px solid #a5abb3;
  background: #fff;
  padding: 24px 22px;
  font-family: 'Public Sans', sans-serif;
}

.rdf-heading {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.3;
  color: #141414;
  margin: 0 0 8px;
}

.rdf-intro {
  font-size: 15px;
  line-height: 1.55;
  color: #333;
  margin: 0 0 18px;
}

.rdf-form { margin: 0; }

/* Honeypot — visually and semantically hidden from real users */
.rdf-hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.rdf-row { margin: 0 0 14px; }

.rdf-row--2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.rdf-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.rdf-group > label,
.rdf-fieldset > legend {
  font-size: 13px;
  font-weight: 600;
  color: #233963;
  padding: 0;
}

.rdf-req { color: #d33; }

.rdf-form input[type="text"],
.rdf-form input[type="email"],
.rdf-form select {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid #a5abb3;
  border-radius: 4px;
  background: #fff;
  color: #141414;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.4;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.rdf-form select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23233963' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 34px;
}

.rdf-form input::placeholder { color: #8a9099; }

.rdf-form input:focus,
.rdf-form select:focus {
  outline: none;
  border-color: #233963;
  box-shadow: 0 0 0 3px rgba(35, 57, 99, 0.15);
}

.rdf-form input.invalid,
.rdf-form select.invalid {
  border-color: #d33;
  box-shadow: 0 0 0 3px rgba(221, 51, 51, 0.12);
}

.rdf-fieldset {
  border: 0;
  margin: 0;
  padding: 0;
}

.rdf-fieldset.invalid > legend { color: #d33; }

.rdf-radios {
  display: flex;
  gap: 20px;
  margin-top: 8px;
}

.rdf-radio {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 15px;
  font-weight: 400;
  color: #141414;
  cursor: pointer;
}

.rdf-radio input { accent-color: #233963; width: 16px; height: 16px; }

.rdf-actions { margin: 20px 0 0; }

.rdf-submit {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 13px 18px;
  border: 2px solid #233963;
  background: #233963;
  color: #fff;
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  cursor: pointer;
  border-radius: 4px;
  transition: background 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.rdf-submit:hover { background: #fff; color: #233963; }

.rdf-submit:disabled,
.rdf-submit.loading {
  opacity: 0.75;
  cursor: default;
  background: #233963;
  color: #fff;
}

.rdf-spinner {
  display: none;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: rdf-spin 0.7s linear infinite;
}

.rdf-submit.loading .rdf-spinner { display: inline-block; }

@keyframes rdf-spin { to { transform: rotate(360deg); } }

.rdf-consent {
  font-size: 12px;
  line-height: 1.5;
  color: #6b7280;
  margin: 14px 0 0;
}

.rdf-consent a { color: #233963; text-decoration: underline; }

.rdf-status {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.5;
  border-radius: 4px;
}

.rdf-status.success {
  padding: 12px 14px;
  background: #e7f6ec;
  border: 1px solid #9bd6ac;
  color: #1a6b34;
}

.rdf-status.error {
  padding: 12px 14px;
  background: #fdecec;
  border: 1px solid #f0b4b4;
  color: #a12626;
}

/* Editor-only "not live yet" notice (no Document chosen) */
.rdf-card--notice {
  background: #fff8e5;
  border-color: #e8c766;
}
.rdf-card--notice p { margin: 0 0 6px; font-size: 14px; color: #6a5300; }
.rdf-card--notice p:last-child { margin-bottom: 0; }

/* ── Gated Download Form — dark mode ─────────────────────── */
[data-theme="dark"] .rdf-card {
  background: var(--t-surface-raised);
  border-color: var(--t-border-strong);
}

[data-theme="dark"] .rdf-heading { color: var(--t-text); }
[data-theme="dark"] .rdf-intro { color: var(--t-text-muted); }

[data-theme="dark"] .rdf-group > label,
[data-theme="dark"] .rdf-fieldset > legend {
  color: var(--t-text);
}

[data-theme="dark"] .rdf-form input[type="text"],
[data-theme="dark"] .rdf-form input[type="email"],
[data-theme="dark"] .rdf-form select {
  background: var(--t-surface);
  border-color: var(--t-border-strong);
  color: var(--t-text);
}

[data-theme="dark"] .rdf-form input::placeholder { color: var(--t-text-muted); }

[data-theme="dark"] .rdf-form input:focus,
[data-theme="dark"] .rdf-form select:focus {
  border-color: var(--ds-gold, #f6b43f);
  box-shadow: 0 0 0 3px rgba(246, 180, 63, 0.2);
}

[data-theme="dark"] .rdf-radio { color: var(--t-text); }
[data-theme="dark"] .rdf-radio input { accent-color: var(--ds-gold, #f6b43f); }

[data-theme="dark"] .rdf-submit {
  background: var(--ds-gold, #f6b43f);
  border-color: var(--ds-gold, #f6b43f);
  color: #1a1a1a;
}
[data-theme="dark"] .rdf-submit:hover {
  background: transparent;
  color: var(--ds-gold, #f6b43f);
}
[data-theme="dark"] .rdf-submit:disabled,
[data-theme="dark"] .rdf-submit.loading {
  background: var(--ds-gold, #f6b43f);
  color: #1a1a1a;
}
[data-theme="dark"] .rdf-spinner {
  border-color: rgba(26, 26, 26, 0.35);
  border-top-color: #1a1a1a;
}

[data-theme="dark"] .rdf-consent { color: var(--t-text-muted); }
[data-theme="dark"] .rdf-consent a { color: var(--ds-gold, #f6b43f); }

[data-theme="dark"] .rdf-status.success {
  background: rgba(45, 122, 62, 0.18);
  border-color: rgba(120, 200, 140, 0.5);
  color: #9be0af;
}
[data-theme="dark"] .rdf-status.error {
  background: rgba(160, 40, 40, 0.18);
  border-color: rgba(220, 120, 120, 0.5);
  color: #f2b3b3;
}

[data-theme="dark"] .rdf-card--notice {
  background: rgba(232, 199, 102, 0.12);
  border-color: var(--ds-gold, #f6b43f);
}
[data-theme="dark"] .rdf-card--notice p { color: var(--ds-gold, #f6b43f); }

/* Single-column fallback for very narrow sidebars */
@media (max-width: 400px) {
  .rdf-row--2col { grid-template-columns: 1fr; }
}

