/* ═══════════════════════════════════════════════════════════════════════════
   PYTHON & VBA — pythonandvba.com custom CSS
   Restructured 2026-08-02 · overhauled 2026-08-06 (underlined article links,
   sticky docs sidebars, mobile type fixes, brand tokens, print styles)

   TABLE OF CONTENTS
    1. Brand reference
    2. Global — layout, header & footer
    3. Global — buttons & text elements
    4. Navigation (mega menu, NEW! badge, Excel Solutions CTA)
    5. Video & media
    6. Shared components
    7. Pricing tables & ribbons
    8. Homepage
    9. Blog — archive & search
   10. Blog — single post
   11. Docs — BetterDocs UI
   12. Docs — .sven-docs article content
   13. Tool & solution pages
   14. Forms
   15. Page-specific overrides
   16. Legal pages
   17. Print
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   1. BRAND REFERENCE (colors used throughout this file)
   Primary blue   --pv-brand  #3772a3 · hover --pv-brand-hover  #265782
                                      · deep  --pv-brand-deep   #1B3851
   Accent yellow  --pv-accent #FFDC03 · hover --pv-accent-hover #FFF14D
   Brand tints stay as rgba(55, 114, 163, …) literals where an alpha is needed.
   Text grays     #1f2937 / #333 / #374151 / #4a4a4a / #555 / #666
   Muted / lines  #9ca3af / #d1d5db / #e5e7eb / #f3f4f6 / #f9fafb

   ── Article tokens ─────────────────────────────────────────────────────────
   Long-form body content appears in two places, docs (.sven-docs, section 12)
   and blog posts (.single-blog, section 10). They used to carry separate
   literal values for the same things and had drifted apart in ten places, so a
   doc and a post read as two different sites. Both now reference the tokens
   below; anything that still differs between them does so on purpose.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* text */
  --pv-text: #374151;           /* body copy */
  --pv-heading: #1f2937;        /* h2-h3 */
  --pv-heading-strong: #111827; /* h1, <strong> */
  --pv-heading-soft: #4b5563;   /* h5-h6 */
  --pv-muted: #6b7280;          /* captions, meta */

  /* surfaces & lines */
  --pv-rule: #e5e7eb;
  --pv-surface: #f9fafb;
  --pv-surface-alt: #f3f4f6;

  /* verdicts, for comparison tables */
  --pv-yes: #15803d;
  --pv-no: #b91c1c;

  /* brand */
  --pv-brand: #3772a3;
  --pv-brand-hover: #265782;
  --pv-brand-deep: #1B3851;
  --pv-accent: #FFDC03;
  --pv-accent-hover: #FFF14D;

  /* code */
  --pv-code-bg: #f3f4f6;
  --pv-code-text: #1f2937;      /* deliberately NOT red: most inline code in
                                   the docs is a button or sheet name, and red
                                   reads as an error */
  --pv-pre-bg: #1e293b;
  --pv-pre-text: #e2e8f0;
  /* System monospace only. Fira Code used to lead this stack but was never
     loaded as a webfont, so each OS silently rendered a different font. */
  --pv-mono: ui-monospace, 'SF Mono', Consolas, Menlo, monospace;

  /* rhythm */
  --pv-leading: 1.7;
  --pv-radius: 8px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   2. GLOBAL — LAYOUT, HEADER & FOOTER
   ═══════════════════════════════════════════════════════════════════════════ */

/* Prevent horizontal overflow on the Themify page wrapper.
   overflow-x: clip, NOT hidden: clip does not create a scroll container, so
   position: sticky keeps working inside (hidden silently killed every sticky
   sidebar and TOC on the site). display: flow-root keeps the block formatting
   context that overflow: hidden used to provide, so float containment and
   margin collapsing behave exactly as before. */
#body {
  display: flow-root;
  overflow-x: clip;
}

/* Header: hairline + soft shadow under the nav bar */
#headerwrap {
  border-bottom: 1px solid #ccc;
  box-shadow: 0 0.15em 0.35em 0 rgb(0 0 0 / 14%);
}

/* Footer: remove default spacing, tighten widgets */
#footerwrap {
  padding: 0em 0 0em;
  margin: 0em 0 0em;
}

.footer-widgets .widget {
  margin: 4%;
}

.footer-widgets-wrap {
  font-size: 0.8em !important;
}

/* Hide the first footer widget column */
.main-col.first.tf_clearfix {
  display: none;
}

/* NOTE: hides page titles SITE-WIDE (pages use Builder-made headings instead) */
.page-title {
  display: none;
}

/* Remove the 1px seam between colored section frames (Themify row frames) */
.tb_row_frame_wrap {
  inset-block: 0;
}

/* Compact list spacing on small screens (global) */
@media screen and (max-width: 680px) {
  ul li {
    line-height: 22px;
  }
  .fa-ul > li {
    display: inline-flex;
    margin-right: 2px !important;
  }
  .fa-ul > li i {
    padding-right: 20px;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   3. GLOBAL — BUTTONS & TEXT ELEMENTS
   ═══════════════════════════════════════════════════════════════════════════ */

/* Form submit buttons: brand blue */
input[type=reset], input[type=submit], button[type=submit] {
  background-color: var(--pv-brand);
}

input[type=reset]:hover, input[type=submit]:hover, button[type=submit]:hover {
  background-color: var(--pv-brand-deep);
}

/* Themify shortcode buttons */
a.shortcode.button {
  margin-top: -3%;
  border: none !important;
}

a.shortcode.button:hover {
  background: var(--pv-brand-deep) !important;
  border: none !important;
}

/* Small shortcode buttons keep their natural position (regular ones pull up
   -3% above). Class selector instead of the old exact attribute match, so it
   survives Themify reordering or extending the class list. */
.shortcode.button.small {
  margin-top: 0 !important;
}

/* Highlighted text */
mark {
  background-color: #FFECD1;
}


/* ═══════════════════════════════════════════════════════════════════════════
   4. NAVIGATION
   Desktop ≥1025px: mega menu (Fullwidth Columns on "Free Tools")
   Mobile  ≤1024px: accordion with category toggles
   ═══════════════════════════════════════════════════════════════════════════ */

#main-nav {
  padding-top: 2%;
}

/* ── "New!" badge (add CSS class "nav-new" to the item in Appearance > Menus) */
#main-nav li.nav-new {
  position: relative;
}

#main-nav li.nav-new > a::after {
  content: "New!";
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-10%) rotate(13deg);
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: #333;
  background: var(--pv-accent);
  border-radius: 999px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 5;
}

/* Mobile: flat inline pill instead of the tilted floating one */
@media (max-width: 1024px) {
  #main-nav li.nav-new > a::after {
    position: static;
    display: inline-block;
    top: auto;
    left: auto;
    transform: none;
    margin-left: 10px;
    padding: 3px 9px;
    font-size: 11px;
    vertical-align: middle;
  }
}

/* ── "Excel Solutions" CTA: yellow button style on the last nav item ──────── */
@media only screen and (min-width: 769px) {
  #main-nav > li:last-child > a {
    box-sizing: border-box;
    border-radius: 5px;
    padding: .5em 1em;
    background: var(--pv-accent);
    border: 3px solid var(--pv-accent);
    color: #333 !important;
    font-weight: bold !important;
    transition: background-color 0.15s linear, color 0.15s linear;
  }

  #main-nav > li:last-child > a:hover {
    background: var(--pv-accent-hover);
    color: #222 !important;
  }

  #main-nav > li:last-child > a:active {
    color: #fff !important;
  }
}

/* ── Mega menu ────────────────────────────────────────────────────────────── */

/* Tighter item text so wrapped labels read as one item */
#main-nav .has-mega .sub-menu a {
  line-height: 1.4;
}

/* Desktop: mega menu */
@media (min-width: 1025px) {

  /* Panel glides up as it fades in.
     visibility + pointer-events keep the CLOSED (invisible) panel from
     catching hovers — without them, mousing under the header re-opens it */
  #main-nav .has-mega > .sub-menu {
    visibility: hidden;
    pointer-events: none;
    transform: translateY(12px);
    transition: opacity .28s ease, transform .28s cubic-bezier(.21, 1.02, .55, 1), visibility .28s;
  }
  #main-nav .has-mega:hover > .sub-menu,
  #main-nav .has-mega:focus-within > .sub-menu {
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
  }

  /* Category headers (# links): gray label + yellow underline base */
  #main-nav .sub-menu a[href="#"] {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #9ca3af !important;
    pointer-events: none;
    cursor: default;
    margin-top: 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid #e5e7eb;
    background: linear-gradient(to right, var(--pv-accent), var(--pv-accent)) no-repeat 0 100% / 0 2px;
    transition: background-size .4s ease;
  }

  /* Yellow underline sweeps in, cascading left to right */
  #main-nav .has-mega:hover > .sub-menu a[href="#"] { background-size: 100% 2px; }
  #main-nav .has-mega:hover > .sub-menu > li:nth-child(2) a[href="#"] { transition-delay: .06s; }
  #main-nav .has-mega:hover > .sub-menu > li:nth-child(3) a[href="#"] { transition-delay: .12s; }
  #main-nav .has-mega:hover > .sub-menu > li:nth-child(4) a[href="#"] { transition-delay: .18s; }
  #main-nav .has-mega:hover > .sub-menu > li:nth-child(5) a[href="#"] { transition-delay: .24s; }

  /* Category icons: wiggle when hovering that column */
  #main-nav .sub-menu a[href="#"] svg.tf_fa {
    transform-origin: 50% 85%;
  }
  #main-nav .has-mega > .sub-menu > li:hover a[href="#"] svg.tf_fa {
    animation: pvaIconWiggle .5s ease-in-out;
  }

  /* Tool links: blue tint pill + gentle slide on hover */
  #main-nav .has-mega .sub-menu a:not([href="#"]) {
    border-radius: 6px;
    transition: color .15s ease, background-color .15s ease, transform .18s ease;
  }
  #main-nav .has-mega .sub-menu a:not([href="#"]):hover {
    color: var(--pv-brand);
    background-color: rgba(55, 114, 163, 0.06);
    transform: translateX(4px);
  }
}

/* Mobile: accordion */
@media (max-width: 1024px) {

  /* Category rows are toggles — style as tappable items */
  #main-nav .sub-menu a[href="#"] {
    font-weight: 600;
    color: #1f2937;
  }

  /* Chevron circle: light blue tint, brand-blue arrow, thicker bars */
  #main-nav .child-arrow {
    background: rgba(55, 114, 163, 0.08);
    color: var(--pv-brand);
  }
  #main-nav .child-arrow:before,
  #main-nav .child-arrow:after {
    height: 2px;
  }

  /* Open state (X): yellow circle + dark icon, matches NEW! pill */
  #main-nav .toggle-on > a > .child-arrow {
    background: var(--pv-accent);
    color: #333;
  }
}

