/* ============================================================
   LUMA — Screens for Creators
   Design system: dark-mode-first, violet/pink/cyan studio-light
   gradient accents, glassmorphism dock, Sora + Inter type system.
   ============================================================ */

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
img, picture, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
button { background: none; border: none; cursor: pointer; }

/*
 * Hide the active theme's own header on every page this plugin
 * renders — get_header() (called by every templates/*.php file) always
 * renders it too, so without this every plugin page showed two headers
 * stacked on top of each other: the theme's own header, then our
 * luma-catnav bar right below it. Scoped for real by the fact that
 * this stylesheet itself only loads on pages this plugin controls
 * (luma_screens_should_load_assets()), not by anything on the selector
 * — this rule has zero effect on pages where our CSS isn't enqueued.
 * Two different selectors here because the live site's get_header()
 * turned out NOT to render Twenty Twenty-Five's block-based header
 * markup (header.wp-block-template-part, targeted by the first rule) —
 * it renders a classic-style #header/#headerimg block instead (with a
 * stray <hr> right after it), likely from a leftover header.php on the
 * server. Both are covered so this survives either markup.
 */
.wp-site-blocks > header.wp-block-template-part,
body > header.wp-block-template-part,
body > #page > #header[role="banner"],
body > #page > #header[role="banner"] + hr { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Tokens ---------- */
:root {
  color-scheme: dark;

  /*
   * Surfaces — a 4-tier ladder, each step a real, perceptible jump:
   *   --bg          page's outer margins (outside the content column)
   *   --bg-content  the center content column itself
   *   --surface     individual content boxes inside it (ad slots,
   *                 cards, sidebar widgets)
   *   --surface-2/3 hover/active states on top of a --surface box
   * First attempt at this ladder kept each step within ~1.16-1.2
   * contrast, reasoned as "clearly perceptible" from WCAG luminance
   * math — in practice that read as barely-differentiated grey, not a
   * real zone. bg-vs-content is now a decisive ~1.8 contrast jump
   * instead (surface-2/3 pulled back slightly from a first, even
   * bigger pass to keep --text-primary readable against --surface-3,
   * the lightest tier, above the ~3:1 WCAG floor for UI components).
   * .luma-container also gets an explicit border now, so the zone
   * boundary doesn't depend on color contrast being read correctly on
   * any given screen at all.
   */
  --bg: #181820;
  --bg-soft: #1c1c26;
  --bg-content: #42425c;
  --surface: #585876;
  --surface-2: #68688a;
  --surface-3: #78789e;
  --border: rgba(255,255,255,0.09);
  --border-strong: rgba(255,255,255,0.16);
  /* Requested exact color. Only declared once, here in the base
     :root -- the light theme no longer overrides it (the .footer rule
     forces the dark theme's own surface/text tokens too), so the
     footer stays this same dark color in both themes rather than
     switching to a lighter one under light theme. */
  --footer-bg: #1c2b31;

  /* Text */
  /*
   * --text-secondary/--text-tertiary lightened from their original
   * values (#a6a6bd / #6f6f88) — those were tuned against the
   * session's original, much darker surface ladder. Once --bg-content/
   * --surface/--surface-2/--surface-3 all got brighter (for the 3-tier
   * zone system and its later contrast pass), the *same* text colors
   * fell to as low as ~1.4:1 against --surface — text-tertiary is used
   * on card/sidebar/dropdown backgrounds (--surface) constantly, not
   * just --bg. These values hold ~3:1+ against --surface and ~4.5:1+
   * against --bg-content, verified via WCAG relative-luminance math,
   * not eyeballed.
   */
  --text-primary: #f6f6fa;
  --text-secondary: #d2d2e0;
  --text-tertiary: #afafc1;
  --text-on-accent: #0a0a12;

  /* Accents — studio light triad */
  --violet: #7c5cff;
  --violet-strong: #6238ff;
  --pink: #ff4fa3;
  --cyan: #22d3ee;
  --amber: #ffb020;
  --success: #34d399;
  --danger: #fb4d4d;

  --gradient-primary: linear-gradient(135deg, var(--violet) 0%, var(--pink) 52%, var(--cyan) 100%);
  --gradient-radial-glow: radial-gradient(circle at 30% 20%, rgba(124,92,255,0.35), transparent 55%),
                          radial-gradient(circle at 75% 75%, rgba(255,79,163,0.28), transparent 55%),
                          radial-gradient(circle at 85% 15%, rgba(34,211,238,0.22), transparent 50%);

  /* Type */
  --font-display: 'Sora', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', 'Consolas', monospace;

  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-md: 1rem;
  --fs-lg: 1.125rem;
  --fs-xl: 1.25rem;
  --fs-2xl: 1.5rem;
  --fs-3xl: 2rem;
  --fs-4xl: 2.75rem;
  --fs-5xl: 3.75rem;

  /* Spacing (4/8 rhythm) */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;
  --sp-16: 64px;
  --sp-20: 80px;
  --sp-24: 96px;

  /*
   * Real .luma-catnav height, measured and kept current by
   * catnav.js (it can wrap to two lines depending on viewport width
   * and how many nav items are present) — every sticky element that
   * needs to clear the header uses this instead of a guessed pixel
   * value, so a taller/wrapped header can never end up overlapped by
   * a sticky ad whose offset assumed a single-line header. 64px here
   * is only the pre-JS fallback.
   */
  --catnav-height: 64px;

  /* Radius */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --radius-full: 999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 150ms;
  --dur-med: 250ms;
  --dur-slow: 400ms;

  /* Elevation */
  --shadow-sm: 0 2px 8px rgba(0,0,0,0.24);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.32);
  --shadow-lg: 0 20px 60px rgba(0,0,0,0.45);
  --shadow-glow: 0 0 0 1px rgba(255,255,255,0.06), 0 20px 60px rgba(124,92,255,0.18);

  /* Glass */
  --glass-bg: rgba(20, 20, 32, 0.62);
  --glass-border: rgba(255,255,255,0.12);
  --glass-blur: blur(20px) saturate(140%);

  /* Z-index scale */
  --z-nav: 100;
  --z-dropdown: 200;
  --z-dock: 500;
  --z-overlay: 1000;
  --z-toast: 2000;

  --container: 1240px;
}

/* ---------- Light theme override ---------- */
:root[data-luma-theme="light"] {
  color-scheme: light;

  /*
   * --bg deliberately more grey than the old #f6f6fb (barely off-white,
   * left almost no perceptible room for a distinct --bg-content tier
   * before hitting pure-white --surface) — this also directly gives the
   * page's outer margins the "grey sides" look, with --bg-content
   * sitting as a subtle off-white step between --bg and pure-white
   * --surface content boxes.
   */
  --bg: #d8dbe5;
  --bg-soft: #ffffff;
  --bg-content: #edeef4;
  --surface: #ffffff;
  --surface-2: #eef0f6;
  --surface-3: #e2e4ee;
  --border: rgba(20,20,40,0.10);
  --border-strong: rgba(20,20,40,0.18);

  --text-primary: #15151f;
  --text-secondary: #52526b;
  /* Darkened from #7d7d94 — --bg also got more grey this session
     (#f6f6fb -> #d8dbe5), which took text-tertiary below the 3:1 floor
     against it (2.9:1). #5f5f76 holds ~4.5:1+ against every surface
     tier, verified via WCAG math. */
  --text-tertiary: #5f5f76;
  --text-on-accent: #ffffff;

  --gradient-radial-glow: radial-gradient(circle at 30% 20%, rgba(124,92,255,0.16), transparent 55%),
                          radial-gradient(circle at 75% 75%, rgba(255,79,163,0.13), transparent 55%),
                          radial-gradient(circle at 85% 15%, rgba(34,211,238,0.12), transparent 50%);

  --shadow-sm: 0 2px 8px rgba(20,20,40,0.08);
  --shadow-md: 0 8px 24px rgba(20,20,40,0.10);
  --shadow-lg: 0 20px 60px rgba(20,20,40,0.14);
  --shadow-glow: 0 0 0 1px rgba(20,20,40,0.05), 0 20px 60px rgba(124,92,255,0.16);

  --glass-bg: rgba(255,255,255,0.72);
  --glass-border: rgba(20,20,40,0.10);
}

/* ---------- Base ---------- */
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  overflow-x: hidden;
}

h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.15; letter-spacing: -0.01em; font-weight: 600; }

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/*
 * Deliberately scoped as .luma-container, not the generic .container —
 * that name collides with utility classes many WordPress themes ship
 * (e.g. Bootstrap-derived ones), and since the active theme's own
 * stylesheet loads independently of this plugin's, whichever one
 * happens to load later wins any colliding property (seen live: a
 * theme .container rule was injecting ~48px of unwanted top padding
 * here). A unique class name is immune regardless of theme.
 */
/*
 * Gives the center content column its own background (--bg-content)
 * distinct from both the page's outer margins (--bg, visible on wide
 * viewports on either side of this 1240px column) and the individual
 * content boxes inside it (--surface — ad slots, cards, sidebar
 * widgets), instead of all three being visually flat/undifferentiated.
 */
.luma-container {
  max-width: var(--container); margin-inline: auto; padding-inline: var(--sp-6);
  background: var(--bg-content);
  /* Explicit edge, not just a background-color difference — the zone
     boundary shouldn't depend on color contrast alone being visible. */
  border-left: 1px solid var(--border-strong); border-right: 1px solid var(--border-strong);
  /*
   * width: 100% (not just max-width) because .luma-single-shell wraps
   * this in a flex row alongside the ad rails (templates/single-
   * luma_screen.php) — as a flex item, max-width alone doesn't stretch
   * it to fill available space the way it does in normal block layout;
   * flex-basis defaults to the content's own shrink-to-fit size, which
   * left the whole content column ~170px narrower than intended on
   * single screen pages. Harmless outside a flex context, since block
   * elements already default to filling their parent's width anyway.
   */
  width: 100%;
}
@media (max-width: 640px) { .luma-container { padding-inline: var(--sp-4); } }

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

