/*
Theme Name: YouTube Thumbnail Downloader
Theme URI: https://blog.youtubethumbnaildownloader4k.com
Author: YouTube Thumbnail Downloader
Description: A fast, mobile-first, SEO-optimized YouTube thumbnail downloader theme. Free thumbnail extraction tool with HD/4K resolution detection, zero backend, and privacy-first architecture.
Version: 1.5.0
Requires at least: 6.0
Requires PHP: 7.4
Text Domain: ytd
*/

/* ============================================================
   Design tokens — derived from the brand mark (red / black / white)
   ============================================================ */
:root {
  --brand-primary: #dd0000;
  --brand-primary-dark: #b30000;
  --brand-secondary: #0a0a0a;
  --brand-accent: #ffe8e8;
  --brand-dark: #0a0a0a;
  --brand-light: #ffffff;
  --brand-bg: #fafafa;
  --brand-text: #131313;
  --brand-muted: #63666b;
  --brand-border: #e6e6e6;

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(10, 10, 10, 0.06);
  --shadow-md: 0 8px 24px rgba(10, 10, 10, 0.08);
  --shadow-red: 0 10px 24px rgba(221, 0, 0, 0.22);

  --container: 1100px;
  --touch: 48px;

  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Dark mode intentionally disabled: the brand mark (logo) is a flattened
   PNG with an opaque white background, so auto-switching the site dark
   leaves the logo sitting in an ugly white box. The theme is light-only
   until a transparent-background logo is available. */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* A single over-wide child (imported table, pasted ad iframe, long
   unbroken URL) widens <body> and every section inside it — that is what
   "destroys" a mobile layout, because the damage is never local to the
   offending element. Clip it at the root and fix the real cases below. */
html, body { overflow-x: clip; max-width: 100%; }
/* Deliberately `clip`, not `hidden`. overflow-x:hidden on html/body turns
   the document into a scroll container, which breaks the sticky header.
   `clip` contains the overflow without that side effect. */

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--brand-bg);
  color: var(--brand-text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 20px;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.12;
  margin: 0;
}

h1 { font-size: clamp(2rem, 5vw + 1rem, 3.4rem); }
h2 { font-size: clamp(1.5rem, 2.6vw + 1rem, 2.1rem); }
h3 { font-size: clamp(1.15rem, 1.4vw + 1rem, 1.4rem); }

p { margin: 0; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand-primary);
}

.muted { color: var(--brand-muted); }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--touch);
  padding: 0 22px;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 1rem;
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: scale(0.98); }
.btn-primary { background: var(--brand-primary); color: #fff; box-shadow: var(--shadow-red); }
.btn-primary:hover { background: var(--brand-primary-dark); color: #fff; }
.btn-outline { background: transparent; border-color: var(--brand-border); color: var(--brand-text); }
.btn-outline:hover { border-color: var(--brand-primary); color: var(--brand-primary); }
.btn-block { width: 100%; }
.btn:focus-visible { outline: 3px solid var(--brand-primary); outline-offset: 2px; }

button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 3px solid var(--brand-primary);
  outline-offset: 2px;
}

section { padding-block: clamp(2.5rem, 6vw, 5rem); }
section.tight { padding-block: clamp(1.5rem, 3vw, 2.5rem); }
section.alt { background: var(--brand-light); border-block: 1px solid var(--brand-border); }

.card { background: var(--brand-light); border: 1px solid var(--brand-border); border-radius: var(--radius-lg); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--brand-primary); color: #fff;
  padding: 10px 16px; border-radius: 0 0 8px 0; z-index: 100;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ============================================================
   Header
   ============================================================ */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--brand-light); border-bottom: 1px solid var(--brand-border); }
.header-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
.brand { display: flex; align-items: center; text-decoration: none; min-width: 0; }
.brand .custom-logo-link { display: flex; align-items: center; }

/* ------------------------------------------------------------------
   LOGO SIZING — deliberately NOT scoped to an ancestor.

   The old rules were written as `.brand img.custom-logo`, which stopped
   matching the moment the logo markup changed shape (and did stop
   matching, because the_custom_logo() nested an <a> inside .brand and
   the HTML parser moved the <img> out of .brand entirely). A logo that
   loses its height rule falls back to its intrinsic size — a 2048px-wide
   PNG painting across the whole viewport. These rules are element-scoped
   so no markup change can un-match them.

   width:auto + max-width guard keeps the aspect ratio correct whatever
   dimensions the uploaded file happens to have.
   ------------------------------------------------------------------ */