/* Keyframes */
@keyframes pvaIconWiggle {
  0%, 100% { transform: rotate(0); }
  25%      { transform: rotate(-11deg); }
  55%      { transform: rotate(8deg); }
  80%      { transform: rotate(-4deg); }
}

/* Accessibility: respect reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  #main-nav .has-mega > .sub-menu,
  #main-nav .sub-menu a,
  #main-nav .sub-menu a svg.tf_fa {
    transition: none !important;
    transform: none !important;
    animation: none !important;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   5. VIDEO & MEDIA
   ═══════════════════════════════════════════════════════════════════════════ */

/* Rounded corners on all videos — page 5396 (WhatsAppBlaster) is the exception */
body:not(.page-id-5396) video,
body:not(.page-id-5396) .module-video {
  border-radius: 20px !important;
}

body:not(.page-id-5396) .video-wrap,
body:not(.page-id-5396) .video-wrap:hover {
  border-radius: 20px !important;
}

body:not(.page-id-5396) .tf_hide_controls .tf_video_wrap,
body:not(.page-id-5396) .tf_video_is_playing .tf_video_wrap {
  border-radius: 20px !important;
}

/* Hide the play-button icon on VideoPlayer modules with class "remove-icon" */
.remove-icon .tb_video_play {
  display: none;
}

/* Presto Player reusable embed: remove bottom gap */
.wp-block-presto-player-reusable-edit .wp-block-video {
  margin-bottom: 0px;
}

/* Bunny.net video iframes: round top corners only */
.bunnyIframe iframe {
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

/* Blog post embedded videos */
.single-blog .post-video iframe {
  border-radius: 10px;
}

/* Small demo videos on solution pages */
.demoVideos iframe {
  border-radius: 10px;
}

/* Tabbed videos on solution pages: round top corners only */
.solutionTab iframe {
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   6. SHARED COMPONENTS
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Yellow marker highlight (add class "pv-highlight" to text) ──────────── */
.pv-highlight {
  position: relative;
  display: inline;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  background-image: linear-gradient(to top, rgba(255, 220, 3, 0.4) 12px, transparent 12px);
  background-position: bottom;
  background-repeat: no-repeat;
}

@media (max-width: 768px) {
  /* Hide manual <br> in H1s so titles wrap naturally on mobile */
  h1 br {
    display: none;
  }

  /* Smaller highlight bar on mobile */
  .pv-highlight {
    background-image: linear-gradient(to top, rgba(255, 220, 3, 0.4) 8px, transparent 8px);
  }
}

/* ── Small helpers ───────────────────────────────────────────────────────── */

/* Hero image aligned right */
.hero-img-right img {
  float: right;
}

/* Muted note text (e.g. "Windows only" under download buttons) */
.platform-note {
  margin-top: 10px;
  font-size: 13px;
  color: var(--pv-muted);
  line-height: 1.4;
}

/* ── Testimonials ────────────────────────────────────────────────────────── */

/* Tighter bullet lists inside Themify testimonials */
.testimonial-content .testimonial-entry-content ul {
  margin: 8px 0;
  padding-left: 18px;
}

.testimonial-content .testimonial-entry-content ul li {
  margin: 2px 0;
  line-height: 1.3;
}

/* Scale-on-hover for review sliders (e.g. About page) */
.customSlider .slide-image img {
  transition: transform 0.3s ease-in-out;
}
.customSlider .slide-image img:hover {
  transform: scale(1.02);
}

.tf_swiper-slide .testimonial-item {
  transition: transform 0.3s ease;
}

.tf_swiper-slide .testimonial-item:hover {
  transform: scale(1.02);
}

/* ── Testimonial slider controls (Themify carousel) ──────────────────────── */

/* Keep arrows + dots on one line on mobile */
@media (max-width: 680px) {
  .module-testimonial-slider .carousel-nav-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: 10px;
    padding: 0;
  }
  .module-testimonial-slider .carousel-nav,
  .module-testimonial-slider .carousel-dots,
  .module-testimonial-slider .carousel-pager {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .module-testimonial-slider .carousel-nav::-webkit-scrollbar,
  .module-testimonial-slider .carousel-dots::-webkit-scrollbar,
  .module-testimonial-slider .carousel-pager::-webkit-scrollbar {
    display: none;
  }
  .module-testimonial-slider .carousel-nav li,
  .module-testimonial-slider .carousel-dots li,
  .module-testimonial-slider .carousel-pager li {
    flex: 0 0 auto;
  }
}

/* Round brand-blue arrow buttons */
.module-testimonial-slider .carousel-prev,
.module-testimonial-slider .carousel-next {
  background-color: var(--pv-brand);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color .2s;
  color: #fff;
  font-size: 20px;
}
.module-testimonial-slider .carousel-prev:hover,
.module-testimonial-slider .carousel-next:hover {
  background-color: var(--pv-brand-hover);
}

.module-testimonial-slider .carousel-prev i,
.module-testimonial-slider .carousel-next i {
  font-size: 20px;
  line-height: 1;
}

/* Image-bubble variant: push pagination down */
.module-testimonial-slider.image-bubble .carousel-nav-wrap {
  bottom: 0;
}

/* ── Social links ────────────────────────────────────────────────────────── */
.social-links .social-link-item em {
  border-radius: 10px !important;
  border: 1px solid var(--pv-brand) !important
}
.social-links .social-link-item:hover em {
  background-color: #fff !important;
  color: var(--pv-brand) !important;
  border: 1px solid var(--pv-brand) !important;
}

/* ── Keyboard focus ──────────────────────────────────────────────────────── */
/* The interactive pieces below give mouse users hover feedback;
   :focus-visible gives keyboard users the same signal without flashing a
   ring on ordinary mouse clicks. */
.post-filter a:focus-visible,
.post-filter span:focus-visible,
.sven-docs a:focus-visible,
.sven-docs summary:focus-visible,
.single-blog .ptb_post a:focus-visible,
.betterdocs-single-category-wrapper a:focus-visible {
  outline: 2px solid var(--pv-brand);
  outline-offset: 2px;
}

/* ── Popup modal (Magnific Popup) ────────────────────────────────────────── */
.mfp-content {
  border-radius: 10px !important;
}

/* ── Announcement bar / promo banner ─────────────────────────────────────── */
.promo-banner {
  text-align: center;
  font-size: 1rem;
}

.promo-button {
  display: inline-block;
  font-weight: 600;
  text-decoration: none;
}
.promo-button:hover {
  color: #6a6a6a;
}
.themify_announcement .toggle-close {
  background: var(--pv-brand);
  right: -50px;
}

@media only screen and (max-width: 768px) {
  .promo-banner {
    font-size: 14px;
    height: 15px !important;
  }
  .themify_announcement .toggle-close {
    background: var(--pv-brand);
    right: 60px;
  }
}

/* ── Buy Me a Coffee button ──────────────────────────────────────────────── */
.bmc-btn:hover {
  background: var(--pv-brand-deep) !important;
}

/* ── Feature chart circles (class "customFeature" on Builder module) ─────── */
.customFeature .chart-html5-circle {
  justify-content: flex-end;
}

@media (max-width: 768px) {
  .customFeature .chart-html5-circle {
    justify-content: center;
  }
}

/* ── Changelog (Simple Changelog plugin) ─────────────────────────────────── */
.version-tag {
  background-color: var(--pv-brand) !important;
}

/* ── FluentBoards roadmap ────────────────────────────────────────────────── */
.frm_ideas_filter .el-input .el-input__wrapper input {
  background: var(--frm-bg-secendary) !important;
}
/* NOTE: global selector — affects any Element-UI input, in practice only FluentBoards pages */
.el-input__inner {
  width: 100% !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   7. PRICING TABLES & RIBBONS
   ═══════════════════════════════════════════════════════════════════════════ */

/* No all-caps in pricing table headers */
.module-pricing-table-price {
  text-transform: none;
}

/* ── "Best Value" highlighted card ───────────────────────────────────────── */
.best-value {
  position: relative;
  border: 3px solid var(--pv-accent) !important;
  border-radius: 14px !important;
  box-shadow: 0 8px 30px rgba(0,0,0,.12);
  overflow: visible !important;
  z-index: 2;
}

.best-value::before {
  content: "Best Value";
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--pv-accent);
  color: #1a2e42;
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 4px 16px;
  border-radius: 20px;
  white-space: nowrap;
  z-index: 3;
}

/* ── Taglines under pricing table content ────────────────────────────────── */
.FreeInfo .module-pricing-table-content::after {
  content: "No credit card required";
  display: block;
  font-size: 14px;
  margin-top: 10px;
  text-align: center;
  white-space: pre-wrap;
}

.customPricing .module-pricing-table-content::after {
  content: "14-day money-back guarantee";
  display: block;
  font-size: 14px;
  margin-top: 10px;
  text-align: center;
  white-space: pre-wrap;
}

.onetimepayment .module-pricing-table-content::after {
  content: "Pay once. Use forever!";
  display: block;
  font-size: 14px;
  margin-top: 10px;
  text-align: center;
  white-space: pre-wrap;
}

/* "BUNDLE" pill on bundle cards */
.onetimepayment.bundle .module-pricing-table-content::before {
  content: "BUNDLE";
  display: inline-block;
  background-color: var(--pv-accent);
  color: #000;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  box-shadow: 0 0 0 2px var(--pv-brand);
}

/* ── Corner ribbon banners ───────────────────────────────────────────────── */
.free,
.bundle-version,
.free-lite-version,
.popular-version {
  position: relative;
  overflow: hidden;
}

.free::before,
.bundle-version::before,
.free-lite-version::before,
.popular-version::before {
  position: absolute;
  top: 30px;
  left: -70px;
  padding: 10px 0;
  width: 250px;
  text-align: center;
  font-size: 18px;
  font-weight: bold;
  background: var(--pv-accent);
  color: #333333;
  transform: rotate(-45deg);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: background-color 0.3s;
}

/* Individual ribbon labels */
.free::before              { content: "Free"; }
.bundle-version::before    { content: "Bundle Deal"; z-index: 1; }
.free-lite-version::before { content: "Free Lite Version"; font-size: 16px; }
.popular-version::before   { content: "Popular"; background: var(--pv-brand); color: #FFFFFF; }


/* ═══════════════════════════════════════════════════════════════════════════
   8. HOMEPAGE
   ═══════════════════════════════════════════════════════════════════════════ */

/* Feature icons: fill blue on hover (class "home-feature-icon" on module) */
.home-feature-icon:hover .module-feature-chart-html5 {
  background-color: var(--pv-brand) !important;
  transition: background-color 0.3s ease;
}

.home-feature-icon:hover .module-feature-icon {
  color: #ffffff !important;
  transition: color 0.3s ease;
}


/* ═══════════════════════════════════════════════════════════════════════════
   9. BLOG — ARCHIVE & SEARCH
   ═══════════════════════════════════════════════════════════════════════════ */

/* More whitespace left/right of archive content */
.post-content {
  padding: 0 5%;
}

/* ── Post cards (4-column grid) ──────────────────────────────────────────── */
/* Themify's .boxed loop pads the whole card by 10px, which reads as a white
   margin around the thumbnail. The padding moves to .post-content below so the
   image can reach the card edges. */
.loops-wrapper.blog.grid4 .post {
  background: #ffffff !important;
  border: 1px solid #e5e7eb !important;
  border-radius: 12px !important;
  overflow: hidden !important;
  padding: 0 !important;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1) !important;
  transition: transform 0.3s ease, box-shadow 0.3s ease !important;
}

/* Thumbnail full-bleed: no gap left, right or top. Its top corners are clipped
   by the card's own radius, hence the overflow: hidden above. */
.loops-wrapper.blog.grid4 .post .post-image,
.loops-wrapper.blog.grid4 .post .post-image > a {
  display: block;
  margin: 0;
}

.loops-wrapper.blog.grid4 .post .post-image img {
  display: block;
  width: 100%;
  border-radius: 0;
  transition: transform 0.3s ease !important;
}

/* The inset the card gave up, applied to the text only */
.loops-wrapper.blog.grid4 .post .post-content {
  padding: 16px 18px;
}

.loops-wrapper.blog.grid4 .post:hover {
  border-color: var(--pv-brand) !important;
  box-shadow: 0 8px 24px rgba(55, 114, 163, 0.15) !important;
  transform: translateY(-4px) scale(1.03) !important;
}

.loops-wrapper.blog.grid4 .post:hover .post-image img {
  transform: scale(1.05) !important;
}

/* Consistent title height across cards. Three lines is what the longest titles
   actually run to at desktop width; the old 90px reserved nearly five, so every
   card carried a block of empty space under its title. A longer title still
   grows past this — the wrapper is masonry, so a taller card packs rather than
   leaving a hole. */
.loops-wrapper.blog.grid4 .post-title,
.loops-wrapper.blog.grid4 .ptb_post_title {
  min-height: 3.6em; /* fallback: 3 lines at the theme's 1.2 line-height */
  min-height: 3lh;
}

/* Narrow screens: titles nearly all fit two lines, so reserving a third would
   put back the empty space this is trying to avoid. Masonry packs the uneven
   cards instead. */
@media (max-width: 768px) {
  .loops-wrapper.blog.grid4 .post-title,
  .loops-wrapper.blog.grid4 .ptb_post_title {
    min-height: 0;
  }
}

.loops-wrapper.blog.grid4 .post:hover .post-title a,
.loops-wrapper.blog.grid4 .post:hover .ptb_post_title a {
  color: var(--pv-brand) !important;
}

/* ── Category filter pills ───────────────────────────────────────────────── */
.post-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  padding: 0;
  margin: 0 auto 40px;
  background: none;
  border: none;
  border-radius: 0;
  transition: none !important;
}
.post-filter a,
.post-filter span {
  padding: 8px 18px;
  border: 1px solid #d1d5db;
  background: #ffffff;
  border-radius: 6px;
  font-weight: 500;
  font-size: 14px;
  color: #374151;
  text-decoration: none;
  transition: all 0.15s;
  cursor: pointer;
}
.post-filter a:hover,
.post-filter span:hover {
  border-color: var(--pv-brand);
  color: var(--pv-brand);
  background: #e8f4fc;
}
.post-filter a.active,
.post-filter span.active,
.post-filter a.current,
.post-filter span.current {
  background: var(--pv-brand);
  border-color: var(--pv-brand);
  color: #ffffff;
}

/* ── Blog search box ─────────────────────────────────────────────────────── */
.ptb_search_module {
  max-width: 500px;
  margin: 0 auto 30px;
}

.ptb_search_module .ptb_search_label {
  display: none;
}

.ptb_search_module input[type="text"] {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 14px;
  color: #374151;
  background: #ffffff;
}

.ptb_search_module input[type="text"]:focus {
  border-color: var(--pv-brand);
  outline: none;
  box-shadow: 0 0 0 3px rgba(55, 114, 163, 0.1);
}

.ptb_search_module input[type="text"]::placeholder {
  color: #9ca3af;
}

/* ── Search results grid (PTB archive template) ──────────────────────────── */
/* NOTE: CSS-generated text is not a real heading (invisible to SEO, weak for
   screen readers). The proper fix is a heading in the PTB archive template on
   the WordPress side; this stays until that exists. */
.ptb_loops_wrapper.ptb_grid4::before {
  content: "Search Results";
  display: block;
  font-size: 2rem;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin-bottom: 1rem;
  width: 100%;
}

.ptb_loops_wrapper.ptb_grid4 {
  position: relative;
  padding-top: 1rem;
  margin-top: 1rem;
}

.ptb_loops_wrapper .ptb_post {
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  border-radius: 12px;
  overflow: hidden;
}

.ptb_loops_wrapper .ptb_post:hover {
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  transform: scale(1.03);
}

div.ptb_loops_wrapper:not(.ptb_masonry) > .ptb_post {
  box-shadow: 0 5px 15px rgb(0 0 0 / 10%);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  border-radius: 12px;
  overflow: hidden;
}

.ptb_loops_wrapper.ptb_grid4 .ptb_module.ptb_title.tf_clearfix {
  box-sizing: border-box;
  padding: .2em 7% .4em;
}

.ptb_loops_wrapper.ptb_grid4 .ptb_post_title a {
  font-size: 1em;
  color: #4a4a4a;
  font-weight: bold;
}

/* More whitespace under the category field on archive cards. :where() keeps
   specificity flat so the .blogMetarow reset (section 10) still wins on
   single posts; the :not excludes that meta row's inline category anyway. */
.ptb_module.ptb_category:where(:not(.ptb_module_inline)) {
  margin-bottom: 5% !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   10. BLOG — SINGLE POST (.single-blog)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Headings & text ─────────────────────────────────────────────────────── */
/* Sizes stay larger than the docs (a post is a page's main content, a doc sits
   inside a sidebar layout), but the colours and rhythm come from the shared
   article tokens in section 1. */

/* Themify capitalizes bare h1-h4, which retitles every heading on the page
   regardless of what was written. Same fix as docs (section 12). */
.single-blog h2,
.single-blog h3,
.single-blog h4,
.single-blog h5,
.single-blog h6 {
  text-transform: none;
}

.single-blog h2 {
  line-height: 1.3em;
  margin-top: 1.5em;
  margin-bottom: 0.5em;
  font-size: 1.75em;
  font-weight: 700;
  color: var(--pv-heading);
}

.single-blog h3 {
  line-height: 1.4em;
  margin-top: 0.9em;
  margin-bottom: 0.4em;
  font-size: 1.5em;
  font-weight: 600;
  color: var(--pv-heading);
}

.single-blog h4 {
  line-height: 1.5em;
  margin-top: 0.8em;
  margin-bottom: 0.3em;
  font-size: 1.3em;
  font-weight: 600;
  color: var(--pv-text);
}

.single-blog p {
  line-height: var(--pv-leading);
  font-size: 1em;
  color: var(--pv-text);
  margin-bottom: 0.8em;
}

.single-blog strong {
  font-weight: 600;
  color: var(--pv-heading-strong);
}

.single-blog div#custom-footer p {
  line-height: inherit;
}

.single-blog ul li,
.single-blog ol li {
  color: var(--pv-text);
  margin-bottom: 0.5em;
  padding-left: 1em;
  line-height: 1.5em;
}

/* ── Content links ───────────────────────────────────────────────────────── */
/* Scoped to the article (.ptb_post) so nav, footer and widget links stay
   untouched. Underlined, not color-only: the link blue and the body gray sit
   at ~1.1:1 contrast against each other, so without an underline links are
   invisible to color-blind readers (WCAG 1.4.1) and undiscoverable on touch
   screens, where hover never fires. Same treatment as docs links (section 12).
   :where() keeps the exclusions from raising specificity, so the TOC box and
   shortcode-button rules still win where they apply. */
.single-blog .ptb_post a:where(:not(.shortcode):not(.button)) {
  color: var(--pv-brand);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--pv-brand) 35%, transparent);
  text-underline-offset: 0.15em;
  transition: text-decoration-color 0.2s ease;
}