.skip-link {
  position: absolute; left: var(--sp-4); top: -60px;
  background: var(--surface-2); color: var(--text-primary);
  padding: var(--sp-3) var(--sp-5); border-radius: var(--radius-md);
  z-index: var(--z-toast); transition: top var(--dur-med) var(--ease-out);
  border: 1px solid var(--border-strong);
}
.skip-link:focus { top: var(--sp-4); }

/* Background ambience */
.bg-ambient {
  position: fixed; inset: 0; z-index: -1;
  background: var(--bg) var(--gradient-radial-glow);
  pointer-events: none;
}
.bg-noise {
  position: fixed; inset: 0; z-index: -1; opacity: 0.035; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 0.75rem 1.5rem; border-radius: var(--radius-full);
  font-weight: 600; font-size: var(--fs-sm); white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
  min-height: 44px;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: var(--gradient-primary); color: #fff;
  box-shadow: var(--shadow-glow);
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 24px 70px rgba(124,92,255,0.28), var(--shadow-glow); }
.btn-secondary {
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-primary);
}
.btn-secondary:hover { background: var(--surface-3); border-color: rgba(255,255,255,0.24); }
.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover { color: var(--text-primary); background: rgba(255,255,255,0.06); }
.btn-icon {
  width: 44px; height: 44px; border-radius: var(--radius-full); padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--border);
}
.btn-icon:hover { background: var(--surface-3); }
.btn-sm { padding: 0.5rem 1rem; font-size: var(--fs-xs); min-height: 36px; }

/* ---------- Nav ---------- */
.nav {
  position: sticky; top: 0; z-index: var(--z-nav);
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-4) var(--sp-6);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--border);
}
.nav-brand { display: flex; align-items: center; gap: var(--sp-2); font-family: var(--font-display); font-weight: 700; font-size: var(--fs-xl); }
.nav-brand .logo-mark {
  width: 32px; height: 32px; border-radius: 10px; background: var(--gradient-primary);
  display: inline-flex; align-items: center; justify-content: center; box-shadow: var(--shadow-glow);
}
.nav-links { display: flex; align-items: center; gap: var(--sp-8); }
.nav-links a { font-size: var(--fs-sm); font-weight: 500; color: var(--text-secondary); transition: color var(--dur-fast); }
.nav-links a:hover { color: var(--text-primary); }
.nav-actions { display: flex; align-items: center; gap: var(--sp-3); }
.nav-toggle { display: none; }

@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* ---------- Hero ---------- */
.hero {
  padding: var(--sp-10) 0 var(--sp-10);
  display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--sp-16); align-items: center;
}
@media (max-width: 960px) { .hero { grid-template-columns: 1fr; padding-top: var(--sp-8); gap: var(--sp-10); } }

.eyebrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-4); border-radius: var(--radius-full);
  background: rgba(124,92,255,0.12); border: 1px solid rgba(124,92,255,0.35);
  /* var(--violet), not a hardcoded light lavender (#c9baff) — that
     was tuned for dark backgrounds only and read as near-invisible
     pale-on-pale in the light theme, since this pill's own background
     is only 12% opaque and mostly shows the page background through. */
  color: var(--violet); font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  margin-bottom: var(--sp-5);
}
.eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 8px var(--cyan); }

.hero h1 { font-size: clamp(2.25rem, 5vw, var(--fs-5xl)); margin-bottom: var(--sp-5); }
.hero h1 .grad { background: var(--gradient-primary); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero p.lede { font-size: var(--fs-lg); color: var(--text-secondary); max-width: 46ch; margin-bottom: var(--sp-8); }
.hero-cta { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-10); }
.hero-stats { display: flex; gap: var(--sp-8); flex-wrap: wrap; }
.hero-stats .stat b { display: block; font-family: var(--font-display); font-size: var(--fs-2xl); }
.hero-stats .stat span { color: var(--text-tertiary); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.04em; }

/* Hero live preview panel — a carousel of one screen per category */
.hero-preview {
  position: relative; aspect-ratio: 4/3; border-radius: var(--radius-xl);
  border: 1px solid var(--border-strong); overflow: hidden; box-shadow: var(--shadow-lg);
  background: var(--surface);
}
.hero-preview-slide {
  position: absolute; inset: 0; display: block;
  opacity: 0; visibility: hidden; transition: opacity 0.6s ease;
}
.hero-preview-slide.is-active { opacity: 1; visibility: visible; }
.hero-preview-slide canvas, .hero-preview-slide .preview-fill, .hero-preview-slide .thumb-fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-preview-chrome {
  position: absolute; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-4); background: linear-gradient(to bottom, rgba(0,0,0,0.5), transparent);
  z-index: 2;
}
.hero-preview-dots { display: flex; gap: 6px; }
.hero-preview-dots span { width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,0.35); }
.hero-preview-label { font-size: var(--fs-xs); color: #fff; background: rgba(0,0,0,0.35); padding: 4px 10px; border-radius: var(--radius-full); backdrop-filter: blur(6px); }
/*
 * A screen can be flat solid white (or any other light color) behind
 * this caption, not just a photo — the original single soft gradient
 * (0.55 opacity fading to transparent) left white text unreadable
 * against a white thumb (this is exactly what happened with the
 * White Screen tool). Stronger, multi-stop scrim + text-shadow
 * guarantees contrast against literally any thumb color; the "Open"
 * button also gets its own opaque backing instead of relying on
 * theme surface tokens, which are near-white in the light theme.
 */
.hero-preview-caption {
  position: absolute; bottom: 0; left: 0; right: 0; padding: var(--sp-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  background: linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.6) 60%, rgba(0,0,0,0.05) 100%);
  z-index: 2;
}
/* min-width: 0 so this text column can actually shrink inside the flex
   row -- without it, a long post title pushes flush against (or under)
   the "Read ->" button on narrow screens instead of wrapping, since a
   flex item's default min-width is auto (its content's width), not 0. */
.hero-preview-caption > div { min-width: 0; }
.hero-preview-caption .btn { flex-shrink: 0; }
.hero-preview-caption strong { color: #fff; font-family: var(--font-display); font-size: var(--fs-md); text-shadow: 0 1px 4px rgba(0,0,0,0.5); }
.hero-preview-caption span { color: rgba(255,255,255,0.85); font-size: var(--fs-xs); text-shadow: 0 1px 4px rgba(0,0,0,0.5); }
.hero-preview-caption .btn-secondary {
  background: rgba(255,255,255,0.16); border: 1px solid rgba(255,255,255,0.3); color: #fff;
  backdrop-filter: blur(6px);
}
.hero-preview-caption .btn-secondary:hover { background: rgba(255,255,255,0.28); }

/* ---------- Section headers ---------- */
.section { padding: var(--sp-12) 0; }
.section[id] { scroll-margin-top: 90px; }
.section-header { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-6); margin-bottom: var(--sp-8); flex-wrap: wrap; }
.section-header h2 { font-size: clamp(1.6rem, 3vw, var(--fs-3xl)); }
.section-header p { color: var(--text-secondary); max-width: 56ch; margin-top: var(--sp-2); }
.section-kicker { color: var(--violet); font-weight: 600; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: var(--sp-2); display: block; }

/* ---------- Bento grid (category gallery) ---------- */
/* 3 columns (not 4) — this grid lives inside .page-main, alongside
   the sidebar, so its available width is narrower than the full
   container; 4 columns here would cramp each card. */
.bento {
  display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 170px; gap: var(--sp-4);
}
@media (max-width: 780px) { .bento { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 160px; } }
@media (max-width: 480px) { .bento { grid-template-columns: 1fr; grid-auto-rows: 140px; } }