img.custom-logo,
img.brand-logo,
.wp-custom-logo .custom-logo {
  height: 32px;
  max-height: 32px;
  width: auto;
  /* A wide-but-short wordmark is normal; this cap only exists to stop a
     genuinely broken upload from eating the header. object-fit:contain
     letterboxes rather than distorting if the cap ever bites. */
  max-width: 280px;
  object-fit: contain;
}
@media (max-width: 420px) {
  img.custom-logo,
  img.brand-logo { height: 26px; max-height: 26px; max-width: 170px; }
}

.footer-brand-link { display: inline-flex; align-items: center; text-decoration: none; }
.site-footer img.custom-logo,
.site-footer img.footer-logo { height: 28px; max-height: 28px; width: auto; max-width: 180px; }
.footer-brand-text { display: block; font-weight: 800; font-size: 1.05rem; color: #fff; }

.site-nav { display: none; gap: 28px; }
.site-nav ul { list-style: none; display: flex; gap: 28px; margin: 0; padding: 0; }
.site-nav a { text-decoration: none; font-weight: 600; font-size: 0.95rem; color: var(--brand-text); }
.site-nav a:hover { color: var(--brand-primary); }

.menu-toggle {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; background: none; border: none; cursor: pointer;
}
.menu-toggle span { display: block; height: 2px; background: var(--brand-text); border-radius: 2px; }

.mobile-nav { display: flex; flex-direction: column; border-top: 1px solid var(--brand-border); background: var(--brand-light); }
.mobile-nav[hidden] { display: none; }
.mobile-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.mobile-nav a {
  padding: 14px 20px; text-decoration: none; font-weight: 600; color: var(--brand-text);
  border-bottom: 1px solid var(--brand-border); min-height: var(--touch); display: flex; align-items: center;
}

@media (min-width: 860px) {
  .site-nav { display: flex; }
  .menu-toggle { display: none; }
  .mobile-nav { display: none !important; }
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer { background: var(--brand-dark); color: #d8d8d8; margin-top: 3rem; }
.site-footer .muted { color: #9a9a9a; }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: 32px; padding-block: 3rem 2rem; }
.footer-brand p { margin-top: 14px; max-width: 32ch; font-size: 0.92rem; }
.site-footer h4 { color: #fff; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.site-footer a { color: #d8d8d8; text-decoration: none; font-size: 0.92rem; }
.site-footer a:hover { color: var(--brand-primary); }
.footer-bottom { border-top: 1px solid #262626; padding-block: 20px; }
.footer-bottom p { font-size: 0.82rem; }
@media (min-width: 700px) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; } }

/* ============================================================
   Hero / generic page header
   ============================================================ */
.hero { padding-top: clamp(1.5rem, 4vw, 3rem); }
.hero-grid { display: grid; gap: 28px; align-items: start; }
.hero-copy h1 { margin: 14px 0 14px; }
.lead { font-size: 1.05rem; max-width: 46ch; }
.lead code { background: var(--brand-accent); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 0.95fr 1.05fr; } }

.narrow { max-width: 760px; }

/* ============================================================
   Downloader tool
   ============================================================ */
.downloader {
  background: var(--brand-light);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: var(--shadow-md);
}
.input-row {
  display: flex; align-items: center; gap: 8px;
  background: var(--brand-bg); border: 2px solid var(--brand-border);
  border-radius: var(--radius-md); padding: 4px 6px 4px 16px;
  transition: border-color 0.15s ease;
}
.input-row:focus-within { border-color: var(--brand-primary); }
.input-row input {
  flex: 1; border: none; background: transparent; font-size: 1rem;
  min-height: var(--touch); outline: none; color: var(--brand-text);
}
.icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--radius-sm);
  border: none; background: transparent; color: var(--brand-muted); cursor: pointer;
}
.icon-btn:hover { color: var(--brand-primary); background: var(--brand-accent); }

.ytd-hint { font-size: 0.82rem; margin: 10px 2px 14px; }
.ytd-submit { margin-top: 2px; }

.ytd-status { min-height: 1.4em; margin: 14px 2px 0; font-size: 0.92rem; font-weight: 600; }
.ytd-status[data-state="error"] { color: var(--brand-primary); }
.ytd-status[data-state="loading"] { color: var(--brand-muted); }
.ytd-status[data-state="success"] { color: #1a7f37; }

.ytd-result { margin-top: 24px; border-top: 1px solid var(--brand-border); padding-top: 20px; }
.ytd-result-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.ytd-result-head h2 { font-size: 1.15rem; }
.ytd-video-id { font-size: 0.82rem; font-family: ui-monospace, monospace; }

.ytd-preview {
  display: block;
  max-width: 100%;
  max-height: 60vh;
  width: auto;
  height: auto;
  margin: 0 auto;
  border-radius: var(--radius-md);
  border: 1px solid var(--brand-border);
  background: var(--brand-bg);
}

.ytd-cards { display: flex; flex-direction: column; gap: 10px; margin: 18px 0; }
.ytd-card {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--brand-border); border-radius: var(--radius-md);
  padding: 10px; background: var(--brand-bg);
}
.ytd-card img {
  display: block;
  max-width: 96px;
  max-height: 96px;
  width: auto;
  height: auto;
  border-radius: 8px;
  flex-shrink: 0;
  background: #eee;
}
.ytd-card-info { flex: 1; min-width: 0; }
.ytd-card-info .label { font-weight: 700; font-size: 0.95rem; }
.ytd-card-info .dims { font-size: 0.8rem; color: var(--brand-muted); }
.ytd-card .btn { padding: 0 16px; min-height: 40px; font-size: 0.88rem; flex-shrink: 0; }

@media (max-width: 639px) {
  .ytd-card img { max-width: 72px; max-height: 72px; }
}

/* ============================================================
   Content sections (steps, benefits, table, FAQ, related links)
   ============================================================ */
.steps { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 18px; }
.steps li, .guide-steps li { display: flex; gap: 14px; align-items: flex-start; }
.step-num, .num {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 50%;
  background: var(--brand-accent); color: var(--brand-primary); font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 0.9rem;
}
.steps strong, .guide-steps strong { display: block; margin-bottom: 4px; }
.guide-steps { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 18px; }

.benefits { display: grid; gap: 18px; margin-top: 20px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.benefit h3 { margin-bottom: 6px; color: var(--brand-primary); }

.table-wrap { overflow-x: auto; margin-top: 18px; border: 1px solid var(--brand-border); border-radius: var(--radius-md); }
table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
th, td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--brand-border); }
thead th { background: var(--brand-bg); font-weight: 700; }
tbody tr:last-child td { border-bottom: none; }