.single-blog .ptb_post a:where(:not(.shortcode):not(.button)):hover {
  text-decoration-color: var(--pv-brand);
}

/* Category & author links in the meta row read as labels, not prose links */
.single-blog .blogMetarow a {
  text-decoration: none;
}

/* Post title & category meta */
.single-blog-title {
  line-height: 1.1em;
}

.single-blog-category {
  margin-top: -10px;
  padding-bottom: 50px;
}
@media screen and (max-width: 768px) {
  .single-blog-category {
    padding-bottom: 20px;
  }
}

/* ── Tables ──────────────────────────────────────────────────────────────── */
/* #body is overflow:hidden, so a wide table would be clipped rather than
   scrollable. Same treatment as docs. */
.single-blog table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5em 0;
  font-size: 0.95em;
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.single-blog th {
  background-color: var(--pv-text);
  color: #ffffff;
  font-weight: 600;
  text-align: left;
  padding: 0.75em 1em;
  border: 1px solid var(--pv-text);
}

.single-blog td {
  padding: 0.75em 1em;
  border: 1px solid var(--pv-rule);
  vertical-align: top;
  color: var(--pv-text);
}

.single-blog tr:nth-child(even) {
  background-color: var(--pv-surface);
}

.single-blog tr:hover {
  background-color: var(--pv-surface-alt);
}

/* ── Images (logos excluded below — keep these two rules together) ───────── */
.single-blog img {
  border-radius: 10px;
  border: 2px solid rgba(0, 0, 0, 0.1);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  max-width: 100%;
  height: auto;
  margin-bottom: 1em;
}

#site-logo img,
.footer-logo img,
.mytoolbelt-img img {
  border: none;
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 0;
}

/* ── Blockquotes ─────────────────────────────────────────────────────────── */
.single-blog blockquote {
  border-left: 4px solid #d1d5db;
  margin: 1.5em 0;
  padding: 0.75em 1.25em;
  background-color: var(--pv-surface);
  border-radius: 0 var(--pv-radius) var(--pv-radius) 0;
  color: var(--pv-heading-soft);
  font-style: italic;
}

.single-blog blockquote p {
  margin: 0;
}

/* ── Code ────────────────────────────────────────────────────────────────── */
.single-blog code {
  background-color: var(--pv-code-bg);
  color: var(--pv-code-text);
  font-family: var(--pv-mono);
  font-size: 0.875em;
  padding: 0.15em 0.4em;
  border-radius: 4px;
  border: 1px solid var(--pv-rule);
}