.bento-card {
  position: relative; border-radius: var(--radius-lg); padding: var(--sp-5);
  border: 1px solid var(--border); background: var(--surface);
  background-size: cover; background-position: center;
  display: flex; flex-direction: column; justify-content: flex-end;
  overflow: hidden; isolation: isolate;
  transition: transform var(--dur-med) var(--ease-out), border-color var(--dur-med), box-shadow var(--dur-med);
}
.bento-card:hover { transform: translateY(-4px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.bento-card::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(165deg, rgba(8,8,13,0.2) 0%, rgba(8,8,13,0.55) 55%, rgba(8,8,13,0.92) 100%);
}
.bento-card .bento-icon {
  width: 42px; height: 42px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.16); margin-bottom: auto;
  font-size: 1.1rem; backdrop-filter: blur(6px);
}
.bento-card h3 { font-size: var(--fs-lg); margin-bottom: 2px; color: #fff; }
.bento-card p { color: rgba(255,255,255,0.72); font-size: var(--fs-xs); }
.bento-card .bento-count { position: absolute; top: var(--sp-4); right: var(--sp-4); font-size: var(--fs-xs); color: #fff; background: rgba(0,0,0,0.35); padding: 2px 10px; border-radius: var(--radius-full); backdrop-filter: blur(6px); }

.bento-card.span-2 { grid-column: span 2; }
.bento-card.span-2row { grid-row: span 2; }
@media (max-width: 560px) { .bento-card.span-2 { grid-column: span 1; } .bento-card.span-2row { grid-row: span 1; } }

/* ---------- Tool grid + card ---------- */
.tool-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--sp-4);
}
.tool-card {
  position: relative; border-radius: var(--radius-lg); border: 1px solid var(--border);
  background: var(--surface); overflow: hidden; text-align: left; width: 100%;
  transition: transform var(--dur-med) var(--ease-out), border-color var(--dur-med), box-shadow var(--dur-med);
  display: flex; flex-direction: column;
}
.tool-card:hover { transform: translateY(-3px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.tool-card:active { transform: translateY(-1px) scale(0.99); }
.tool-thumb {
  position: relative; aspect-ratio: 16/10; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.tool-thumb .thumb-fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tool-thumb .thumb-play {
  position: relative; z-index: 2; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(0,0,0,0.35); backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center;
  color: #fff; opacity: 0; transform: scale(0.85); transition: all var(--dur-fast) var(--ease-out);
  border: 1px solid rgba(255,255,255,0.3);
}
.tool-card:hover .thumb-play { opacity: 1; transform: scale(1); }
.tool-badge {
  position: absolute; top: var(--sp-2); left: var(--sp-2); z-index: 2;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 8px; border-radius: var(--radius-full); background: rgba(0,0,0,0.45); color: #fff; backdrop-filter: blur(4px);
}
.tool-badge.live { background: var(--danger); }
.tool-badge.new { background: var(--gradient-primary); }
.tool-body { padding: var(--sp-4); display: flex; flex-direction: column; gap: 2px; flex: 1; }
.tool-body h4 { font-size: var(--fs-sm); font-weight: 600; }
.tool-body span { font-size: var(--fs-xs); color: var(--text-tertiary); }

.filter-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-8); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--sp-2) var(--sp-4); border-radius: var(--radius-full); border: 1px solid var(--border-strong);
  background: var(--surface-2); font-size: var(--fs-xs); font-weight: 600; color: var(--text-secondary);
  transition: all var(--dur-fast) var(--ease-out); min-height: 36px;
}
.chip:hover { color: var(--text-primary); border-color: rgba(255,255,255,0.3); }
.chip.active { background: var(--gradient-primary); color: #fff; border-color: transparent; }

/* ---------- Quick Launch (solid colors & light) ---------- */
/*
 * Fixed columns (not auto-fill) so 9 swatches split predictably into
 * 5 + 4 across two rows instead of however many happen to fit the
 * available width — that also freed up the right-hand space for
 * quick-launch-ad-rail below, which used to be dead whitespace.
 */
.quick-launch-layout {
  display: grid; grid-template-columns: 1fr; gap: var(--sp-6);
}
@media (min-width: 1024px) {
  .quick-launch-layout { grid-template-columns: minmax(0, 1fr) 300px; align-items: start; }
}
.quick-launch-ad-rail .ad-slot { width: 100%; max-width: 300px; margin-inline: auto; }
@media (min-width: 1024px) {
  /* position: sticky (not fixed) — it holds its place in normal flow
     and scrolls away once quick-launch-layout ends, rather than
     floating on top of whatever content comes after it. Offset is
     the *real* header height (--catnav-height, kept current by
     catnav.js) plus a little breathing room, not a guessed pixel
     value — otherwise a header that wraps to two lines on some
     viewport would let this sit under/behind the second row of nav
     items instead of below it. */
  .quick-launch-ad-rail { position: sticky; top: calc(var(--catnav-height) + var(--sp-4)); }
}
.quick-launch-grid {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-4);
}
@media (max-width: 860px) { .quick-launch-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 640px) { .quick-launch-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 420px) { .quick-launch-grid { grid-template-columns: repeat(2, 1fr); } }
.quick-swatch {
  position: relative; display: flex; flex-direction: column;
  border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface);
  transition: transform var(--dur-med) var(--ease-out), border-color var(--dur-med) var(--ease-out), box-shadow var(--dur-med) var(--ease-out);
}
.quick-swatch:hover {
  transform: translateY(-5px);
  border-color: var(--swatch-glow, var(--border-strong));
  box-shadow: 0 18px 40px -14px var(--swatch-glow, rgba(124,92,255,0.5)), var(--shadow-md);
}
.quick-swatch-thumb { position: relative; aspect-ratio: 1; }
.quick-swatch-thumb .thumb-fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.quick-swatch-label {
  padding: var(--sp-3); font-size: var(--fs-sm); font-weight: 600; text-align: center;
}

/* ---------- Category nav bar (site-wide category explorer) ---------- */
.luma-catnav {
  position: relative; z-index: var(--z-dropdown);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--border);
}
.luma-catnav-inner {
  max-width: var(--container); margin-inline: auto; padding: var(--sp-3) var(--sp-6);
  display: flex; align-items: center; gap: var(--sp-5);
}
@media (max-width: 640px) { .luma-catnav-inner { padding: var(--sp-3) var(--sp-4); } }
.luma-catnav-brand {
  display: flex; align-items: center; flex-shrink: 0;
}
.luma-logo {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-lg); letter-spacing: -0.02em;
  background: linear-gradient(90deg, #7c5cff, #ff4fa3, #22d3ee, #ffb020, #7c5cff);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  animation: luma-logo-shift 6s linear infinite;
}
.luma-logo-tld {
  font-weight: 600; background: none;
  color: var(--text-tertiary); -webkit-text-fill-color: var(--text-tertiary);
}
@keyframes luma-logo-shift {
  to { background-position: 300% 50%; }
}
/*
 * Job-based buckets (Work & Focus, Fun, Essentials, Create & Stream)
 * instead of one dropdown listing all 12 categories flat — that flat
 * list already exists on the homepage bento grid and every page's
 * sidebar, so cramming it into the header too was a junk-drawer menu.
 * Each bucket is its own small toggle + dropdown pair
 * (luma_screens_print_category_nav() in includes/assets.php); Kids and
 * Blog are plain links since they don't need a submenu.
 */
.luma-catnav-mobile-toggle {
  display: none; flex-shrink: 0; margin-left: auto;
  width: 40px; height: 40px; border-radius: var(--radius-full);
  align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-primary);
}
.luma-catnav-mobile-toggle:hover,
.luma-catnav-mobile-toggle[aria-expanded="true"] { background: var(--surface-3); }
.luma-catnav-menu {
  display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap;
  /* Extra breathing room beyond .luma-catnav-inner's own gap, nudging
     the menu away from the logo instead of hugging it. */
  margin-left: var(--sp-10);
}
/*
 * Below 900px the 6 top-level items (4 bucket dropdowns + Kids + Blog)
 * no longer fit on one line — flex-wrap used to just let the header
 * grow to however many lines that took (up to ~270px tall on a phone,
 * more than a third of the screen before any page content appeared).
 * This collapses it into a single hamburger toggle (assets/catnav.js)
 * that reveals the same items as a stacked drawer instead.
 */
@media (max-width: 900px) {
  .luma-catnav-mobile-toggle { display: inline-flex; }
  .luma-catnav-menu {
    display: none; flex-direction: column; align-items: stretch; gap: 2px;
    margin-left: 0; width: 100%;
    position: absolute; left: 0; right: 0; top: 100%; z-index: var(--z-dropdown);
    padding: var(--sp-3); background: var(--surface); border-top: 1px solid var(--border);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg); box-shadow: var(--shadow-lg);
    max-height: calc(100dvh - var(--catnav-height)); overflow-y: auto;
  }
  .luma-catnav-menu.is-open { display: flex; }
  .luma-catnav-item, .luma-catnav-link { width: 100%; }
  .luma-catnav-link, .luma-catnav-toggle { justify-content: space-between; width: 100%; }
  /* Dropdowns become an inline accordion under their toggle instead of
     a floating absolute popup, since the menu itself is now a full-
     width drawer rather than a horizontal bar. */
  .luma-catnav-dropdown {
    position: static; margin-top: 0; min-width: 0; box-shadow: none;
    border: none; background: var(--surface-2); border-radius: var(--radius-md);
  }
}
.luma-catnav-item { position: relative; }
.luma-catnav-link, .luma-catnav-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-full);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.luma-catnav-link:hover, .luma-catnav-toggle:hover { background: var(--surface-2); color: var(--text-primary); }
.luma-catnav-toggle svg { transition: transform var(--dur-fast) var(--ease-out); }
.luma-catnav-toggle[aria-expanded="true"] { background: var(--surface-2); color: var(--text-primary); }
.luma-catnav-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.luma-catnav-dropdown {
  position: absolute; top: 100%; left: 0; margin-top: var(--sp-2); z-index: var(--z-dropdown);
  min-width: 240px; display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: var(--sp-2);
}
.luma-catnav-dropdown[hidden] { display: none; }
.luma-catnav-dropdown-item {
  display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-md); transition: background var(--dur-fast);
}
.luma-catnav-dropdown-item:hover { background: var(--surface-2); }
.luma-catnav-dropdown-icon {
  width: 32px; height: 32px; border-radius: var(--radius-md); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); font-size: 1rem;
}
.luma-catnav-dropdown-item strong { display: block; font-size: var(--fs-sm); color: var(--text-primary); }
.luma-catnav-dropdown-item small { display: block; font-size: var(--fs-xs); color: var(--text-tertiary); }

/*
 * ---------- Header search ----------
 * A single icon button that expands into a search field + live results
 * dropdown (assets/search.js queries the CPT's own public REST route),
 * pushed to the far right of the header via margin-left:auto since
 * .luma-catnav-menu doesn't grow to fill the row on its own.
 */
.luma-catnav-search { position: relative; margin-left: auto; flex-shrink: 0; }
.luma-catnav-search-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--radius-full);
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-secondary);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.luma-catnav-search-toggle:hover,
.luma-catnav-search-toggle[aria-expanded="true"] { background: var(--surface-3); color: var(--text-primary); }

.luma-catnav-search-panel {
  position: absolute; top: calc(100% + var(--sp-2)); right: 0; z-index: var(--z-dropdown);
  width: min(360px, 90vw);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: var(--sp-2);
}
.luma-catnav-search-panel[hidden] { display: none; }
.luma-catnav-search-field {
  position: relative; display: flex; align-items: center;
  color: var(--text-tertiary);
}
/* top:50%/translateY, not align-items:center on the flex parent --
   position:absolute takes the svg out of flow, so flex alignment
   never applied to it; it was falling back to its static position
   (near the top of the field, overlapping the placeholder text). */
.luma-catnav-search-field svg { position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%); pointer-events: none; }
.luma-catnav-search-input {
  /* var(--sp-9) here was a typo -- that step doesn't exist in the
     spacing scale (...--sp-8: 32px, --sp-10: 40px..., nothing in
     between), so the whole padding shorthand was invalid at computed-
     value time and collapsed to 0. With no left padding reserved, the
     placeholder text started under the icon instead of clearing it --
     the actual cause of the reported misalignment, not a vertical
     centering issue (fixed separately below on the icon itself).
     --sp-10 (40px) clears the 16px icon at left:12px with a bit of
     breathing room after it. */
  width: 100%; height: 44px; padding: 0 var(--sp-8) 0 var(--sp-10);
  background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  color: var(--text-primary); font-size: var(--fs-md);
}
.luma-catnav-search-input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.luma-catnav-search-input::placeholder { color: var(--text-tertiary); }
/* Visible "ajax loader" while a search request is in flight, not a
   silent instant swap. */