.two-col { display: grid; gap: 28px; }
@media (min-width: 900px) { .two-col { grid-template-columns: 1fr 1fr; } }

.related-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.related-links a {
  text-decoration: none; font-weight: 600; font-size: 0.9rem;
  padding: 10px 16px; border-radius: var(--radius-pill);
  border: 1px solid var(--brand-border); background: var(--brand-light);
}
.related-links a:hover { border-color: var(--brand-primary); color: var(--brand-primary); }

/* FAQ */
.faq-list { margin-top: 20px; display: grid; gap: 10px; }
.faq-item { background: var(--brand-light); border: 1px solid var(--brand-border); border-radius: var(--radius-md); padding: 4px 18px; }
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 0; font-weight: 700; cursor: pointer; list-style: none; min-height: var(--touch);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item .chev { flex-shrink: 0; transition: transform 0.2s ease; color: var(--brand-muted); }
.faq-item[open] .chev { transform: rotate(180deg); color: var(--brand-primary); }
.faq-item p { padding-bottom: 16px; font-size: 0.95rem; }

/* Legal pages */
.legal h2 { margin-top: 26px; margin-bottom: 10px; }
.legal .small { font-size: 0.85rem; margin-top: 30px; }

/* 404 */
.not-found { text-align: center; padding-block: clamp(4rem, 12vw, 7rem); }
.not-found p { margin: 14px 0 26px; }
.actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

/* Contact */
.email { margin: 18px 0 8px; font-size: 1.1rem; font-weight: 700; }
.email a { color: var(--brand-primary); }

/* ============================================================
   Blog
   ============================================================ */