.single-blog pre code {
  background-color: transparent;
  color: inherit;
  padding: 0;
  border: none;
  border-radius: 0;
  font-size: 0.875em;
  line-height: 1.6;
}

.single-blog pre {
  position: relative;
  background-color: var(--pv-pre-bg);
  color: var(--pv-pre-text);
  font-family: var(--pv-mono);
  padding: 1em 1.25em;
  border-radius: var(--pv-radius);
  overflow-x: auto;
  border: 1px solid #334155;
  margin-bottom: 0.8em;
}

/* ── Copy button on code blocks (blog and docs) ──────────────────────────────
   scripts/site.js wraps every styled <pre> in .pv-code and appends .pv-copy.
   The button is positioned against the WRAPPER, not the <pre>: both selectors
   set overflow-x: auto, so a button inside would scroll out of sight on any
   block wide enough to need scrolling.

   Visible by default rather than hover-only. Hover does not exist on touch,
   and roughly half the traffic here is on a phone, so a hover-reveal button
   would simply not exist for them. Dimmed to 0.6 so it stays out of the way
   while reading, full strength on hover and on keyboard focus. */
.pv-code {
  position: relative;
}

.pv-copy {
  position: absolute;
  top: 0.5em;
  right: 0.5em;
  z-index: 2;
  padding: 0.35em 0.7em;
  min-height: 32px; /* touch target */
  font-family: var(--pv-mono);
  font-size: 0.75rem;
  line-height: 1.2;
  color: var(--pv-pre-text);
  background-color: #334155;
  border: 1px solid #475569;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}

.pv-code:hover .pv-copy,
.pv-copy:hover,
.pv-copy:focus-visible {
  opacity: 1;
}

.pv-copy:hover {
  background-color: #475569;
}

.pv-copy:focus-visible {
  outline: 2px solid var(--pv-brand);
  outline-offset: 2px;
}

.pv-copy[data-state="done"] {
  opacity: 1;
  color: #052e16;
  background-color: #86efac;
  border-color: #86efac;
}

.pv-copy[data-state="fail"] {
  opacity: 1;
  background-color: #7f1d1d;
  border-color: #991b1b;
}

@media (prefers-reduced-motion: reduce) {
  .pv-copy {
    transition: none;
  }
}

/* ── Syntax highlighting (Prism tokens) ──────────────────────────────────────
   No Prism theme stylesheet is loaded; these are the only token rules, so the
   colours are ours and stay in step with the rest of the palette. Prism core
   injects no CSS of its own, only the grammars.

   Languages are decided at build time by tools/tag_code_languages.py and land
   in the HTML as class="language-python|visual-basic|bash|json". A block with
   no such class is not code (mail-merge templates, sample data, file paths)
   and correctly renders as plain text on the same dark background.

   Hues are the 300-weight steps of the slate-family palette already in use, so
   every one clears WCAG AA against --pv-pre-bg without shouting.

   Every selector below is scoped to `pre` BECAUSE of that last sentence: the
   colours are only legible on the dark block background, and an unscoped
   `.token` rule also paints inline <code> sitting in white prose. One post
   shipped an inline <code class="language-visual-basic"> and its string token
   rendered #86efac on white at 1.40:1, the punctuation at 1.48:1, against the
   4.5:1 AA needs. The same rule's `background: none` had stripped the chip
   background that would have saved it. Inline code carries no language class
   anywhere else in the corpus (685 plain <code> against that one), and
   tag_code_languages.py only ever writes inside <pre>, so scoping here costs
   nothing and closes the hole for good. */
/* Only the <code> gets background:none. Putting it on the <pre> as well, the
   way a stock Prism theme does, is wrong here: a stock theme paints the dark
   background itself, ours comes from `.single-blog pre`, and
   pre[class*="language-"] outranks that selector. The result was highlighted
   blocks losing their background and rendering on white. */
.single-blog pre code[class*="language-"],
.sven-docs pre code[class*="language-"] {
  color: inherit;
  background: none;
  text-shadow: none;
}

.single-blog pre .token.comment,
.single-blog pre .token.prolog,
.single-blog pre .token.doctype,
.single-blog pre .token.cdata,
.sven-docs pre .token.comment,
.sven-docs pre .token.prolog,
.sven-docs pre .token.doctype,
.sven-docs pre .token.cdata {
  color: #94a3b8;
  font-style: italic;
}

.single-blog pre .token.punctuation,
.sven-docs pre .token.punctuation {
  color: #cbd5e1;
}

.single-blog pre .token.string,
.single-blog pre .token.char,
.single-blog pre .token.attr-value,
.single-blog pre .token.regex,
.sven-docs pre .token.string,
.sven-docs pre .token.char,
.sven-docs pre .token.attr-value,
.sven-docs pre .token.regex {
  color: #86efac;
}

.single-blog pre .token.keyword,
.single-blog pre .token.control,
.single-blog pre .token.atrule,
.single-blog pre .token.important,
.sven-docs pre .token.keyword,
.sven-docs pre .token.control,
.sven-docs pre .token.atrule,
.sven-docs pre .token.important {
  color: #c4b5fd;
}

.single-blog pre .token.function,
.single-blog pre .token.class-name,
.sven-docs pre .token.function,
.sven-docs pre .token.class-name {
  color: #93c5fd;
}

.single-blog pre .token.number,
.single-blog pre .token.boolean,
.single-blog pre .token.constant,
.single-blog pre .token.symbol,
.sven-docs pre .token.number,
.sven-docs pre .token.boolean,
.sven-docs pre .token.constant,
.sven-docs pre .token.symbol {
  color: #fdba74;
}

.single-blog pre .token.builtin,
.single-blog pre .token.property,
.single-blog pre .token.attr-name,
.single-blog pre .token.variable,
.sven-docs pre .token.builtin,
.sven-docs pre .token.property,
.sven-docs pre .token.attr-name,
.sven-docs pre .token.variable {
  color: #7dd3fc;
}

.single-blog pre .token.operator,
.sven-docs pre .token.operator {
  color: #e2e8f0;
}

/* Prism's bash grammar marks the leading $ of a prompt. It is not part of the
   command, and the copy button strips it, so it is dimmed to match. */
.single-blog pre .token.shell-symbol,
.sven-docs pre .token.shell-symbol {
  color: #94a3b8;
}

.single-blog pre .token.italic,
.sven-docs pre .token.italic {
  font-style: italic;
}

.single-blog pre .token.bold,
.sven-docs pre .token.bold {
  font-weight: 600;
}

/* ── Table of contents box ───────────────────────────────────────────────── */
.single-blog .toc-box {
  background-color: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  padding: 1.25em 1.5em;
  margin: 1.5em 0;
}

.single-blog .toc-box .toc-title {
  font-size: 1.1em;
  font-weight: bold;
  color: #333;
  margin-bottom: 0.5em;
}

.single-blog .toc-box ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
}

.single-blog .toc-box ul li {
  padding-left: 0;
  margin-bottom: 0.35em;
  line-height: 1.4em;
}

.single-blog .toc-box ul li a {
  color: #374151;
  text-decoration: none;
  font-size: 0.95em;
}

.single-blog .toc-box ul li a:hover {
  color: #111;
  text-decoration: underline;
}

/* ── tl;dr summary box ───────────────────────────────────────────────────────
   The first paragraph is what a search engine quotes and what an LLM reads
   before deciding whether the page answers anything. 74 of 174 posts opened
   with "In this tutorial, I'll guide you through the process of...", which
   answers nothing, while the highest-traffic post on the site opens by naming
   the actual cause of the error in 26 words.

   So this box holds the ANSWER, not a promise of one: if the rest of the post
   were deleted it should still be worth reading. Left rule rather than a full
   card, so it reads as part of the article instead of an interruption.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Comparison-table verdict marks ──────────────────────────────────────────
   Three posts built their comparison tables from Font Awesome <i> icons, but
   only ONE of them loaded the Font Awesome stylesheet and the theme does not
   load it either. On the other two every tick and cross rendered as nothing:
   the tables still read, because each cell also carries a word, but the
   at-a-glance column of green and red was simply absent.

   Replaced with the characters the house style already allows (see
   ALLOWED_NON_ASCII in tools/blog_common.py). That deletes a render-blocking
   CDN request from the article body, works with no stylesheet at all, and is
   readable by a screen reader, which a decorative <i> is not.

   Shape and colour carry SEPARATE meanings and both had to survive: in the
   data-entry-form comparison a green cross means "no coding required" (good)
   and a red tick means "yes, VBA required" (bad). So the mark is the shape and
   the class is the verdict, never assumed from one another.
   ────────────────────────────────────────────────────────────────────────── */
.single-blog .pv-yes,
.single-blog .pv-no,
.single-blog .pv-arrow {
  font-style: normal;
  font-weight: 700;
  margin-right: 0.15em;
}

.single-blog .pv-yes   { color: var(--pv-yes); }
.single-blog .pv-no    { color: var(--pv-no); }
.single-blog .pv-arrow { color: var(--pv-brand); }

.single-blog .pv-tldr {
  background-color: var(--pv-surface);
  border-left: 4px solid var(--pv-brand);
  border-radius: 0 var(--pv-radius) var(--pv-radius) 0;
  padding: 1em 1.35em;
  margin: 0 0 1.75em;
}

.single-blog .pv-tldr p {
  margin: 0;
  color: var(--pv-text);
}

/* "tl;dr" set in the brand blue and small caps rather than as a heading: it is
   a label on a paragraph, not a section, and must stay out of the document
   outline so it cannot compete with the h2s for the page structure. */
.single-blog .pv-tldr p::before {
  content: "tl;dr";
  display: inline;
  margin-right: 0.5em;
  color: var(--pv-brand);
  font-weight: 700;
  font-variant: all-small-caps;
  letter-spacing: 0.04em;
}

/* ── Product call to action ──────────────────────────────────────────────────
   For posts that demo one of the site's own tools. A reader who has just
   watched the thing work is the one most likely to want it, and making them
   hunt the nav for it helps nobody.

   Deliberately ONE box with ONE button. Two calls to action compete and the
   reader takes neither, and a wall of product boxes at the end of every post
   is the thing that makes a blog feel like a funnel instead of a resource.
   ────────────────────────────────────────────────────────────────────────── */
.single-blog .pv-cta {
  display: flex;
  align-items: center;
  gap: 1.25em;
  background-color: var(--pv-surface);
  border: 1px solid var(--pv-rule);
  border-radius: var(--pv-radius);
  padding: 1.25em 1.5em;
  margin: 2em 0;
}

.single-blog .pv-cta-body {
  flex: 1 1 auto;
  min-width: 0;
}

.single-blog .pv-cta-title {
  display: block;
  font-weight: 700;
  color: var(--pv-heading);
  margin-bottom: 0.2em;
}