.luma-catnav-search-spinner {
  position: absolute; right: var(--sp-3);
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--text-secondary);
  animation: luma-search-spin 700ms linear infinite;
}
.luma-catnav-search-spinner[hidden] { display: none; }
@keyframes luma-search-spin { to { transform: rotate(360deg); } }

.luma-catnav-search-results {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: var(--sp-2); max-height: 60vh; overflow-y: auto;
}
.luma-catnav-search-results[hidden] { display: none; }
.luma-catnav-search-result {
  display: block; padding: var(--sp-3); border-radius: var(--radius-md);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-primary);
  transition: background var(--dur-fast) var(--ease-out);
}
.luma-catnav-search-result:hover, .luma-catnav-search-result.is-active { background: var(--surface-2); }
.luma-catnav-search-empty { padding: var(--sp-4) var(--sp-3); font-size: var(--fs-sm); color: var(--text-tertiary); text-align: center; }
@media (max-width: 640px) {
  .luma-catnav-search-panel { position: fixed; top: var(--catnav-height); left: var(--sp-4); right: var(--sp-4); width: auto; }
}

/* ---------- Page shell: breadcrumb, two-column layout, sidebar ---------- */
.luma-breadcrumb {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--text-tertiary); margin-bottom: var(--sp-4);
}
.luma-breadcrumb a { color: var(--text-secondary); transition: color var(--dur-fast); }
.luma-breadcrumb a:hover { color: var(--text-primary); }
.luma-archive-lede { color: var(--text-secondary); font-size: var(--fs-lg); max-width: 60ch; margin-top: var(--sp-3); }

.page-layout {
  display: grid; grid-template-columns: 1fr; gap: var(--sp-10);
  padding: var(--sp-10) 0;
}
@media (min-width: 1024px) {
  .page-layout { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
}
.page-main { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-12); }

.page-sidebar { display: flex; flex-direction: column; gap: var(--sp-6); }
@media (min-width: 1024px) { .page-sidebar { position: sticky; top: calc(var(--catnav-height) + var(--sp-4)); } }
.sidebar-widget {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--sp-5);
}
.sidebar-widget h3 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-tertiary); margin-bottom: var(--sp-4); }
.sidebar-widget ul { display: flex; flex-direction: column; gap: var(--sp-1); }
.sidebar-widget li a {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2); border-radius: var(--radius-sm); font-size: var(--fs-sm);
  color: var(--text-secondary); transition: background var(--dur-fast), color var(--dur-fast);
}
.sidebar-widget li a:hover { background: var(--surface-2); color: var(--text-primary); }
.sidebar-widget li a .swatch { width: 16px; height: 16px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.25); flex-shrink: 0; }
.sidebar-widget .sidebar-category-list li a { justify-content: space-between; }
.sidebar-widget .sidebar-category-list li a span:last-child { color: var(--text-tertiary); font-size: var(--fs-xs); }
.sidebar-ad { margin: 0 auto; }

/*
 * Article body typography (the_content() output on both a Screen's
 * article and — new — blog posts). Had zero rules of its own, so it
 * fell through to this stylesheet's own aggressive base reset
 * (a{color:inherit;text-decoration:none}, ul[class]{list-style:none},
 * headings/p{margin:0}) — meaning links were literally
 * indistinguishable from surrounding text and any list WordPress gave
 * a class (common from the block editor) lost its bullets/numbers
 * entirely. This is the fix: a full prose stylesheet scoped to
 * `.luma-article` so it never touches the app-chrome elsewhere that
 * the base reset is actually meant for.
 */
.luma-article { color: var(--text-secondary); font-size: var(--fs-md); line-height: 1.7; }
.luma-article > *:first-child { margin-top: 0; }
.luma-article p { margin: 0 0 var(--sp-5); }
.luma-article h2, .luma-article h3, .luma-article h4 {
  color: var(--text-primary); margin: var(--sp-10) 0 var(--sp-4); line-height: 1.25;
}
.luma-article h2 { font-size: var(--fs-2xl); }
.luma-article h3 { font-size: var(--fs-xl); }
.luma-article h4 { font-size: var(--fs-lg); }
.luma-article a { color: var(--cyan); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(34,211,238,0.4); transition: text-decoration-color var(--dur-fast); }
.luma-article a:hover { text-decoration-color: currentColor; }
.luma-article ul, .luma-article ol {
  margin: 0 0 var(--sp-5); padding-left: 1.4em; display: flex; flex-direction: column; gap: var(--sp-2);
}
.luma-article ul { list-style: disc; }
.luma-article ol { list-style: decimal; }
.luma-article li { padding-left: var(--sp-1); }
.luma-article li::marker { color: var(--violet); }
.luma-article li > ul, .luma-article li > ol { margin-top: var(--sp-2); }
.luma-article strong, .luma-article b { color: var(--text-primary); font-weight: 700; }
.luma-article em, .luma-article i { font-style: italic; }
.luma-article blockquote {
  margin: var(--sp-6) 0; padding: var(--sp-4) var(--sp-6); border-left: 3px solid var(--violet);
  background: var(--surface); border-radius: 0 var(--radius-md) var(--radius-md) 0; color: var(--text-primary);
}
.luma-article blockquote p:last-child { margin-bottom: 0; }
.luma-article code {
  font-family: var(--font-mono); font-size: 0.9em; background: var(--surface-2);
  padding: 0.15em 0.45em; border-radius: var(--radius-sm); color: var(--cyan);
}
.luma-article pre {
  margin: 0 0 var(--sp-5); padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); overflow-x: auto;
}
.luma-article pre code { background: none; padding: 0; color: var(--text-secondary); }
.luma-article img { border-radius: var(--radius-lg); margin: var(--sp-6) 0; }
.luma-article hr { border: none; border-top: 1px solid var(--border); margin: var(--sp-8) 0; }
.luma-article table { width: 100%; border-collapse: collapse; margin: 0 0 var(--sp-5); }
.luma-article th, .luma-article td { padding: var(--sp-3); border-bottom: 1px solid var(--border); text-align: left; }
.luma-article th { color: var(--text-primary); font-weight: 600; }

/*
 * FAQ content is plain post-body HTML (typed straight into the editor,
 * not a structured block) -- assets/faq-accordion.js finds an "FAQ"
 * H2 followed by H3 questions and rewrites them into native <details>
 * elements at runtime. Native <details>/<summary> gets keyboard
 * support, ARIA semantics, and toggle behavior for free; this only
 * needs to style the result. First item starts open (set by the JS)
 * so the section doesn't read as empty before anyone's clicked.
 */
/* This class also lands on RankMath SEO's own .rank-math-list element
   (assets/faq-accordion.js adds it there rather than creating a fresh
   wrapper) -- reset in case that plugin ships its own list/padding
   defaults, so this always fully controls the layout regardless. */
.luma-faq-accordion { list-style: none; padding: 0; margin: var(--sp-10) 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.luma-faq-item {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden;
}
.luma-faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5); cursor: pointer; list-style: none;
  font-size: var(--fs-md); font-weight: 700; color: var(--text-primary);
  transition: background var(--dur-fast) var(--ease-out);
}
.luma-faq-item summary::-webkit-details-marker { display: none; }
.luma-faq-item summary:hover { background: var(--surface-2); }
.luma-faq-item summary:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }
.luma-faq-chevron { flex-shrink: 0; display: flex; color: var(--text-tertiary); transition: transform var(--dur-fast) var(--ease-out); }
.luma-faq-item[open] .luma-faq-chevron { transform: rotate(180deg); }
.luma-faq-answer { padding: 0 var(--sp-5) var(--sp-5); color: var(--text-secondary); }
.luma-faq-answer p:last-child { margin-bottom: 0; }

/*
 * WordPress's own the_posts_pagination() markup: <nav class="navigation
 * pagination"><div class="nav-links">…</div></nav>. Scoped under
 * .pagination (not just .nav-links) since .nav-links is also this
 * stylesheet's own site-header link list — an unscoped rule here would
 * have bled into the header nav.
 */
.pagination { margin-top: var(--sp-10); display: flex; justify-content: center; }
.pagination .nav-links { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); flex-wrap: wrap; }
.pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 42px; height: 42px; padding: 0 var(--sp-4);
  border-radius: var(--radius-full); border: 1px solid var(--border-strong);
  background: var(--surface-2); color: var(--text-secondary);
  font-size: var(--fs-sm); font-weight: 600;
  transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.pagination a.page-numbers:hover { color: var(--text-primary); border-color: rgba(255,255,255,0.3); background: var(--surface-3); transform: translateY(-1px); }