.blog-grid {
  display: grid;
  gap: 20px;
  margin-top: 24px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.blog-card {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--brand-light);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.blog-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.blog-card-thumb { aspect-ratio: 16 / 9; background: var(--brand-bg); overflow: hidden; }
.blog-card-thumb img { width: 100%; height: 100%; object-fit: cover; }
.blog-card-body { padding: 16px 18px 20px; }
.blog-date { font-size: 0.8rem; }
.blog-card-body h2, .blog-card-body h3 { font-size: 1.1rem; margin: 6px 0 8px; }
.blog-card-body p { font-size: 0.92rem; }

.blog-pagination { display: flex; gap: 10px; justify-content: center; margin-top: 32px; flex-wrap: wrap; }
.blog-pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; height: 40px; padding: 0 12px;
  border-radius: var(--radius-pill); border: 1px solid var(--brand-border);
  text-decoration: none; color: var(--brand-text); font-weight: 600; font-size: 0.9rem;
}
.blog-pagination .page-numbers.current { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.blog-pagination .page-numbers:hover:not(.current) { border-color: var(--brand-primary); color: var(--brand-primary); }

/* ------------------------------------------------------------------
   SINGLE POST — mobile hardening

   The article body is the one place on this site where the markup is
   not written by the theme: it comes from the editor or a WXR import.
   That means over-wide tables, raw iframes, long unbroken URLs, <pre>
   blocks and oversized images can all land inside it. Each of those
   widens the page rather than itself, which is why the single post view
   was the template breaking on phones. Everything below constrains the
   content to the column instead of letting it stretch the document.
   ------------------------------------------------------------------ */
.blog-post { max-width: 100%; min-width: 0; overflow-wrap: anywhere; }
.blog-post .eyebrow { display: block; margin-bottom: 10px; }

/* Long single words and URLs in a headline used to push the column
   wider than the screen. hyphens + break-word keeps them inside it, and
   the smaller clamp floor stops a 3-word title eating half the screen. */
.blog-post h1 {
  margin-bottom: 20px;
  font-size: clamp(1.6rem, 4.2vw + 0.7rem, 2.75rem);
  overflow-wrap: break-word;
  word-break: break-word;
  hyphens: auto;
}
.blog-post-thumb {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--brand-border);
  margin-bottom: 24px;
}
.blog-post-thumb img { width: 100%; height: auto; display: block; }

/* Load-triggered entrance (not scroll-gated, so it can never leave
   content stuck invisible): plays once automatically on page load. */
.blog-post .eyebrow,
.blog-post h1,
.blog-post-thumb {
  animation: fade-up 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.blog-post h1 { animation-delay: 0.08s; }
.blog-post-thumb { animation-delay: 0.16s; }
@keyframes fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .blog-post .eyebrow, .blog-post h1, .blog-post-thumb { animation: none; }
}
.blog-content {
  font-size: 1rem;
  line-height: 1.7;
  max-width: 100%;
  min-width: 0;
  overflow-wrap: break-word;
  word-break: break-word;
}
.blog-content > * { max-width: 100%; }
.blog-content p { margin-bottom: 1.2em; color: var(--brand-text); }
.blog-content h2, .blog-content h3 {
  margin: 1.6em 0 0.6em;
  overflow-wrap: break-word;
  /* Content headings inherited the sitewide clamp, which tops out at
     2.1rem — far too large inside a 16px article column on a phone. */
  font-size: clamp(1.3rem, 2.2vw + 0.85rem, 1.75rem);
}
.blog-content h3 { font-size: clamp(1.1rem, 1.2vw + 0.8rem, 1.3rem); }
.blog-content img {
  border-radius: var(--radius-md);
  margin-block: 0.5em;
  max-width: 100%;
  height: auto;   /* never let a width/height attr pair force an overflow */
}
.blog-content a { color: var(--brand-primary); overflow-wrap: anywhere; }
.blog-content ul, .blog-content ol { padding-left: 1.4em; margin-bottom: 1.2em; }
.blog-content li { overflow-wrap: break-word; }

/* Code and preformatted blocks: scroll internally, never widen the page. */
.blog-content pre {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 16px;
  background: #f4f4f5;
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  font-size: 0.85rem;
  line-height: 1.5;
}
.blog-content code { overflow-wrap: anywhere; font-size: 0.9em; }
.blog-content pre code { white-space: pre; overflow-wrap: normal; }