.single-blog .pv-cta p {
  margin: 0;
  font-size: 0.95em;
  color: var(--pv-muted);
}

/* The button is an <a>, so the generic in-article link rule in section 10
   would give it an underline and the body link colour. Overridden here rather
   than by adding a class to the shared rule, which would leak into docs. */
.single-blog .pv-cta a.pv-cta-btn,
.single-blog .ptb_post a.pv-cta-btn {
  flex: 0 0 auto;
  display: inline-block;
  /* The theme has no global border-box, so the stacked width:100% below
     resolved to 100% PLUS 2.8em of horizontal padding and the button hung off
     the right edge of the card on every phone. */
  box-sizing: border-box;
  max-width: 100%;
  background-color: var(--pv-brand);
  color: #fff;
  border-bottom: none;
  padding: 0.65em 1.4em;
  border-radius: var(--pv-radius);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease;
}

.single-blog .pv-cta a.pv-cta-btn:hover,
.single-blog .ptb_post a.pv-cta-btn:hover {
  background-color: var(--pv-brand-hover);
  color: #fff;
  text-decoration: none;
}

/* Stacking below ~520px: side by side, the button squeezes the text to two
   words per line long before the viewport runs out. */
@media (max-width: 520px) {
  .single-blog .pv-cta {
    display: block;
  }
  .single-blog .pv-cta a.pv-cta-btn {
    margin-top: 1em;
    width: 100%;
    text-align: center;
  }
}

/* ── Category & author meta row ──────────────────────────────────────────── */
.blogMetarow {
  display: flex !important;
  flex-wrap: nowrap !important;
  justify-content: flex-start !important;
  align-items: center !important;
  gap: 10px;
  padding-bottom: 10px !important;
}
.blogMetarow > .ptb_col {
  width: auto !important;
  flex: 0 0 auto !important;
  max-width: none !important;
  padding: 0 5px !important;
  float: none !important;
}
.blogMetarow::after,
.blogMetarow > .ptb_col::after {
  display: none !important;
}
.blogMetarow .ptb_module {
  margin: 0 !important;
  padding: 0 !important;
}

@media (max-width: 768px) {
  .blogMetarow {
    flex-wrap: wrap !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 4px;
  }
  .blogMetarow > .ptb_col {
    width: 100% !important;
    flex: 0 0 100% !important;
  }
}

/* ── Mobile typography ───────────────────────────────────────────────────── */
/* Same 768px breakpoint as the docs (section 12), so a post and a doc switch
   to their phone styles together — they used to split at 600 vs 768 and
   behave differently in between. Body copy keeps its full size on purpose:
   16px is the readability floor on phones (the old 0.9em landed at 14.4px),
   and pre keeps its size so the pre code 0.875em is not compounded by a
   second shrink. Table size matches the docs' mobile 0.9em. */
@media only screen and (max-width: 768px) {
  .single-blog h1 {
    font-size: 1.8em;
    line-height: 1.1em;
  }

  .single-blog h2 {
    font-size: 1.5em;
    margin-top: 1em;
  }

  .single-blog h3 {
    font-size: 1.3em;
    margin-top: 0.7em;
  }

  .single-blog h4 {
    font-size: 1.1em;
    margin-top: 0.6em;
  }

  .single-blog pre {
    padding: 0.9em;
  }

  .single-blog table {
    font-size: 0.9em;
  }

  .single-blog th,
  .single-blog td {
    padding: 0.5em 0.75em;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   11. DOCS — BETTERDOCS UI
   ═══════════════════════════════════════════════════════════════════════════ */

.betterdocs-entry-title {
  margin-bottom: 20px !important;
  padding-bottom: 0 !important;
}

/* KB category grid: proper grid layout */
.betterdocs-category-box-inner-wrapper {
  display: grid !important;
}

/* ── Category cards ──────────────────────────────────────────────────────── */
.betterdocs-category-box-wrapper .betterdocs-single-category-wrapper,
.betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper {
  background: #ffffff !important;
  border: 1px solid #e5e7eb !important;
  border-radius: 8px !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06) !important;
  transition: all 0.2s ease !important;
  display: flex !important;
  min-height: 60px !important;
}

.betterdocs-category-box-wrapper .betterdocs-single-category-wrapper:hover,
.betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper:hover {
  background: rgba(55, 114, 163, 0.05) !important;
  border-color: var(--pv-brand) !important;
  box-shadow: 0 4px 12px rgba(55, 114, 163, 0.15) !important;
  transform: translateY(-2px) !important;
}

.betterdocs-category-box-wrapper .betterdocs-single-category-wrapper .betterdocs-category-title,
.betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper .betterdocs-category-title {
  color: #1f2937 !important;
  transition: color 0.2s ease !important;
  margin: 0 !important;
  padding: 0 !important;
}

.betterdocs-category-box-wrapper .betterdocs-single-category-wrapper:hover .betterdocs-category-title,
.betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper:hover .betterdocs-category-title {
  color: var(--pv-brand) !important;
}

.betterdocs-category-box-wrapper,
.betterdocs-category-grid-wrapper {
  background: transparent !important;
}

.betterdocs-category-box-wrapper .betterdocs-single-category-wrapper .betterdocs-category-box-inner-wrapper,
.betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper .betterdocs-category-box-inner-wrapper {
  display: flex !important;
  align-items: center !important;
  width: 100% !important;
}

/* ── Mobile adjustments ──────────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* Hide TOC icon (keeps "View Categories" sidebar icon) */
  .betterdocs-toc-icon {
    display: none !important;
  }

  /* Tighter Builder rows inside docs content */
  .betterdocs-content .row_inner,
  .betterdocs-content .module_column {
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }

  /* Hide search bar on single doc pages */
  .betterdocs-single-wrapper .betterdocs-search-form-wrapper {
    display: none !important;
  }

  /* Smaller card titles */
  .betterdocs-category-box-wrapper .betterdocs-single-category-wrapper .betterdocs-category-title,
  .betterdocs-category-grid-wrapper .betterdocs-single-category-wrapper .betterdocs-category-title {
    font-size: 16px !important;
  }

  /* Single column on mobile — override last-item fix */
  .betterdocs-category-box-inner-wrapper.docs-col-3 .betterdocs-single-category-wrapper:last-child {
    flex: 0 0 100% !important;
    max-width: 100% !important;
  }
}

/* ── Docs archive (/docs/): hide search, show "Documentation" title ──────── */
body.post-type-archive-docs .betterdocs-search-form-wrapper .betterdocs-live-search,
body.post-type-archive-docs .betterdocs-search-form-wrapper form.betterdocs-searchform {
  display: none;
}

body.post-type-archive-docs .betterdocs-search-form-wrapper {
  padding-top: 32px !important;
  padding-bottom: 32px !important;
  margin-bottom: 24px;
  text-align: center;
}

/* NOTE: CSS-generated text is not a real heading — the docs landing page has
   no h1 for SEO or screen readers. The proper fix is a real heading in the
   BetterDocs archive template (WordPress side); this stays until that exists. */
body.post-type-archive-docs .betterdocs-search-form-wrapper::before {
  content: "Documentation";
  display: block;
  font-size: clamp(26px, 6vw, 48px);
  line-height: 1.15;
  font-weight: 900;
  text-align: center;
}

body.post-type-archive-docs .betterdocs-search-form-wrap {
  min-height: 0;
}

/* The card grid sits inside fixed padding that never shrinks: 32px below the
   title band (ours) plus BetterDocs' own 50px above the cards, and 120px below
   them before the footer. Against the 48px desktop title that reads as
   balanced, which is why it went unnoticed — but the title clamps down to 26px
   on a phone and the padding does not, so the 83px lead-in ends up three times
   the height of the heading it separates and pushes a card below the fold,
   while the 120px tail leaves the last card stranded above the footer band.
   Scale all three with the viewport, the same way the title itself does. */
@media (max-width: 768px) {
  body.post-type-archive-docs .betterdocs-search-form-wrapper {
    padding-top: clamp(20px, 4vw, 32px) !important;
    padding-bottom: clamp(14px, 2.5vw, 24px) !important;
  }

  body.post-type-archive-docs .betterdocs-content-wrapper {
    padding-top: clamp(16px, 3vw, 28px) !important;
    padding-bottom: clamp(32px, 7vw, 56px) !important;
  }
}

/* ── Sticky sidebars (desktop) ───────────────────────────────────────────── */
/* On a long doc the category tree and the TOC follow the reader instead of
   scrolling out of view. Requires #body overflow-x: clip (section 2) —
   position: sticky is dead inside an overflow: hidden ancestor. Each column
   caps its height and scrolls internally when taller than the viewport. */
@media (min-width: 1025px) {
  aside.betterdocs-sidebar > .betterdocs-sidebar-content,
  .betterdocs-sidebar .layout3-toc-container {
    position: sticky;
    top: 90px;
    max-height: calc(100vh - 110px);
    overflow-y: auto;
  }
}

/* ── Feedback form submit button ─────────────────────────────────────────── */
/* NOTE: the BetterDocs feedback form is currently switched off in the plugin,
   so these rules are dormant. Kept so the button is on-brand the day the
   form comes back. */
#feedback_form_submit_btn {
  background-color: var(--pv-brand) !important;
  border: none;
  border-radius: 6px;
  color: #ffffff;
  padding: 10px 48px !important;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  line-height: 1.2;
  box-shadow: none;
  text-shadow: none;
}

#feedback_form_submit_btn:hover {
  background-color: var(--pv-brand-hover) !important;
  color: #ffffff;
}

#feedback_form_submit_btn:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(55, 114, 163, 0.35);
}

#feedback_form_submit_btn:active {
  transform: translateY(1px);
}


/* ═══════════════════════════════════════════════════════════════════════════
   12. DOCS — .SVEN-DOCS ARTICLE CONTENT
   All classes prefixed with .sven-docs to avoid conflicts.
   Typography comes from the article tokens in section 1, shared with blog
   posts (section 10), so the two cannot drift apart again. Elements the blog
   never styled at all (hr, kbd, figcaption, h5/h6) are grouped into the rules
   here via .single-blog .ptb_post selectors — one rule, both surfaces. The
   docs-only authoring constructs (.sven-hint, .sven-pill, details/summary)
   stay docs-only on purpose: no post uses them, and speculative rules are
   how dead CSS accumulates.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Jump links land below the sticky header instead of behind it.
   This used to be a <style> block copied into each doc; only 2 of the 9 docs
   with in-page anchors actually had it, so the other 7 were broken. Docs are
   deployed from the pythonandvba-pages repo now, so it lives here once. */
.betterdocs-content [id] {
  scroll-margin-top: 80px;
}

/* Container.
   No font-family here on purpose: this used to force a system stack, which
   made docs the only pages on the site not set in the theme font. */
.sven-docs {
  line-height: var(--pv-leading);
  color: var(--pv-text);
  font-size: 16px;
}