.pagination .page-numbers.current { background: var(--gradient-primary); color: #fff; border-color: transparent; box-shadow: var(--shadow-glow); }
.pagination .page-numbers.dots { background: transparent; border-color: transparent; color: var(--text-tertiary); min-width: 20px; }
.pagination .page-numbers.next, .pagination .page-numbers.prev { padding: 0 var(--sp-5); }

/* ---------- Blog: post cards, single-post meta, 404 search ---------- */
.post-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-4); }
.post-card {
  position: relative; border-radius: var(--radius-lg); border: 1px solid var(--border);
  background: var(--surface); overflow: hidden; display: flex; flex-direction: column;
  transition: transform var(--dur-med) var(--ease-out), border-color var(--dur-med), box-shadow var(--dur-med);
}
.post-card:hover { transform: translateY(-3px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.post-card-thumb { position: relative; aspect-ratio: 16/9; overflow: hidden; background: var(--surface-2); }
.post-card-thumb .thumb-fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.post-card-thumb-fallback { display: flex; align-items: center; justify-content: center; background: var(--gradient-primary); }
.post-card-thumb-fallback span { font-family: var(--font-display); font-weight: 800; font-size: 2.5rem; color: rgba(255,255,255,0.85); }
.post-card-cat {
  position: absolute; top: var(--sp-3); left: var(--sp-3); z-index: 2;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 10px; border-radius: var(--radius-full); background: rgba(0,0,0,0.55); color: #fff; backdrop-filter: blur(4px);
}
.post-card-body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; }
.post-card-body h3 { font-size: var(--fs-lg); color: var(--text-primary); line-height: 1.3; }
.post-card-body p { font-size: var(--fs-sm); color: var(--text-secondary); flex: 1; line-height: 1.55; }
/* Matched search-term highlight (templates/blog-search.php via
   luma_screens_highlight_terms()) -- background wash rather than the
   browser's default yellow-on-black <mark>, which reads harshly
   against this dark surface. */
.search-highlight { background: rgba(124,92,255,0.28); color: var(--text-primary); border-radius: 3px; padding: 0 2px; }
.post-card-meta { font-size: var(--fs-xs); color: var(--text-tertiary); margin-top: auto; padding-top: var(--sp-2); }

.post-meta-row { display: flex; align-items: center; gap: var(--sp-2); color: var(--text-tertiary); font-size: var(--fs-sm); margin: var(--sp-3) 0; }
.post-meta-cat { color: var(--violet); font-weight: 600; }
.post-featured-image { border-radius: var(--radius-xl); overflow: hidden; margin-bottom: var(--sp-8); }
.post-featured-image img { width: 100%; height: auto; display: block; }
.post-tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-6) 0; }

/* Thin fixed bar under the header, filled via JS (assets/blog-
   article.js) as the reader scrolls through .luma-article -- a
   lightweight "how much is left" cue for long articles. */
.reading-progress {
  /* One below --z-dropdown (200), not --z-dock (500) -- the category
     nav's dropdown panels extend below the header into this same
     strip, and at --z-dock this thin bar would render on top of and
     visually slice through an open dropdown. */
  position: fixed; top: var(--catnav-height); left: 0; right: 0; z-index: calc(var(--z-dropdown) - 1);
  height: 3px; background: transparent; pointer-events: none;
}
.reading-progress-bar { height: 100%; width: 0%; background: var(--gradient-primary); transition: width 100ms linear; }

/* Author + share sit in one row: byline pushed left, share actions
   pushed right, matching the meta row's own left-aligned rhythm above
   it rather than stacking as two separate full-width blocks. */
.post-byline-row {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-4);
  padding: var(--sp-4) 0; margin-bottom: var(--sp-6);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.post-byline { display: flex; align-items: center; gap: var(--sp-3); }
.post-byline img { border-radius: 50%; flex-shrink: 0; }
.post-byline-label { display: block; font-size: var(--fs-xs); color: var(--text-tertiary); }
.post-byline-name { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--text-primary); }
.post-share { display: flex; align-items: center; gap: var(--sp-2); }
.post-share-btn {
  /* 44px, not 36px -- matches .btn-icon's touch-target size used
     everywhere else in this codebase (e.g. the fullscreen overlay's
     exit button), rather than introducing a smaller one-off. */
  display: inline-flex; align-items: center; gap: var(--sp-2);
  width: 44px; height: 44px; padding: 0; border-radius: var(--radius-full);
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-secondary);
  font-size: var(--fs-xs); font-weight: 600; overflow: hidden; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), width var(--dur-med) var(--ease-out);
}
.post-share-btn svg { flex-shrink: 0; margin-inline: 14px; }
.post-share-btn:hover { background: var(--surface-3); color: var(--text-primary); }
/* The copy-link button grows to fit "Copy link" / "Copied!" text; the
   share-to-X button stays icon-only (span-less), so only this one
   needs the width transition to actually show. */
#articleShareCopy { width: auto; padding-right: var(--sp-4); }
#articleShareCopy.is-copied { background: rgba(52,211,153,0.16); border-color: rgba(52,211,153,0.4); color: var(--success); }

.post-author-card {
  display: flex; gap: var(--sp-4); align-items: flex-start;
  margin: var(--sp-8) 0; padding: var(--sp-5); border-radius: var(--radius-lg);
  background: var(--surface); border: 1px solid var(--border);
}
.post-author-card img { border-radius: 50%; flex-shrink: 0; }
.post-author-card strong { display: block; color: var(--text-primary); margin-bottom: var(--sp-1); }
.post-author-card p { font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.6; margin: 0; }

.post-adjacent-nav { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); margin: var(--sp-8) 0; }
.post-adjacent-link {
  display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-4);
  border-radius: var(--radius-lg); border: 1px solid var(--border); background: var(--surface);
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.post-adjacent-link:hover { border-color: var(--border-strong); transform: translateY(-2px); }
.post-adjacent-next { text-align: right; align-items: flex-end; }
.post-adjacent-kicker { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-tertiary); }
.post-adjacent-title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-primary); line-height: 1.4; }
@media (max-width: 640px) { .post-adjacent-nav { grid-template-columns: 1fr; } }

/* Sidebar widget, hidden by default and only revealed by JS once it's
   actually populated with >=2 headings (assets/blog-article.js) --
   never shows an empty "On this page" box for a short article.
   .page-sidebar .article-toc (not just .article-toc), and li.article-
   toc-h3 (not just .article-toc-h3) -- .article-toc also carries
   .sidebar-widget for its box styling, and .sidebar-widget li a's own
   padding rule otherwise wins the specificity tie against a plainer
   .article-toc a selector, silently flattening the h2/h3 indent. */
.article-toc ul { display: flex; flex-direction: column; gap: 2px; list-style: none; }
.page-sidebar .article-toc li a {
  display: block; padding: 6px var(--sp-3); border-radius: var(--radius-md);
  font-size: var(--fs-sm); color: var(--text-secondary); border-left: 2px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.page-sidebar .article-toc li.article-toc-h3 a { padding-left: var(--sp-6); font-size: var(--fs-xs); }
.page-sidebar .article-toc li a:hover { color: var(--text-primary); background: var(--surface-2); }
.page-sidebar .article-toc li a.is-active { color: var(--violet); border-left-color: var(--violet); font-weight: 600; background: var(--surface-2); }

/* Category/tag/date/author archive header -- reuses .hero's own
   layout/eyebrow/heading rules, just single-column (no side preview
   like blog-home's hero has) and shorter vertical padding since an
   archive page needs to get to the post grid quickly. */
.hero-archive { grid-template-columns: 1fr; padding-bottom: var(--sp-6); }
.hero-archive h1 { font-size: clamp(2rem, 4vw, var(--fs-4xl)); }
.luma-archive-lede-html { font-size: var(--fs-lg); color: var(--text-secondary); max-width: 60ch; }
.luma-archive-lede-html p { margin: 0 0 var(--sp-3); }
.luma-archive-lede-html p:last-child { margin-bottom: 0; }

.sidebar-note { color: var(--text-tertiary); font-size: var(--fs-sm); line-height: 1.5; }
.sidebar-note a { color: var(--cyan); }

.section-empty { padding: var(--sp-16) 0; text-align: center; color: var(--text-secondary); }
.section-empty .hero-cta { justify-content: center; margin-top: var(--sp-6); }

.hero-404 { grid-template-columns: 1fr; max-width: 760px; }
.search-form-404 { display: flex; gap: var(--sp-3); max-width: 480px; margin-bottom: var(--sp-6); }
.search-form-404 input {
  flex: 1; min-width: 0; padding: 0.75rem 1.25rem; border-radius: var(--radius-full); border: 1px solid var(--border-strong);
  background: var(--surface-2); color: var(--text-primary); font-size: var(--fs-sm);
}
.search-form-404 input::placeholder { color: var(--text-tertiary); }
.search-form-404 input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ---------- Use cases / testimonial cards ---------- */
.usecase-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
@media (max-width: 860px) { .usecase-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .usecase-grid { grid-template-columns: 1fr; } }
.usecase-card {
  padding: var(--sp-6); border-radius: var(--radius-lg); background: var(--surface); border: 1px solid var(--border);
}
.usecase-card .avatar {
  width: 40px; height: 40px; border-radius: 50%; background: var(--gradient-primary); margin-bottom: var(--sp-4);
  display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; color: #fff; font-size: var(--fs-sm);
}
.usecase-card p { color: var(--text-secondary); font-size: var(--fs-sm); margin-bottom: var(--sp-4); }
.usecase-card .who { font-size: var(--fs-xs); color: var(--text-tertiary); font-weight: 600; }

/*
 * The active theme's own default site-credit ("... is proudly powered
 * by WordPress") and the <hr> before it — rendered by the theme's own
 * footer.php via get_footer(), not by this plugin, and this repo has
 * no access to the active theme's files to remove it at the source.
 * #footer is the theme's own element id (unrelated to .footer below,
 * this plugin's own footer class) confirmed via the live page's raw
 * HTML, so this is a precise hide, not a blanket rule.
 */
#footer[role="contentinfo"] { display: none; }
hr:has(+ #footer) { display: none; }

/*
 * The "Ask AI" chat widget's message input -- also a third-party
 * plugin's own element (.chatbot-footer__input), the only <textarea>
 * findable anywhere on the public site. Its default height (52px,
 * rows="2") meant most typed messages wrapped to more visible lines
 * than needed before the panel's own auto-grow (up to 150px) kicked
 * in. If this isn't the textarea that was meant, it's a narrow,
 * reversible override -- easy to point at the right element instead.
 */
.chatbot-footer__input { min-height: 72px !important; }

/*
 * ---------- Footer ----------
 * Deliberately NOT .luma-container — that class now carries the
 * lighter center-column background + border (see the 3-tier system
 * above), and the footer should stay dark, sitting directly on body's
 * own --bg like the outer margins do (it renders as a normal-flow
 * sibling after .luma-container closes, on every template). This
 * wrapper only borrows the same max-width/centering/padding so footer
 * content lines up with the reading column above it.
 */
/*
 * Re-declares the dark theme's own surface/text tokens, scoped to
 * .footer, so the footer stays the same dark anchor in both themes
 * instead of following light theme's own (light) palette -- every
 * child rule below still just reads var(--surface)/var(--text-*)/etc,
 * this is the only place that needs to know about the override.
 */
.footer {
  position: relative;
  --surface: #585876;
  --surface-2: #68688a;
  --border: rgba(255,255,255,0.09);
  --border-strong: rgba(255,255,255,0.16);
  --text-primary: #f6f6fa;
  --text-secondary: #d2d2e0;
  --text-tertiary: #afafc1;
  background: var(--footer-bg);
  padding: var(--sp-10) 0 var(--sp-6);
}
/* Thin brand-gradient accent instead of a plain border-top — the same
   gradient used everywhere else (logo, primary buttons, hero heading)
   so the footer reads as part of the same brand, not a bolted-on
   afterthought. */
.footer::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--gradient-primary); opacity: 0.7;
}
.footer-inner { max-width: var(--container); margin-inline: auto; padding-inline: var(--sp-6); }
@media (max-width: 640px) { .footer-inner { padding-inline: var(--sp-4); } }