.blog-content blockquote {
  margin: 1.4em 0;
  padding: 2px 0 2px 16px;
  border-left: 3px solid var(--brand-primary);
  color: var(--brand-muted);
}

/* Imported tables and iframes get wrapped server-side (see
   ytd_wrap_wide_content() in functions.php) so the scroll/aspect box
   below always exists, even for content the theme never generated. */
.ytd-scroll-x {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 18px 0;
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
}
.ytd-scroll-x > table { margin: 0; border: 0; min-width: 460px; }

/* Generic embed: just stop it overflowing. Non-video embeds (maps,
   forms, dashboards) keep whatever height they declared. */
.ytd-embed { max-width: 100%; margin: 20px 0; }
.ytd-embed > iframe { max-width: 100%; width: 100%; border: 0; border-radius: var(--radius-md); }

/* Video embeds get a real responsive 16:9 box. The hardcoded
   width="560" height="315" that YouTube's embed code ships with is a
   fixed 560px — wider than most phones, and the single most common
   reason an imported article overflows its column. */
.ytd-embed--video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #000;
}
.ytd-embed--video > iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 0;
}

.blog-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.blog-tags .tag {
  font-size: 0.82rem; font-weight: 600; text-decoration: none;
  padding: 6px 14px; border-radius: var(--radius-pill);
  background: var(--brand-accent); color: var(--brand-primary);
}

/* Prev/next used to be a two-up flex row with max-width:45% at every
   size. On a phone that gives each link ~140px for a full post title,
   which either overflows or collapses into an unreadable sliver. Grid,
   stacked by default, side-by-side only when there's room. */
.post-nav {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--brand-border);
}
.post-nav-link {
  text-decoration: none;
  font-weight: 600;
  color: var(--brand-text);
  font-size: 0.95rem;
  line-height: 1.4;
  padding: 12px 14px;
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  background: var(--brand-light);
  overflow-wrap: break-word;
  min-width: 0;
}
.post-nav-link:hover { color: var(--brand-primary); border-color: var(--brand-primary); }
@media (min-width: 640px) {
  .post-nav { grid-template-columns: 1fr 1fr; }
  .post-nav-link.next { text-align: right; grid-column: 2; }
}

/* ============================================================
   Rating widget
   ============================================================ */
.ytd-rating {
  background: var(--brand-light);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  margin-top: 20px;
}
.ytd-rating-stars { display: flex; gap: 4px; }
.ytd-star {
  background: none; border: none; padding: 4px; cursor: pointer;
  color: var(--brand-border); transition: color 0.15s ease, transform 0.15s ease;
  min-width: 32px; min-height: 32px; display: inline-flex; align-items: center; justify-content: center;
}
.ytd-star:hover:not(:disabled) { transform: scale(1.1); }
.ytd-star.is-hover, .ytd-star.is-filled { color: var(--brand-primary); }
.ytd-rating.is-rated .ytd-star { cursor: default; }
.ytd-rating.is-rated .ytd-star:hover { transform: none; }
.ytd-rating-meta { margin-top: 8px; font-size: 0.9rem; font-weight: 600; }
.ytd-rating-average { color: var(--brand-primary); font-size: 1.1rem; }
.ytd-rating-status { min-height: 1.2em; margin-top: 6px; font-size: 0.82rem; }
.ytd-rating.is-loading { opacity: 0.7; pointer-events: none; }

/* ============================================================
   Live viewers / monthly views badges (single post)
   ============================================================ */
.post-engagement {
  display: flex; flex-wrap: wrap; gap: 16px;
  margin: 10px 0 24px; font-size: 0.85rem; color: var(--brand-muted);
}
.post-engagement .badge { display: inline-flex; align-items: center; gap: 6px; }
.post-engagement .dot-live {
  width: 8px; height: 8px; border-radius: 50%; background: #1a7f37;
  animation: pulse-live 1.6s ease-in-out infinite;
}
@keyframes pulse-live {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(26, 127, 55, 0.4); }
  50% { opacity: 0.6; box-shadow: 0 0 0 4px rgba(26, 127, 55, 0); }
}
@media (prefers-reduced-motion: reduce) { .post-engagement .dot-live { animation: none; } }

/* ============================================================
   Related articles (single post)
   ============================================================ */