/* ── Headings ────────────────────────────────────────────────────────────── */
/* Docs never use h1: BetterDocs renders the doc title as the page h1, so the
   body starts at h3. h2 is kept for the few docs that need a top-level split.

   Themify sets `text-transform: capitalize` on bare h1-h4, so every heading
   rendered as Title Case no matter what the markup said, and the sentence-case
   convention was invisible on the page. Section 13 already undoes this for
   solution pages; article content needs the same. */
.sven-docs h2,
.sven-docs h3,
.sven-docs h4,
.sven-docs h5,
.sven-docs h6 {
  text-transform: none;
}

.sven-docs h2 {
  font-size: 1.5em;
  font-weight: 600;
  color: var(--pv-heading);
  margin: 1.4em 0 0.5em 0;
  padding-bottom: 0.25em;
  border-bottom: 1px solid var(--pv-rule);
}

.sven-docs h3 {
  font-size: 1.25em;
  font-weight: 600;
  color: var(--pv-heading);
  margin: 1.3em 0 0.4em 0;
}

.sven-docs h4 {
  font-size: 1.1em;
  font-weight: 600;
  color: var(--pv-text);
  margin: 1.2em 0 0.4em 0;
}

/* Also covers blog posts, which styled h2-h4 but left h5/h6 to the theme */
.sven-docs h5,
.sven-docs h6,
.single-blog .ptb_post h5,
.single-blog .ptb_post h6 {
  font-size: 1em;
  font-weight: 600;
  color: var(--pv-heading-soft);
  margin: 1em 0 0.3em 0;
}

/* The first block sits right under the page title and needs no top margin. */
.sven-docs > :first-child {
  margin-top: 0;
}

/* ── Text ────────────────────────────────────────────────────────────────── */
.sven-docs p {
  margin: 0.8em 0;
}

/* Underlined, not color-only: the link blue and the body gray are nearly
   identical in lightness, so without an underline links are invisible to
   color-blind readers (WCAG 1.4.1) and undiscoverable on touch screens,
   where the old hover-only underline never fired. Soft underline at rest,
   full brand color on hover. Blog content links match (section 10). */
.sven-docs a {
  color: var(--pv-brand);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--pv-brand) 35%, transparent);
  text-underline-offset: 0.15em;
  transition: text-decoration-color 0.2s ease;
}

.sven-docs a:hover {
  text-decoration-color: var(--pv-brand);
}

/* ── Button-style links (class "button" on an <a>) ───────────────────────── */
/* Used by the "Add extra device" CTAs in the license docs. Nothing styled
   this class before, so the CTAs rendered as plain text links. */