/*
 * Brand block + social sit in their own row above the link sitemap —
 * repeats the wordmark and states what the site actually is one more
 * time at the point of exit, instead of the footer being 100% link
 * list with no identity of its own.
 */
/* Used to be a flex row splitting brand vs. social (space-between
   left a lot of dead width once social moved into the 4-column area
   below) -- just a block now, brand/tagline free to use the full
   container width. */
.footer-top {
  position: relative;
  padding-bottom: var(--sp-8); margin-bottom: var(--sp-8);
}
/* A fading gradient rule instead of a flat edge-to-edge border — the
   flat line read as a leftover default-HTML <hr>, not something
   actually designed. Fades in/out at both ends instead of terminating
   abruptly at the container edge. */
.footer-top::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-strong) 20%, var(--border-strong) 80%, transparent);
}
.footer-brand-logo { display: inline-flex; }
/* Full container width, not the old 46ch cap that forced this short
   tagline onto 3 lines with a large empty gap beside it -- at the
   container's actual width this fits on one line. */
.footer-tagline { color: var(--text-secondary); font-size: var(--fs-sm); line-height: 1.6; margin-top: var(--sp-3); white-space: nowrap; }
@media (max-width: 760px) { .footer-tagline { white-space: normal; } }

/*
 * Not a sitemap of all 79+ tools anymore — full discoverability
 * already comes from RankMath's XML sitemap, the category archive
 * pages, and each screen's own "related screens" section, none of
 * which depend on the footer. A footer link dump crammed with 90+
 * items, wrapped inline with middot separators to keep it from
 * ballooning, didn't actually work as a link list -- hard to scan,
 * hard to tell where one item ends and the next begins. Four plain
 * columns instead (Categories, Popular Screens, More Favorites,
 * Follow), one link per line. Categories shows the top 6 by tool
 * count plus a "view all" link, not all 12. The 12-item curated
 * "popular" list is split across two columns purely to balance the
 * layout against that -- not two semantically different lists.
 */
.footer-links-row { display: grid; grid-template-columns: repeat(4, minmax(140px, 1fr)); gap: var(--sp-6); margin-bottom: var(--sp-6); }
@media (max-width: 960px) { .footer-links-row { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px) { .footer-links-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .footer-links-row { grid-template-columns: 1fr; } }

.footer-col h5 {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  /* One tier lighter than the original --text-tertiary -- explicit
     request for brighter footer text, and this already holds strong
     contrast against --footer-bg (#1c2b31). */
  color: var(--text-secondary); margin-bottom: var(--sp-3);
}
.footer-col-list { display: flex; flex-direction: column; gap: 2px; }
.footer-col-list li a {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; font-size: 13px; font-weight: 600; color: var(--text-primary);
}
.footer-col-list li a:hover { color: var(--violet); }
.footer-link-group-icon { font-size: 12px; line-height: 1; }
.footer-view-all { color: var(--cyan) !important; }
/* Space before the "Follow" heading when a Company link list (About,
   Privacy Policy, etc.) is stacked above it in the same column. */
.footer-company-list + h5 { margin-top: var(--sp-5); }

/* The 3rd column: a small vertical stack of icon buttons (shares
   .footer-col for its heading). Only rendered when at least one
   social URL is configured (Tools -> Luma Screens) -- never
   fabricated links. */
.footer-social-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.footer-social-list a {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-md);
  font-size: 13px; font-weight: 600; color: var(--text-primary);
  background: var(--surface); transition: background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.footer-social-list a:hover { background: var(--surface-2); transform: translateX(2px); }
.footer-social-list svg { flex-shrink: 0; }

.footer-bottom {
  position: relative;
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--sp-4);
  padding-top: var(--sp-6);
  color: var(--text-tertiary); font-size: var(--fs-xs);
}
.footer-bottom::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-strong) 20%, var(--border-strong) 80%, transparent);
}
.footer-bottom a { color: var(--text-tertiary); }
.footer-bottom a:hover { color: var(--text-primary); }
.footer-bottom a:hover { color: var(--text-primary); }

/* ============================================================
   FULLSCREEN TOOL OVERLAY
   ============================================================ */
.overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay); background: #000;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-slow) var(--ease-out);
}
.overlay.active { opacity: 1; pointer-events: auto; }
.overlay-stage { position: absolute; inset: 0; overflow: hidden; }
.overlay-stage canvas, .overlay-stage .stage-fill { position: absolute; inset: 0; width: 100%; height: 100%; }

/*
 * The overlay is a fullscreen tool stage whose background can be
 * anything from pure black (Matrix Rain) to pure white (White Screen),
 * so its chrome (exit button, label, dock, hint) is deliberately pinned
 * to fixed dark values below rather than the site's --glass-bg/
 * --text-* variables, which flip to a near-white "light" palette when
 * the page-level theme toggle is on — that previously left every dock
 * control (labels, slider, buttons, select) white-on-near-white.
 */
.overlay-exit {
  position: absolute; top: var(--sp-5); left: var(--sp-5); z-index: 5;
  opacity: 0; transition: opacity var(--dur-med) var(--ease-out);
  /*
   * color was missing here — the SVG's stroke="currentColor" was
   * quietly inheriting the page's theme-dependent --text-primary
   * instead of a fixed value, so it rendered near-black (and nearly
   * invisible against this button's own dark background) whenever the
   * light theme toggle was on. Also bumped background opacity — 0.55
   * wasn't enough backing against a bright/white tool background like
   * White Screen or a light section of a gradient.
   */
  color: #fff; background: rgba(15, 15, 24, 0.78); border: 1px solid rgba(255,255,255,0.28);
  box-shadow: 0 2px 10px rgba(0,0,0,0.35);
}
.overlay-exit:hover { background: rgba(40, 40, 56, 0.88); }
.overlay.controls-visible .overlay-exit,
.overlay-exit:focus-visible { opacity: 1; }

.overlay-label {
  position: absolute; top: var(--sp-5); right: var(--sp-5); z-index: 5;
  font-size: var(--fs-xs); color: rgba(255,255,255,0.85); background: rgba(0,0,0,0.45);
  padding: 6px 14px; border-radius: var(--radius-full); backdrop-filter: blur(8px);
  opacity: 0; transition: opacity var(--dur-med) var(--ease-out);
}
.overlay.controls-visible .overlay-label { opacity: 1; }

.overlay-dock {
  position: absolute; left: 50%; bottom: var(--sp-8); transform: translate(-50%, 12px);
  z-index: var(--z-dock); display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  max-width: min(92vw, 780px); justify-content: center;
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-lg);
  background: rgba(18, 18, 28, 0.82); backdrop-filter: blur(20px) saturate(140%); -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.14); box-shadow: var(--shadow-lg);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-med) var(--ease-out), transform var(--dur-med) var(--ease-out);
}
.overlay.controls-visible .overlay-dock { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }

.dock-group { display: flex; align-items: center; gap: var(--sp-2); padding-inline: var(--sp-2); }
.dock-group + .dock-group { border-left: 1px solid rgba(255,255,255,0.16); }
.dock-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255,255,255,0.8); margin-right: 2px; }

.overlay-dock .btn-secondary, .overlay-dock .btn-icon {
  background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.2); color: #fff;
}
.overlay-dock .btn-secondary:hover, .overlay-dock .btn-icon:hover { background: rgba(255,255,255,0.18); }
.overlay-dock .btn-secondary.active { background: var(--gradient-primary); border-color: transparent; }

.swatch {
  width: 26px; height: 26px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.25);
  transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast);
  flex-shrink: 0;
}
.swatch:hover { transform: scale(1.1); }
.swatch.active { border-color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,0.2); }

.overlay-dock input[type="range"] {
  -webkit-appearance: none; appearance: none; width: 100px; height: 4px; border-radius: var(--radius-full);
  background: rgba(255,255,255,0.25); outline: none;
}
.overlay-dock input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: #fff; cursor: pointer;
  box-shadow: 0 0 0 3px rgba(124,92,255,0.5);
}
.overlay-dock input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%; background: #fff; border: none; cursor: pointer;
  box-shadow: 0 0 0 3px rgba(124,92,255,0.5);
}
.overlay-dock input[type="color"] {
  -webkit-appearance: none; width: 30px; height: 30px; border: none; border-radius: 50%; overflow: hidden; background: none; cursor: pointer;
}
.overlay-dock input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.overlay-dock input[type="color"]::-webkit-color-swatch { border: 2px solid rgba(255,255,255,0.35); border-radius: 50%; }

/* min-height 40px, not the 32px this used to be — these are the
   primary controls for actually using a tool (color, timer, text),
   so undersizing them on touch devices matters more than most other
   chrome on the site. */
.overlay-dock select, .overlay-dock .num-input, .overlay-dock input[type="text"] {
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); color: #fff;
  border-radius: var(--radius-sm); padding: 6px 10px; font-size: var(--fs-xs); min-height: 40px;
}
.overlay-dock .num-input { width: 64px; }
.overlay-dock .num-input-wide { width: 90px; }
.overlay-dock input[type="text"] { width: 140px; }
.overlay-dock input[type="text"]::placeholder { color: rgba(255,255,255,0.4); }