.related-articles { margin-top: 48px; padding-top: 32px; border-top: 1px solid var(--brand-border); }
.related-articles h2 { margin-bottom: 18px; }

/* ============================================================
   Motion system — scroll reveal, hero decoration, hover polish.
   GPU-cheap (opacity/transform only), respects reduced motion,
   and content is visible-by-default so nothing depends on JS
   running for the page to be readable (progressive enhancement).
   ============================================================ */
.reveal { opacity: 1; transform: none; }

/* ------------------------------------------------------------------
   Reveal animation — opt-IN, not opt-out.

   Previously every .reveal-stagger child started at opacity:0 and was
   only un-hidden by JS, with a 2.2s CSS fallback. That is a direct Core
   Web Vitals penalty: if the Largest Contentful Paint element sits in a
   staggered group (the blog grid, the benefits row), it is literally
   invisible at first paint, so LCP is measured against whenever the
   deferred motion.js finally runs — or against the 2.2s fallback. Either
   way the score reflects the animation, not the page.

   Now the hidden start state only applies once motion.js has confirmed
   it is running (html.ytd-motion-ready). Content paints immediately on
   first load; the animation still plays for everything below the fold,
   which is where it was actually visible anyway.
   ------------------------------------------------------------------ */
.ytd-motion-ready .reveal-stagger > *:not(.is-visible-now) {
  opacity: 0;
  transform: translateY(14px);
}
.reveal-stagger > * {
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.reveal-stagger.is-visible > * { opacity: 1; transform: none; }
.reveal-stagger.is-visible > *:nth-child(1) { transition-delay: 0.02s; }
.reveal-stagger.is-visible > *:nth-child(2) { transition-delay: 0.08s; }
.reveal-stagger.is-visible > *:nth-child(3) { transition-delay: 0.14s; }
.reveal-stagger.is-visible > *:nth-child(4) { transition-delay: 0.2s; }
.reveal-stagger.is-visible > *:nth-child(5) { transition-delay: 0.26s; }
.reveal-stagger.is-visible > *:nth-child(6) { transition-delay: 0.32s; }
.reveal-stagger.is-visible > *:nth-child(7) { transition-delay: 0.38s; }
.reveal-stagger.is-visible > *:nth-child(8) { transition-delay: 0.44s; }
.reveal-stagger.is-visible > *:nth-child(9) { transition-delay: 0.5s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-stagger > * { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* JS-disabled fallback: if no-js is present on <html>, motion.js never
   ran to add is-visible, so content must still show. */
.no-js .reveal, .no-js .reveal-stagger > * { opacity: 1 !important; transform: none !important; }

/* Hero decoration — soft floating blobs, pure CSS, no images */
.hero { position: relative; overflow: hidden; }
.hero-blobs { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.hero-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(50px);
  opacity: 0.35;
  animation: float-blob 14s ease-in-out infinite;
}
.hero-blob-1 { width: 260px; height: 260px; background: var(--brand-primary); top: -60px; right: 8%; animation-delay: 0s; }
.hero-blob-2 { width: 200px; height: 200px; background: var(--brand-accent); bottom: -40px; left: 4%; animation-delay: -6s; }
.hero > .container { position: relative; z-index: 1; }

@keyframes float-blob {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-16px, 22px) scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-blob { animation: none; }
}

/* Animated underline on the eyebrow tag for a bit of life on load */
.eyebrow-animated { position: relative; }
.eyebrow-animated::after {
  content: "";
  position: absolute; left: 0; bottom: -4px;
  width: 32px; height: 2px; background: var(--brand-primary);
  animation: grow-line 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.3s both;
}
@keyframes grow-line { from { width: 0; } to { width: 32px; } }

/* Stat strip */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-top: 28px;
}
.stat {
  background: var(--brand-light);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.stat-num { font-size: 1.5rem; font-weight: 800; color: var(--brand-primary); line-height: 1; }
.stat-label { font-size: 0.78rem; color: var(--brand-muted); margin-top: 4px; }
@media (min-width: 640px) { .stat-strip { grid-template-columns: repeat(4, 1fr); } }

/* Card hover polish sitewide */
.benefit, .related-links a, .faq-item {
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.related-links a:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.faq-item:hover { border-color: var(--brand-primary); }

/* Button micro-interaction: subtle press + hover glow already present;
   add a gentle pulse the first time the primary CTA enters view */
@keyframes cta-pulse {
  0% { box-shadow: 0 0 0 0 rgba(221, 0, 0, 0.35); }
  100% { box-shadow: 0 0 0 14px rgba(221, 0, 0, 0); }
}
.cta-pulse-once.is-visible { animation: cta-pulse 1.2s ease-out 0.4s 1; }
@media (prefers-reduced-motion: reduce) { .cta-pulse-once.is-visible { animation: none; } }

/* Comparison table (SEO content block) */
.compare-wrap { overflow-x: auto; margin-top: 18px; border: 1px solid var(--brand-border); border-radius: var(--radius-md); }
.compare-wrap table { min-width: 480px; }
.compare-wrap td.yes { color: #1a7f37; font-weight: 700; }
.compare-wrap td.no { color: var(--brand-muted); }

/* ============================================================
   Ad slots (Customizer > Ads) — hard-contained so a pasted ad
   unit (fixed-width creative, oversized iframe, etc.) can never
   push page width or overlap surrounding content.
   ============================================================ */
.ytd-ad-slot {
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  margin: 28px auto;
  text-align: center;
  /* Reserve real space up front so the container isn't 0px while the GPT/
     AdX request is still resolving. A collapsed 0px slot is treated as
     non-viewable by demand partners, which causes them to skip the
     auction entirely and fall through to an unpriced house/PSA ad. These
     match the most common banner sizes (mobile 320x100 / desktop 728x90 or
     300x250) — adjust to match whatever sizes you actually request. */
  min-height: 100px;
}
@media (min-width: 768px) {
  .ytd-ad-slot { min-height: 250px; }
}
/* Only collapse the wrapper when no ad code was pasted into the
   Customizer at all (ytd_ad_slot() doesn't print the div in that case,
   so this is a defensive fallback, not the normal path). */
.ytd-ad-slot:empty { display: none; margin: 0; min-height: 0; }
/* flex-direction MUST be column: the "Advertisement" label is a child of
   this container, so a flex ROW put the label beside the creative instead
   of above it and stole horizontal space from the ad on narrow screens. */
.ytd-ad-slot { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 0; }
/* IMPORTANT: never CSS-scale an ad iframe's width without its height —
   GPT/AdX iframes carry a fixed height="" attribute, so shrinking only
   the width (the old rule here) squashes/distorts the creative on any
   viewport narrower than the ad's native size. That's what was causing
   "destroyed" ad sizing on mobile. Center it and let it render at its
   real, undistorted dimensions instead. If a slot is requesting a size
   too wide for mobile (e.g. a 728x90 leaderboard), fix that at the
   source with a responsive GPT sizeMapping for that ad unit — CSS
   should never be resizing the iframe itself. */
.ytd-ad-slot ins { max-width: 100%; }
.ytd-ad-slot img { max-width: 100%; height: auto; }
.ytd-ad-slot-label {
  display: block;
  width: 100%;
  text-align: center;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-muted);
  margin-bottom: 6px;
}

/* Use-case chips */
.use-cases { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.use-case-chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--brand-light); border: 1px solid var(--brand-border);
  border-radius: var(--radius-pill); padding: 8px 14px 8px 10px; font-size: 0.88rem; font-weight: 600;
}
.use-case-chip .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand-primary); flex-shrink: 0; }


/* ============================================================
   Paint budget — skip layout/paint work for off-screen blocks.

   content-visibility lets the browser skip rendering work for a subtree
   until it scrolls near the viewport. contain-intrinsic-size supplies a
   placeholder height so the scrollbar doesn't jump while it does that
   (no CLS). Applied only to blocks that are always below the fold.
   ============================================================ */
.related-articles,
.site-footer,
.faq-list {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

/* ============================================================
   Sitewide overflow containment for anything the theme doesn't
   author: pasted ad creatives, embedded widgets, imported markup.
   ============================================================ */
main, section, .container, article { min-width: 0; }
iframe, video, embed, object { max-width: 100%; }
pre, code, samp, kbd { overflow-wrap: anywhere; }
table { max-width: 100%; }

/* Header stays usable when a long site name / big logo is in play. */
.header-inner { gap: 12px; min-width: 0; }
.site-nav { min-width: 0; }