.sven-docs a.button {
  display: inline-block;
  padding: 0.55em 1.2em;
  margin: 0.25em 0;
  background-color: var(--pv-brand);
  color: #ffffff;
  border-radius: 6px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.sven-docs a.button:hover {
  background-color: var(--pv-brand-hover);
  text-decoration: none;
}

/* The CTA labels are wrapped in <strong>, which would otherwise turn dark */
.sven-docs a.button strong {
  color: inherit;
  font-weight: inherit;
}

.sven-docs strong {
  font-weight: 600;
  color: var(--pv-heading-strong);
}

.sven-docs em {
  font-style: italic;
}

/* ── Code ────────────────────────────────────────────────────────────────── */
.sven-docs code {
  background-color: var(--pv-code-bg);
  color: var(--pv-code-text);
  padding: 0.15em 0.4em;
  border-radius: 4px;
  border: 1px solid var(--pv-rule);
  font-family: var(--pv-mono);
  font-size: 0.875em;
}

.sven-docs pre {
  background-color: var(--pv-pre-bg);
  color: var(--pv-pre-text);
  font-family: var(--pv-mono); /* blog pre had this, docs pre had drifted */
  padding: 1em 1.25em;
  border-radius: var(--pv-radius);
  overflow-x: auto;
  margin: 1em 0;
  border: 1px solid #334155;
}

.sven-docs pre code {
  background-color: transparent;
  color: inherit;
  padding: 0;
  border: none;
  border-radius: 0;
  font-size: 0.875em;
  line-height: 1.6;
}

/* emgithub embeds — preserve their own styling */
.emgithub-wrapper pre {
  white-space: pre !important;
  overflow-x: auto !important;
  background-color: #f6f8fa !important;
  padding: 16px !important;
  border-radius: 6px !important;
  line-height: 1.45 !important;
}

.emgithub-wrapper code {
  white-space: pre !important;
  display: block !important;
}

/* ── Tables ──────────────────────────────────────────────────────────────── */
/* #body is overflow:hidden, so a table wider than its column would be clipped
   rather than scrollable. display:block keeps it scrollable on a phone. */
.sven-docs table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5em 0;
  font-size: 0.95em;
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.sven-docs th {
  background-color: var(--pv-text);
  color: #ffffff;
  font-weight: 600;
  text-align: left;
  padding: 0.75em 1em;
  border: 1px solid var(--pv-text);
}

.sven-docs td {
  padding: 0.75em 1em;
  border: 1px solid var(--pv-rule);
  vertical-align: top;
}

.sven-docs tr:nth-child(even) {
  background-color: var(--pv-surface);
}

.sven-docs tr:hover {
  background-color: var(--pv-surface-alt);
}

/* Hide hidden table headers (GitBook cards) */
.sven-docs th.hidden {
  display: none;
}

/* ── Lists ───────────────────────────────────────────────────────────────── */
.sven-docs ul,
.sven-docs ol {
  margin: 0.8em 0;
  padding-left: 1.5em;
}

.sven-docs li {
  margin: 0.4em 0;
}

.sven-docs li > ul,
.sven-docs li > ol {
  margin: 0.3em 0;
}

/* Markers in brand blue, text in body grey. The bullet is structure, not
   content, and colouring it separately is what stops a long list reading as a
   grey wall. ::marker only accepts colour, font and content, so this cannot
   affect the spacing above. */
.sven-docs li::marker {
  color: var(--pv-brand);
}

/* ── Highlighted example text ────────────────────────────────────────────── */
/* <mark> had no rule at all, so it fell through to the browser default. That
   default is a saturated yellow, and against this palette it read as orange
   shouting out of the page. Every use of it in the docs is a specimen, a
   sample SMS the reader is meant to copy the shape of, which wants to look
   set apart rather than urgent.

   A pale brand tint does that: quiet, clearly a quoted specimen, and the same
   family as everything else on the page. box-decoration-break keeps the
   padding and corners intact when a long example wraps onto a second line,
   which the default would clip flat. */
.sven-docs mark {
  background-color: #eef4f9;
  color: var(--pv-heading-strong);
  padding: 0.12em 0.4em;
  border-radius: 3px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ── Do / don't icons ────────────────────────────────────────────────────── */
/* Authored as <span class="sven-ico sven-ico-yes"></span>, replacing the
   emoji these docs used to type inline.

   Emoji were the wrong tool for a structural marker. They render from a
   different font on every platform, at a weight and baseline that fight the
   text beside them, and the corpus had drifted to four characters doing two
   jobs: U+2705 and U+2713 both meaning yes, U+274C and U+26D4 both meaning no.

   Drawn here rather than pulled from an icon font because the site loads no
   icon font at all, and adding one would be a render-blocking third-party
   request to draw two shapes. A mask over a coloured box costs nothing extra,
   stays crisp at any size, and scales with the text because it is sized in em.

   Emoji that are CONTENT still belong in the body: the Gmail Blaster page
   about inserting emoji, the sample WhatsApp messages, and the Command key
   symbol are all things the reader is meant to see. */
.sven-docs .sven-ico {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.14em;
  flex: none;
  background-color: currentColor;
  -webkit-mask: var(--sven-ico) center / contain no-repeat;
  mask: var(--sven-ico) center / contain no-repeat;
}

.sven-docs .sven-ico-yes {
  color: #166534;   /* same green as .sven-hint-success text */
  --sven-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M13.5 4.5 6.5 11.5 2.5 7.5' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.sven-docs .sven-ico-no {
  color: #991b1b;   /* same red as .sven-hint-danger text */
  --sven-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4 12 12M12 4 4 12' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* Inside a coloured callout the icon takes the callout's own text colour,
   or a green tick on a red danger panel would contradict the panel. */
.sven-docs .sven-hint-warning .sven-ico,
.sven-docs .sven-hint-danger .sven-ico,
.sven-docs .sven-hint-success .sven-ico {
  color: inherit;
}

/* When the icon is the whole cell, centre it rather than leaving it ranged
   left against a column of dates. */
.sven-docs td > .sven-ico:only-child {
  display: block;
  margin: 0 auto;
}

/* ── Blockquotes ─────────────────────────────────────────────────────────── */
.sven-docs blockquote {
  margin: 1em 0;
  padding: 0.75em 1em;
  border-left: 4px solid #d1d5db;
  background-color: var(--pv-surface);
  color: var(--pv-heading-soft);
  border-radius: 0 var(--pv-radius) var(--pv-radius) 0;
}

.sven-docs blockquote p {
  margin: 0;
}

/* ── Hint / callout boxes ────────────────────────────────────────────────── */
.sven-docs .sven-hint {
  display: block;
  padding: 1em 1.25em;
  margin: 1.25em 0;
  border-radius: var(--pv-radius);
  font-size: 0.925em;
  line-height: 1.6;
  color: var(--pv-text);
  position: relative;
}

.sven-docs .sven-hint p {
  margin: 0;
}

/* A hint with several paragraphs used to run them together (margin-top was 0). */
.sven-docs .sven-hint p + p {
  margin-top: 0.6em;
}

.sven-docs .sven-hint ul,
.sven-docs .sven-hint ol {
  margin: 0.5em 0 0 0;
  padding-left: 1.25em;
}

.sven-docs .sven-hint li {
  margin: 0.25em 0;
}

.sven-docs .sven-hint strong {
  color: var(--pv-heading);
}

/* On a coloured callout the heading blue fought the panel: the lead-in
   ("Heads up:", "Important:") came out navy on amber and read as a dead link.
   Same reasoning as the .sven-ico rule further up — inside a coloured panel,
   the panel's own colour wins. Equal specificity to the rule above, so this
   has to stay below it. .sven-hint-info keeps the heading blue on purpose:
   its panel has no colour of its own to inherit. */
.sven-docs .sven-hint-warning strong,
.sven-docs .sven-hint-danger strong,
.sven-docs .sven-hint-success strong {
  color: inherit;
}

.sven-docs .sven-hint a {
  color: var(--pv-brand);
  text-decoration: underline;
  font-weight: 600;
}

.sven-docs .sven-hint a:hover {
  color: var(--pv-brand-hover);
}

.sven-docs .sven-hint-info {
  background-color: #ECF1F6;
  border: 1px solid #c5d5e4;
}

/* border was #fef3c7, indistinguishable from its own #fffbeb background */
.sven-docs .sven-hint-warning {
  background-color: #fffbeb;
  border: 1px solid #fde68a;
  color: #92400e;
}

.sven-docs .sven-hint-danger {
  background-color: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
}

.sven-docs .sven-hint-success {
  background-color: #f0fdf4;
  border: 1px solid #bbf7d0;
  color: #166534;
}

/* ── Rules, images, figures & embeds ─────────────────────────────────────── */
/* hr, figcaption, kbd and h5/h6 also cover .single-blog posts: WordPress can
   emit all of them, and they previously fell back to raw theme defaults
   there. Grouped selectors, so the two surfaces cannot drift apart. */
.sven-docs hr,
.single-blog .ptb_post hr {
  border: none;
  border-top: 1px solid var(--pv-rule);
  margin: 2em 0;
}

/* Every other video on the site has rounded corners (section 5); the video
   iframes in docs were the only square ones. */
.sven-docs iframe {
  border-radius: var(--pv-radius);
}

.sven-docs img {
  max-width: 100%;
  height: auto;
  border-radius: var(--pv-radius);
  margin: 0.5em 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.sven-docs figure,
.sven-docs .sven-figure {
  margin: 0.5em 0;
  text-align: left;
}

.sven-docs figure img,
.sven-docs .sven-figure img {
  margin-bottom: 0.5em;
}

.sven-docs figcaption,
.single-blog .ptb_post figcaption {
  font-size: 0.9em;
  color: var(--pv-muted);
  font-style: italic;
}

/* ── Keyboard shortcuts ──────────────────────────────────────────────────── */
.sven-docs kbd,
.single-blog .ptb_post kbd {
  background-color: var(--pv-code-bg);
  border: 1px solid #d1d5db;
  border-radius: 4px;
  padding: 0.1em 0.4em;
  font-family: var(--pv-mono);
  font-size: 0.85em;
  box-shadow: 0 1px 0 #9ca3af;
}

/* ── Details/summary — FAQ accordion ─────────────────────────────────────── */
.sven-docs details {
  margin: 0.5em 0;
  border: 1px solid var(--pv-rule);
  border-radius: var(--pv-radius);
  background-color: #ffffff;
}

.sven-docs details + details {
  margin-top: 0;
  border-top: none;
  border-radius: 0;
}

.sven-docs details:first-of-type {
  border-radius: var(--pv-radius) var(--pv-radius) 0 0;
}

.sven-docs details:last-of-type {
  border-radius: 0 0 var(--pv-radius) var(--pv-radius);
}

.sven-docs details:only-of-type {
  border-radius: var(--pv-radius);
}

.sven-docs summary {
  padding: 1em 1.25em;
  cursor: pointer;
  font-weight: 600;
  color: var(--pv-text);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.75em;
}

.sven-docs summary::-webkit-details-marker {
  display: none;
}

/* A drawn chevron rather than a literal ">" character, which rendered in the
   body font and read as a stray typo. */
.sven-docs summary::before {
  content: "";
  flex: 0 0 auto;
  width: 0.42em;
  height: 0.42em;
  border-right: 2px solid #9ca3af;
  border-bottom: 2px solid #9ca3af;
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
}

.sven-docs details[open] summary::before {
  transform: rotate(45deg);
}

.sven-docs summary:hover::before {
  border-color: var(--pv-brand);
}

/* The whole row is the hit target, so the whole row has to react. Only the
   chevron changed colour before, which left a full-width clickable strip with
   no hover state on the part people actually aim at. */
.sven-docs summary:hover {
  background-color: var(--pv-surface);
  color: var(--pv-heading-strong);
}

.sven-docs summary {
  border-radius: inherit;
  transition: background-color 0.15s ease;
}

/* An open row keeps its tint and gains a rule, so the header reads as attached
   to the panel it opened rather than floating above it. */
.sven-docs details[open] > summary {
  background-color: var(--pv-surface);
  border-bottom: 1px solid var(--pv-rule);
  border-radius: inherit;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

@media (prefers-reduced-motion: reduce) {
  .sven-docs summary,
  .sven-docs summary::before {
    transition: none;
  }
}

/* The bottom padding closes the PANEL, so it belongs on the last child only.
   Applying it to every child put 1em under each one, which then stacked with
   the next element's own top margin: the gap between "How to fix it" and the
   bullets below it measured 29px where the paragraph spacing around it is 8. */
.sven-docs details > *:not(summary) {
  padding: 0 1.25em 0 2.5em;
  color: var(--pv-heading-soft);
}

.sven-docs details > *:not(summary):last-child {
  padding-bottom: 1em;
}

/* Lists need the prose indent PLUS room for the marker, or the bullet hangs
   outside the text column: markers were drawn 18px left of every paragraph in
   the same panel, which is what made the list look unaligned. 1.15em is the
   marker's own advance, so the dot lands exactly on the prose edge. */
.sven-docs details > ul,
.sven-docs details > ol {
  padding-left: 3.65em;   /* 2.5em prose indent + 1.15em for the marker */
  margin: 0.5em 0;
}

.sven-docs details .sven-hint {
  margin-left: 1.25em;
  margin-right: 1.25em;
}

.sven-docs details p {
  margin: 0;
}

.sven-docs details p + p {
  margin-top: 0.6em;
}

/* ── Task lists ──────────────────────────────────────────────────────────── */
.sven-docs input[type="checkbox"] {
  margin-right: 0.5em;
}

/* ── Severity pills ──────────────────────────────────────────────────────── */
.sven-docs .sven-pill {
  display: inline-block;
  padding: 0.15em 0.6em;
  border-radius: 9999px;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
  margin-left: 0.4em;
}

.sven-docs .sven-pill-critical {
  background-color: #fecaca;
  color: #991b1b;
  border: 1px solid #f87171;
}

.sven-docs .sven-pill-warning {
  background-color: #fef3c7;
  color: #92400e;
  border: 1px solid #fcd34d;
}

.sven-docs .sven-pill-info {
  background-color: #ECF1F6;
  color: var(--pv-brand);
  border: 1px solid #c5d5e4;
}

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .sven-docs {
    font-size: 15px;
  }

  .sven-docs h2 {
    font-size: 1.35em;
  }

  .sven-docs h3 {
    font-size: 1.2em;
  }

  /* No font-size shrink here: pre code already runs at 0.875em, and a second
     factor on pre compounded to ~10.5px code on phones */
  .sven-docs pre {
    padding: 0.75em 1em;
  }

  .sven-docs table {
    font-size: 0.9em;
  }

  .sven-docs th,
  .sven-docs td {
    padding: 0.5em 0.75em;
  }

  .sven-docs .sven-hint {
    padding: 0.75em 1em;
  }

  .sven-docs details > *:not(summary) {
    padding: 0 1em 0 1.75em;
  }

  .sven-docs details > *:not(summary):last-child {
    padding-bottom: 1em;
  }

  /* Same sum as desktop against the narrower 1.75em prose indent. */
  .sven-docs details > ul,
  .sven-docs details > ol {
    padding-left: 2.9em;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   13. TOOL & SOLUTION PAGES
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Solutions sub-menu ──────────────────────────────────────────────────── */

/* Horizontal scroll on mobile */
@media (max-width: 768px) {
  #menu-solutions {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  #menu-solutions li {
    flex-shrink: 0;
  }
}

/* Active item: bold */
#menu-solutions .current-menu-item a {
  font-weight: 700;
}

/* No rounding on the menu container */
.module-menu-container,
#menu-solutions {
  border-radius: 0 !important;
}

/* ── Content sections (pva-s-* wrapper classes, e.g. SMS Spam Checker) ───── */

/* All section wrappers */
.pva-s-sve, .pva-s-trg, .pva-s-rpl, .pva-s-spw,
.pva-s-enc, .pva-s-p2p, .pva-s-tps, .pva-s-vol, .pva-s-leg {
  line-height: 1.65;
}

/* H2 headings */
.pva-s-sve h2, .pva-s-trg h2, .pva-s-rpl h2, .pva-s-spw h2,
.pva-s-enc h2, .pva-s-p2p h2, .pva-s-tps h2, .pva-s-vol h2, .pva-s-leg h2 {
  color: #1f2937;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
}

/* H3 headings */
.pva-s-sve h3, .pva-s-trg h3, .pva-s-rpl h3, .pva-s-spw h3,
.pva-s-enc h3, .pva-s-p2p h3, .pva-s-tps h3, .pva-s-vol h3, .pva-s-leg h3 {
  color: #1f2937;
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
}

/* Paragraphs */
.pva-s-sve p, .pva-s-trg p, .pva-s-rpl p, .pva-s-spw p,
.pva-s-enc p, .pva-s-p2p p, .pva-s-tps p, .pva-s-vol p, .pva-s-leg p {
  color: #374151;
  line-height: 1.65;
  margin-bottom: 14px;
}

/* Lists */
.pva-s-sve ul, .pva-s-trg ul, .pva-s-rpl ul, .pva-s-spw ul,
.pva-s-enc ul, .pva-s-p2p ul, .pva-s-tps ul, .pva-s-vol ul, .pva-s-leg ul {
  padding-left: 20px;
  margin-bottom: 14px;
}

.pva-s-sve li, .pva-s-trg li, .pva-s-rpl li, .pva-s-spw li,
.pva-s-enc li, .pva-s-p2p li, .pva-s-tps li, .pva-s-vol li, .pva-s-leg li {
  color: #374151;
  line-height: 1.65;
  margin-bottom: 8px;
}

/* Links */
.pva-s-sve a, .pva-s-trg a, .pva-s-rpl a, .pva-s-spw a,
.pva-s-enc a, .pva-s-p2p a, .pva-s-tps a, .pva-s-vol a, .pva-s-leg a {
  color: var(--pv-brand);
  text-decoration: none;
}

.pva-s-sve a:hover, .pva-s-trg a:hover, .pva-s-rpl a:hover, .pva-s-spw a:hover,
.pva-s-enc a:hover, .pva-s-p2p a:hover, .pva-s-tps a:hover, .pva-s-vol a:hover,
.pva-s-leg a:hover {
  text-decoration: underline;
}

/* Hero heading */
.pva-s-hero {
  text-align: center;
}

.pva-s-hero h1 {
  color: #1f2937;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
}

.pva-s-hero p {
  color: #6b7280;
}

/* ── FAQ accordion (Themify module with class pva-faq) ───────────────────── */
.pva-faq .accordion-title-wrap {
  color: #1f2937;
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
}

.pva-faq .tb_title_accordion {
  color: #1f2937;
  text-decoration: none;
}

.pva-faq .tb_title_accordion:hover {
  color: var(--pv-brand);
  text-decoration: none;
}

.pva-faq .tb_text_wrap p {
  color: #374151;
  line-height: 1.65;
  margin-bottom: 10px;
}

.pva-faq .accordion-content a {
  color: var(--pv-brand);
  text-decoration: none;
}

.pva-faq .accordion-content a:hover {
  text-decoration: underline;
}


/* ═══════════════════════════════════════════════════════════════════════════
   14. FORMS
   ═══════════════════════════════════════════════════════════════════════════ */

/* Fluent Forms: brand-blue input focus across all forms */
.fluentform .ff-el-form-control:focus,
.fluentform .ff-el-form-control:focus-visible,
.fluentform textarea.ff-el-form-control:focus,
.fluentform select.ff-el-form-control:focus {
  border-color: var(--pv-brand) !important;
  box-shadow: 0 0 0 0.15rem rgba(55, 114, 163, 0.25) !important;
  outline: none !important;
}

/* Contact form (Fluent Forms #54): less padding on mobile */
@media (max-width: 768px) {
  .fluentform_wrapper_54.ffs_custom_wrap {
    padding: 24px !important;
  }
}

/* Themify opt-in form */
.module-optin label {
  line-height: 20px;
  display: inline-block;
  width: -webkit-fill-available;
}
label.tb_optin_email_text {
  width: 100%;
}

.tb_optin_gdpr_text {
  font-size: 0.8rem;
}

/* Themify Builder contact form: "send copy" checkbox spacing */
.builder-contact-field.builder-contact-field-sendcopy {
  margin-top: 2% !important;
}

/* PTB search autocomplete box */
.ptb-search-autocomplete.ui-autocomplete-input {
  padding: 15px !important;
  border-radius: 10px !important;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   15. PAGE-SPECIFIC OVERRIDES
   ═══════════════════════════════════════════════════════════════════════════ */

/* Hide footer on popup/offer pages:
   6367 = MyToolBelt Limited Time Offer · 3009 = MyToolBelt Free Version
   6682 = WhatsAppBlaster Free Download PopUp · 6834 = WhatsAppBlaster Success */
.page-id-6367 .tb_layout_part_wrap.tf_w,
.page-id-3009 .tb_layout_part_wrap.tf_w,
.page-id-6682 .tb_layout_part_wrap.tf_w,
.page-id-6834 .tb_layout_part_wrap.tf_w {
  display: none;
}

/* MyToolBelt pricing (page 5850): italic "Windows only" note */
.page-id-5850 .module-pricing-table-reccuring-fee {
  font-style: italic;
}


/* ═══════════════════════════════════════════════════════════════════════════
   16. LEGAL PAGES (.legal-doc)
   The six legal documents: Terms and Conditions, Privacy Policy, Refund
   Policy, the EULA, and the two app privacy policies (QuickText Desktop,
   SendCommander). Sibling documents that have to look identical, so their
   CSS lives here once rather than inside six page snippets.

   The look is deliberately a CLASSIC formal document (serif body, plain
   numbered uppercase headings, a contents list like a contract's, no pill
   navigation or other site chrome): Sven wants a legal page to read like a
   legal document. Cross-links between the documents sit in a quiet
   "Related documents" line at the BOTTOM (.ld-related), not as chrome on
   top. Each page offers "Print or save as PDF" (.ld-print, window.print());
   the print rules live in section 17 and turn the browser's Save as PDF
   into a clean filed document.

   Everything is scoped under .legal-doc and prefixed ld-. The pages
   themselves are markup only, in pages/<slug>/index.html.
   ═══════════════════════════════════════════════════════════════════════════ */

.legal-doc {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 16px;
  line-height: 1.9;
  color: #1a202c;
  max-width: 820px;
  margin: 0 auto;
}

.legal-doc .ld-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding-bottom: 24px;
  margin-bottom: 32px;
  border-bottom: 2px solid #3772a3;
}

.legal-doc h1 {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif !important;
  font-size: 2em !important;
  font-weight: 800 !important;
  color: #3772a3 !important;
  letter-spacing: -0.02em;
  margin: 0 0 14px !important;
  padding: 0 !important;
  border: none !important;
}

.legal-doc .ld-meta {
  display: inline-block;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 0.72em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #4a5568;
  background: #edf2f7;
  border-left: 3px solid #3772a3;
  padding: 5px 12px;
}

/* The print affordance. A quiet secondary button: useful to the people who
   file legal documents, invisible chrome to everyone else. Hidden on paper
   (section 17). */
.legal-doc .ld-print {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 13px;
  line-height: 1;
  color: #4a5568;
  background: #ffffff;
  border: 1px solid #cbd5e0;
  border-radius: 6px;
  padding: 9px 14px;
  margin-top: 6px;
  cursor: pointer;
  white-space: nowrap;
  flex: none;
}

.legal-doc .ld-print:hover {
  color: #3772a3;
  border-color: #3772a3;
  background: #f7fafc;
}

.legal-doc .ld-intro {
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-left: 4px solid #3772a3;
  padding: 16px 20px;
  margin-bottom: 32px;
  font-size: 0.93em;
  color: #2d3748;
}

/* The contents list, styled like a contract's: a plain bordered box, the
   entries in the document's own face. Screen-only wayfinding (section 17
   hides it in print, where there are no anchors to click). */
.legal-doc .ld-toc {
  border: 1px solid #e2e8f0;
  border-radius: 4px;
  padding: 18px 24px 20px;
  margin: 0 0 36px;
}

.legal-doc .ld-toc__t {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 0.72em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #4a5568;
  margin: 0 0 10px;
}

.legal-doc .ld-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9em;
  columns: 2;
  column-gap: 36px;
}

.legal-doc .ld-toc li {
  margin: 0 0 6px;
  break-inside: avoid;
}

.legal-doc .ld-toc a {
  color: #2d3748;
  text-decoration: none;
}

.legal-doc .ld-toc a:hover {
  color: #3772a3;
  text-decoration: underline;
}

.legal-doc h2 {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
  font-size: 0.75em !important;
  font-weight: 700 !important;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: #3772a3 !important;
  border: none !important;
  border-bottom: 1px solid #e2e8f0 !important;
  padding: 0 0 8px !important;
  margin: 44px 0 16px !important;
}

.legal-doc h3 {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
  font-size: 0.8em !important;
  font-weight: 700 !important;
  color: #2d3748 !important;
  margin: 24px 0 8px !important;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  border: none !important;
}

.legal-doc p {
  margin: 0 0 14px;
  font-size: 0.93em;
}

.legal-doc ul,
.legal-doc ol {
  margin: 0 0 16px;
  padding-left: 22px;
}

.legal-doc li {
  margin-bottom: 7px;
  font-size: 0.93em;
}

.legal-doc li p {
  font-size: 1em;
}

.legal-doc a {
  color: #3772a3;
  text-decoration: underline;
}

.legal-doc strong {
  font-weight: 700;
  color: #1a202c;
}

/* The amber callout: the clauses that cost a customer money if missed.
   The only amber on any of these pages, on purpose. */
.legal-doc .ld-note {
  background: #fffaf0;
  border: 1px solid #f6e0a2;
  border-left: 4px solid #d69e2e;
  border-radius: 0 4px 4px 0;
  padding: 14px 18px;
  margin: 0 0 16px;
}

.legal-doc .ld-note p:last-child {
  margin-bottom: 0;
}

.legal-doc .ld-contact {
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 4px;
  padding: 20px 24px;
  margin-top: 8px;
  line-height: 2;
  font-size: 0.9em;
}

/* Cross-links between the legal documents: present because support replies
   and store listings land people on one document who then need a sibling,
   quiet because navigation must not dress up a legal text. */
.legal-doc .ld-related {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 13px;
  color: #4a5568;
  margin-top: 44px;
  padding-top: 18px;
  border-top: 1px solid #e2e8f0;
}

.legal-doc .ld-related a {
  color: #4a5568;
  text-decoration: none;
}

.legal-doc .ld-related a:hover {
  color: #3772a3;
  text-decoration: underline;
}

@media (max-width: 639px) {
  .legal-doc .ld-header {
    flex-direction: column;
  }

  .legal-doc .ld-toc ol {
    columns: 1;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   17. PRINT
   Docs get printed and saved as PDF. Without this, the mega menu, footer and
   dark code backgrounds print along with the article.
   ═══════════════════════════════════════════════════════════════════════════ */

@media print {
  #headerwrap,
  #footerwrap,
  /* The real site footer: a Themify Builder row, NOT inside #footerwrap
     (which does not exist on this theme config at all). Without this the
     newsletter form, social icons and copyright bar printed as a garbled
     final page on every legal document. */
  #custom-footer,
  .themify_announcement,
  aside.betterdocs-sidebar,
  .betterdocs-search-form-wrapper,
  .betterdocs-mobile-nav,
  .post-filter,
  .ptb_search_module {
    display: none !important;
  }

  /* The sidebars leave empty grid tracks behind; let the article take the
     full page width instead */
  .betterdocs-content-wrapper {
    display: block;
  }

  /* Dark backgrounds waste toner and often print as solid black boxes.
     pre code inherits this color; wrapping replaces scrolling, which paper
     cannot do. */
  .sven-docs pre,
  .single-blog pre {
    background: #ffffff;
    color: #111827;
    border: 1px solid #9ca3af;
    white-space: pre-wrap;
    word-break: break-word;
  }

  /* Scroll containers cannot scroll on paper: lay tables out fully */
  .sven-docs table,
  .single-blog table {
    display: table;
  }

  .sven-docs tr,
  .single-blog tr {
    break-inside: avoid;
  }

  .sven-docs img,
  .single-blog img {
    box-shadow: none;
  }

  /* Legal pages are the most-printed content on the site (people file the
     EULA and the refund policy) and each carries a "Print or save as PDF"
     button that lands here. Screen wayfinding is dead weight on paper, color
     wastes toner, and a heading orphaned at the foot of a page is worse in a
     numbered document than anywhere else. */
  .legal-doc .ld-print,
  .legal-doc .ld-toc,
  .legal-doc .ld-related {
    display: none !important;
  }

  .legal-doc {
    max-width: none;
    color: #000000;
  }

  .legal-doc h1,
  .legal-doc h2,
  .legal-doc h3,
  .legal-doc strong {
    color: #000000 !important;
  }

  .legal-doc a {
    color: #000000;
    text-decoration: none;
  }

  .legal-doc .ld-header {
    border-bottom-color: #000000;
  }

  .legal-doc .ld-meta,
  .legal-doc .ld-intro,
  .legal-doc .ld-note,
  .legal-doc .ld-contact {
    background: #ffffff;
    color: #000000;
  }

  .legal-doc h2 {
    break-after: avoid;
  }

  .legal-doc h3 {
    break-after: avoid;
  }

  .legal-doc .ld-note,
  .legal-doc .ld-contact {
    break-inside: avoid;
    border-color: #000000;
  }
}