.overlay-hint {
  position: absolute; left: 50%; top: var(--sp-6); transform: translateX(-50%);
  font-size: var(--fs-xs); color: rgba(255,255,255,0.85); background: rgba(0,0,0,0.45);
  padding: 6px 14px; border-radius: var(--radius-full); backdrop-filter: blur(8px);
  z-index: 5; text-align: center;
  opacity: 0; transition: opacity var(--dur-med) var(--ease-out);
}
.overlay.controls-visible .overlay-hint { opacity: 1; }

/* ---------- Text-template overlay content ---------- */
.stage-center {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: var(--sp-5); padding: var(--sp-6); z-index: 2;
}
.stage-badge {
  display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-5);
  border-radius: var(--radius-full); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  font-size: var(--fs-sm);
}
.stage-badge.rec { background: rgba(251,77,77,0.15); color: var(--danger); border: 1px solid rgba(251,77,77,0.4); }
.stage-badge .pulse-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--danger); animation: pulseDot 1.2s ease-in-out infinite; }
@keyframes pulseDot { 0%,100% { opacity: 1; transform: scale(1);} 50% { opacity: 0.35; transform: scale(0.8);} }

.stage-title { font-family: var(--font-display); font-weight: 700; font-size: clamp(2rem, 6vw, 4.5rem); color: #fff; text-shadow: 0 4px 30px rgba(0,0,0,0.4); }
.subgoal-channel { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.1rem, 2.6vw, 1.6rem); color: rgba(255,255,255,0.85); }
.stage-subtitle { font-size: clamp(1rem, 2vw, 1.35rem); color: rgba(255,255,255,0.75); max-width: 46ch; }
.stage-timer { font-family: var(--font-mono); font-size: clamp(2.5rem, 8vw, 6rem); color: #fff; font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }

.stage-progress-track { width: min(70vw, 480px); height: 10px; border-radius: var(--radius-full); background: rgba(255,255,255,0.15); overflow: hidden; }
.stage-progress-fill { height: 100%; border-radius: var(--radius-full); background: var(--gradient-primary); transition: width var(--dur-slow) var(--ease-out); }

.stage-spinner {
  width: 56px; height: 56px; border-radius: 50%;
  border: 4px solid rgba(255,255,255,0.2); border-top-color: #fff; animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.stage-neon {
  font-family: var(--font-display); font-weight: 700; font-size: clamp(2.5rem, 8vw, 6rem); letter-spacing: 0.08em;
  color: #fff; text-shadow: 0 0 10px currentColor, 0 0 30px currentColor, 0 0 60px currentColor;
  animation: neonFlicker 3s infinite;
}
@keyframes neonFlicker {
  0%, 19%, 21%, 23%, 54%, 56%, 100% { opacity: 1; }
  20%, 22%, 55% { opacity: 0.55; }
}

.breathing-circle {
  width: 160px; height: 160px; border-radius: 50%;
  background: var(--gradient-primary); box-shadow: 0 0 80px rgba(124,92,255,0.5);
  animation: breathe 8s ease-in-out infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(0.7); }
  50% { transform: scale(1.15); }
}

.stage-quote { font-family: var(--font-display); font-size: clamp(1.9rem, 5.2vw, 3.5rem); color: #fff; max-width: 32ch; font-weight: 700; line-height: 1.28; }
.stage-quote-author { color: rgba(255,255,255,0.65); font-size: var(--fs-md); }
.stage-quote.quote-animated {
  background: linear-gradient(90deg, var(--violet), var(--pink), var(--cyan), var(--amber), var(--violet));
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: quoteColorShift 12s linear infinite;
}
@keyframes quoteColorShift { to { background-position: 300% 0; } }

.flipclock { display: flex; gap: var(--sp-3); }
.flip-unit { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
.flip-card {
  font-family: var(--font-mono); font-size: clamp(2.5rem, 8vw, 5.5rem); font-weight: 700; color: #fff;
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.14);
  padding: 0 var(--sp-4); border-radius: var(--radius-md); min-width: 1.4em; text-align: center;
  font-variant-numeric: tabular-nums;
}
.flip-unit span { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.5); }

.vu-meters { display: flex; gap: 6px; align-items: flex-end; height: 90px; }
.vu-bar { width: 10px; border-radius: 4px; background: var(--gradient-primary); animation: vuBounce 1s ease-in-out infinite; }
@keyframes vuBounce { 0%,100% { height: 20%; } 50% { height: 90%; } }

.dvd-logo {
  position: absolute; font-family: var(--font-display); font-weight: 800; font-size: 2.2rem;
  color: var(--pink); padding: var(--sp-3) var(--sp-5); border: 3px solid currentColor; border-radius: var(--radius-md);
  will-change: transform;
}

.crack-overlay { position: absolute; inset: 0; z-index: 3; mix-blend-mode: screen; opacity: 0.9; }
.shake { animation: shakeScreen 0.4s ease-in-out; }
@keyframes shakeScreen {
  0%, 100% { transform: translate(0,0); }
  20% { transform: translate(-6px, 4px); }
  40% { transform: translate(6px, -4px); }
  60% { transform: translate(-4px, -2px); }
  80% { transform: translate(4px, 2px); }
}

.hacker-term {
  position: absolute; inset: 0; background: #000; color: #3dff5e; font-family: var(--font-mono);
  font-size: clamp(12px, 1.4vw, 16px); padding: var(--sp-8); overflow: hidden; line-height: 1.6; z-index: 2;
  white-space: pre-wrap;
}

.update-screen { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-6); z-index: 2; }
.update-percent { font-family: var(--font-body); font-size: var(--fs-lg); }

/* ---------- AI & Machine Learning screens ---------- */
.ai-orb {
  width: 140px; height: 140px; border-radius: 50%;
  background: conic-gradient(from 0deg, var(--violet), var(--pink), var(--cyan), var(--violet));
  box-shadow: 0 0 90px rgba(124,92,255,0.55);
  animation: aiOrbPulse 2.6s ease-in-out infinite, aiOrbSpin 7s linear infinite;
}
@keyframes aiOrbPulse { 0%, 100% { transform: scale(0.9); } 50% { transform: scale(1.08); } }
@keyframes aiOrbSpin { to { transform: rotate(360deg); } }

.ai-think-dots { display: inline-flex; gap: 5px; margin-left: var(--sp-2); vertical-align: middle; }
.ai-think-dots span, .ai-type-dots span {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--cyan); animation: dotBounce 1.2s ease-in-out infinite;
}
.ai-think-dots span:nth-child(2), .ai-type-dots span:nth-child(2) { animation-delay: 0.15s; }
.ai-think-dots span:nth-child(3), .ai-type-dots span:nth-child(3) { animation-delay: 0.3s; }
.ai-type-dots { display: flex; gap: var(--sp-3); }
.ai-type-dots span { width: 22px; height: 22px; background: var(--gradient-primary); }
@keyframes dotBounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.5; } 30% { transform: translateY(-14px); opacity: 1; } }

.robot-face {
  width: 220px; height: 180px; border-radius: var(--radius-xl);
  background: var(--surface-2); border: 2px solid rgba(34,211,238,0.4);
  box-shadow: 0 0 60px rgba(34,211,238,0.35);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-6);
}
.robot-eyes { display: flex; gap: var(--sp-6); }
.robot-eye { width: 28px; height: 28px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 20px var(--cyan); transition: transform 120ms var(--ease-out); }
.robot-face.blink .robot-eye { transform: scaleY(0.12); }
.robot-mouth { display: flex; gap: 4px; align-items: flex-end; height: 24px; }
.robot-mouth span { width: 6px; border-radius: 3px; background: var(--pink); animation: vuBounce 0.9s ease-in-out infinite; }
.robot-mouth span:nth-child(2) { animation-delay: 0.1s; }
.robot-mouth span:nth-child(3) { animation-delay: 0.2s; }
.robot-mouth span:nth-child(4) { animation-delay: 0.3s; }
.robot-mouth span:nth-child(5) { animation-delay: 0.4s; }

.scan-frame { position: relative; width: min(70vw, 420px); aspect-ratio: 1; }
.scan-corner { position: absolute; width: 28px; height: 28px; border: 3px solid var(--success); }
.scan-corner.tl { top: 0; left: 0; border-right: none; border-bottom: none; }
.scan-corner.tr { top: 0; right: 0; border-left: none; border-bottom: none; }
.scan-corner.bl { bottom: 0; left: 0; border-right: none; border-top: none; }
.scan-corner.br { bottom: 0; right: 0; border-left: none; border-top: none; }
.scan-line {
  position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, transparent, var(--success), transparent);
  box-shadow: 0 0 20px var(--success);
  animation: scanMove 2.4s ease-in-out infinite;
}
@keyframes scanMove { 0%, 100% { top: 0; } 50% { top: calc(100% - 3px); } }

.ai-warning-bg { background: radial-gradient(circle at 50% 40%, rgba(255,176,32,0.28), #1a0f05 65%); animation: warningPulse 2s ease-in-out infinite; }
@keyframes warningPulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.25); } }
.ai-warning-icon { color: var(--amber); }

.ai-prompt-wrap { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--sp-6); padding: var(--sp-10) max(var(--sp-10), 12vw); z-index: 2; }
.ai-prompt-line { font-family: var(--font-mono); color: var(--cyan); font-size: clamp(1rem, 2vw, 1.35rem); }
.ai-prompt-answer { font-family: var(--font-body); color: #fff; font-size: clamp(1.25rem, 2.6vw, 2rem); line-height: 1.5; max-width: 62ch; }
.ai-cursor { display: inline-block; width: 3px; height: 1em; background: var(--pink); vertical-align: -0.15em; animation: cursorBlink 0.9s step-end infinite; }
@keyframes cursorBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* ---------- Windows Update screen (Windows 10 style) ---------- */
.win-update { gap: var(--sp-4); }
.win-spinner { position: relative; width: 44px; height: 44px; margin-bottom: var(--sp-2); }
.win-spinner i { position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; border-radius: 50%; background: #fff; margin: -3.5px; opacity: 0.25; animation: winDot 1.4s linear infinite; }
.win-spinner i:nth-child(1) { transform: rotate(0deg) translate(19px); animation-delay: 0s; }
.win-spinner i:nth-child(2) { transform: rotate(72deg) translate(19px); animation-delay: 0.14s; }
.win-spinner i:nth-child(3) { transform: rotate(144deg) translate(19px); animation-delay: 0.28s; }
.win-spinner i:nth-child(4) { transform: rotate(216deg) translate(19px); animation-delay: 0.42s; }
.win-spinner i:nth-child(5) { transform: rotate(288deg) translate(19px); animation-delay: 0.56s; }
@keyframes winDot { 0%, 100% { opacity: .2; } 50% { opacity: 1; } }
.win-update-title { font-family: var(--font-body); font-weight: 600; font-size: clamp(1.3rem, 2.6vw, 1.75rem); color: #fff; }
.win-update-percent { font-family: var(--font-body); font-size: clamp(1rem, 1.8vw, 1.2rem); color: #fff; font-weight: 400; margin-top: -8px; }
.win-update-warn { font-size: var(--fs-sm); color: #fff; margin-top: var(--sp-4); font-weight: 400; }

/* ---------- Productivity ---------- */
.stopwatch-laps { display: flex; flex-direction: column; gap: 4px; font-family: var(--font-mono); color: rgba(255,255,255,0.6); font-size: var(--fs-sm); max-height: 140px; overflow-y: auto; }
.stage-center.subtle-timer .stage-badge,
.stage-center.subtle-timer .stage-timer { opacity: 0.16; font-size: 0.85rem; transition: opacity var(--dur-med) var(--ease-out); }
.stage-center.subtle-timer { justify-content: flex-end; align-items: flex-end; gap: 2px; }
.stage-center.subtle-timer:hover .stage-badge,
.stage-center.subtle-timer:hover .stage-timer,
.stage-center.subtle-timer:focus-within .stage-badge,
.stage-center.subtle-timer:focus-within .stage-timer { opacity: 0.95; font-size: 1rem; }
.btn-secondary.active { background: var(--gradient-primary); color: #fff; border-color: transparent; }

/* ---------- Distraction-Free Pomodoro: blunt, monochrome, no motion ---------- */
.pomodoro-blunt .stage-badge {
  background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.5);
  border: 1px solid rgba(255,255,255,0.12); font-weight: 600;
}
.pomodoro-blunt .stage-timer { color: #63636a; text-shadow: none; }
.pomodoro-blunt .stage-subtitle { color: rgba(255,255,255,0.4); }

/* ---------- Fun: world landmarks ---------- */
.landmarks-wrap { position: absolute; inset: 0; }
.landmark-frame {
  position: absolute; inset: 0; overflow: hidden; transition: opacity 500ms ease;
  display: flex; align-items: flex-end; justify-content: center;
  background: linear-gradient(180deg, #1b1b3a 0%, #3a2e5c 35%, #cf6d5a 65%, #2a1f1a 100%);
}
.landmark-frame.kenburns .landmark-silhouette { animation: kenburns 7s ease-out forwards; }
@keyframes kenburns { from { transform: scale(1) translateY(0); } to { transform: scale(1.08) translateY(-1%); } }
.landmark-silhouette { width: min(60vw, 420px); color: #0b0b14; opacity: 0.92; filter: drop-shadow(0 -10px 40px rgba(0,0,0,0.3)); }
.landmark-silhouette svg { width: 100%; height: auto; display: block; }
.landmark-caption { position: absolute; bottom: 56px; left: 50%; transform: translateX(-50%); z-index: 3; color: #fff; font-family: var(--font-display); font-size: var(--fs-lg); text-shadow: 0 4px 20px rgba(0,0,0,0.5); }

/* ---------- Kids screens (light, colorful, fun) ---------- */
.kids-bg-warm { background: linear-gradient(135deg, #fff3c4 0%, #ffd8a8 45%, #ffb4c6 100%); }
.kids-bg-pink { background: linear-gradient(135deg, #ffe1f0 0%, #ffc2e6 45%, #d9c2ff 100%); }
.kids-bg-cyan { background: linear-gradient(135deg, #d3f7ff 0%, #bdeaff 45%, #d6ffe4 100%); }
.kids-bubbles { position: absolute; inset: 0; overflow: hidden; z-index: 1; pointer-events: none; }
.kids-bubbles span {
  position: absolute; bottom: -80px; border-radius: 50%;
  background: rgba(255,255,255,0.55); animation: kidsFloat linear infinite;
}
@keyframes kidsFloat { to { transform: translateY(-115vh); } }

.kids-number { font-family: var(--font-display); font-size: clamp(5rem, 20vw, 10rem); color: #3a1d5c; font-weight: 800; text-shadow: 0 2px 0 rgba(255,255,255,0.5); }
.kids-number.pop, .kids-shape-wrap.pop, .kids-letter.pop { animation: kidsPop 0.5s var(--ease-out); }
@keyframes kidsPop { 0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.kids-stars { display: flex; gap: 8px; flex-wrap: wrap; max-width: 60vw; justify-content: center; }
.kids-stars span { font-size: 2rem; color: #e08a00; text-shadow: 0 0 10px rgba(255,224,102,0.8); }
.kids-shape-label { font-family: var(--font-display); font-size: clamp(1.8rem, 4vw, 2.75rem); color: #3a1d4a; font-weight: 700; }
.kids-letter { font-family: var(--font-display); font-size: clamp(6rem, 22vw, 11rem); font-weight: 800; text-shadow: 0 2px 0 rgba(255,255,255,0.5); }
.kids-word { font-size: clamp(1.25rem, 3vw, 2rem); color: #103a3a; font-weight: 600; }

/* ---------- Women Power (girly theme) ---------- */
.girly-bg {
  background:
    radial-gradient(circle at 25% 20%, rgba(255,159,209,0.35), transparent 55%),
    radial-gradient(circle at 80% 30%, rgba(255,214,140,0.28), transparent 55%),
    radial-gradient(circle at 60% 80%, rgba(216,163,255,0.28), transparent 55%),
    #1a0a16;
}

/* ---------- Ad slots ---------- */
.ad-slot {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius-md);
  color: var(--text-tertiary); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em;
  overflow: hidden;
}
.ad-slot::before { content: "Advertisement"; }

/*
 * .luma-single-shell (templates/single-luma_screen.php) lays the two
 * rails and the article out side by side in normal flow — position:
 * sticky, not fixed. Fixed positioning is removed from the document
 * entirely and floats at a viewport-relative spot regardless of what
 * else is there, which is exactly how this used to end up overlapping
 * open nav dropdowns and other ad slots. Sticky still tracks scroll,
 * but respects layout: it can't cover a sibling, and it stops sticking
 * once its own container (the shell) scrolls out of view.
 */
.luma-single-shell {
  display: flex; justify-content: center; align-items: flex-start; gap: var(--sp-6);
}
.ad-rail {
  position: sticky; top: calc(var(--catnav-height) + var(--sp-4));
  width: 160px; height: 600px; flex-shrink: 0;
}
@media (max-width: 1680px) { .ad-rail { display: none; } }

.ad-leaderboard { width: 100%; max-width: 728px; min-height: 90px; margin: var(--sp-10) auto; }
.page-main > .ad-leaderboard:first-child { margin-top: 0; }

/* ---------- Toast ---------- */
.toast {
  position: fixed; bottom: var(--sp-6); left: 50%; transform: translateX(-50%) translateY(20px);
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-primary);
  padding: var(--sp-3) var(--sp-5); border-radius: var(--radius-md); font-size: var(--fs-sm);
  box-shadow: var(--shadow-md); z-index: var(--z-toast);
  opacity: 0; pointer-events: none; transition: all var(--dur-med) var(--ease-out);
  display: flex; align-items: center; gap: var(--sp-2);
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- Mobile menu ---------- */
.mobile-menu {
  position: fixed; inset: 0; z-index: var(--z-toast); background: var(--bg);
  transform: translateX(100%); transition: transform var(--dur-med) var(--ease-out);
  display: flex; flex-direction: column; padding: var(--sp-6);
}
.mobile-menu.open { transform: translateX(0); }
.mobile-menu-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--sp-10); }
.mobile-menu nav { display: flex; flex-direction: column; gap: var(--sp-6); }
.mobile-menu nav a { font-family: var(--font-display); font-size: var(--fs-2xl); }

/*
 * ---------- Theme toggle ----------
 * Used to be its own position:fixed circle pinned to the raw viewport
 * corner, independent of .luma-catnav-inner's centered max-width
 * column -- on any viewport wider than that column, the fixed corner
 * sat noticeably right of where the header's own content actually
 * ended, reading as misaligned/disconnected from the search button
 * next to it. Now a plain flex sibling of .luma-catnav-search inside
 * the header row instead, styled to match .luma-catnav-search-toggle
 * exactly (same size/radius/surface) so the two read as a paired set
 * of icon buttons. Trades away staying visible while scrolled past
 * the header -- the search button already works the same way, and
 * .luma-catnav itself is deliberately not sticky (see its own
 * comment), so this matches the rest of the header's behavior instead
 * of being the one outlier. Being an ordinary child of the header also
 * means it's now naturally covered by .overlay during a fullscreen
 * tool (z-index: var(--z-overlay) sits above var(--z-dropdown)) with
 * no extra CSS needed for that.
 */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 40px; height: 40px; border-radius: var(--radius-full);
  background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--text-secondary);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.theme-toggle:hover { background: var(--surface-3); color: var(--text-primary); }
.theme-toggle-icon { display: none; }
.theme-toggle .icon-moon { display: flex; }
:root[data-luma-theme="light"] .theme-toggle .icon-moon { display: none; }
:root[data-luma-theme="light"] .theme-toggle .icon-sun { display: flex; }

/* Utility */
.text-center { text-align: center; }
.mt-8 { margin-top: var(--sp-8); }
