/* ==========================================================================
   Individual blog post redesign (2026-08-22, client ask) — brings all ~95
   real posts in line with the homepage's visual language. Loads alongside
   pages-shared.css (fonts/tokens/buttons/header already shared from there);
   this file only covers components unique to a blog post: hero, meta bar,
   table of contents, article typography, share/rate widgets, related posts.
   single-post.php (child override) provides the markup this targets.
   ========================================================================== */

/* ---------- hero ---------- */
/* 2026-08-23 (client ask, item 10 — "make blog posts look like the main
   page, good and futuristic"): taller, more cinematic hero and a deeper,
   more directional gradient — the same dark-ink-behind-text technique as
   the homepage's own .mm-hero-bg::after, just kept vertical (180deg, not
   90deg) since a post's featured image can be any real crop/aspect ratio,
   unlike the homepage's one purpose-built hero photo. */
.mm-page .mm-post-hero{
  position:relative;isolation:isolate;overflow:hidden;
  min-height:min(46vh,420px);
  display:flex;align-items:flex-end;
  margin-top:88px;padding:64px 0 56px;
  background:var(--mm-ink);
}
@media(max-width:767px){.mm-page .mm-post-hero{margin-top:60px;min-height:260px;padding:36px 0 36px;}}
.mm-page .mm-post-hero__bg{position:absolute;inset:0;z-index:0;}
/* 2026-08-23 (item 11 consilium finding): across ~95 real posts the
   featured image is sometimes a real photo (works great under the plain
   gradient below) and sometimes a DAW screenshot/waveform/EQ-curve
   graphic in whatever loud, arbitrary colors that tool renders in — those
   clashed hard with the site's ink/blue palette even under the gradient.
   A muted, partly-desaturated filter on every hero image tones down any
   source image's own colors toward the site's palette instead — makes
   screenshots sit quietly in the background instead of fighting the text,
   and gives real photos a slightly more cinematic, consistent look too
   (not just a fix for the bad case). */
.mm-page .mm-post-hero__bg img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.5) saturate(.8) contrast(1.05) brightness(.85);
}
.mm-page .mm-post-hero__bg::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg, rgba(14,14,16,.25) 0%, rgba(14,14,16,.62) 55%, rgba(14,14,16,.94) 100%);
}
.mm-page .mm-post-hero__inner{position:relative;z-index:1;width:100%;}
.mm-page .mm-post-eyebrow{
  display:inline-block;margin-bottom:14px;color:var(--mm-amber-on-dark);
}
/* the parent theme's real custom.css carries its own ".single-post
   .entry-title{position:absolute;...}" rule (built for the ORIGINAL
   flat-hero layout) — reusing the same class name here for continuity
   means every property that rule sets and this one doesn't would still
   apply, so every one of them needs an explicit override, not just the
   ones this design actually wants to change. */
.mm-page .mm-post-hero h1{
  position:static;top:auto;left:auto;transform:none;z-index:auto;
  color:#fff;font-size:clamp(1.85rem,4vw,3rem);font-weight:800;line-height:var(--lh-tight);
  letter-spacing:-.02em;max-width:var(--mm-wrap-text);width:auto;
  margin:0;padding:0;text-align:left;text-wrap:balance;
}

/* The real custom.css (loaded last in the page — same load order as the
   original theme) has several .single-post rules keyed off classes this
   template still carries for continuity (post_class() always adds the
   bare "post" class; "entry-title"/"entry-content" are reused too):
   article.post{margin-top:-250px}, .entry-content{text-align:justify},
   .entry-content img{max-height:250px}. Real, deliberate rules for the
   ORIGINAL overlap-card layout — not a fit for this one, and since
   custom.css loads after this file, equal specificity loses to it by
   load order alone, so these need !important to reliably win. */
.mm-page article.post{margin-top:0 !important;padding:0 !important;background:none !important;border:none !important;box-shadow:none !important;border-radius:0 !important;overflow:visible !important;}

/* 2026-08-23 (QA-agent finding, item 11 consilium): three more real
   custom.css collisions this file hadn't covered yet — confirmed live via
   getComputedStyle, not assumed.
   1) ".container-single{width:95%!important;max-width:1200px!important;}"
      (custom.css) wraps the whole article + related-posts on every post
      and caps out 80px narrower than this design's own --mm-wrap (1280px)
      token on wide screens — only max-width needs raising, width:95%'s
      edge breathing room on narrow/medium viewports is fine as-is.
   2) "body{background:#dadada}" + "#main-content{background-color:
      #dadada}" (custom.css, ID selector on the real <main id="main-
      content"> from single-post.php) — nothing in this design ever set a
      background, so that old Divi-era gray showed through in every
      outer gutter instead of white.
   3) "#related-items{margin-top:20px;margin-bottom:20px}" (custom.css, ID
      selector) re-adds spacing this design zeroed via a class-only rule —
      an ID always beats a class, and needs !important here too since the
      legacy ID rule also loads later on the page. */
.mm-page .container-single{max-width:var(--mm-wrap) !important;}
body.single-post{background:#fff !important;}
.mm-page#main-content{background-color:#fff !important;}
#related-items{margin:0 !important;}
.mm-page .mm-post-article{text-align:left !important;}
.mm-page .mm-post-article img{max-height:none !important;width:auto !important;float:none !important;margin:1em 0 !important;padding:0 !important;}
/* 2026-08-24 (client ask: "some images not in place" — image-audit agent
   confirmed the cause): the blanket float:none above strips WordPress's
   real alignleft/alignright classes from every image, forcing images the
   original authors floated beside text (86 of 95 real posts use these
   classes) into full-width blocks instead. No stretching/distortion
   anywhere (width:auto + height:auto from the rule below already
   preserve every real aspect ratio) — this is purely a text-wrap/
   placement regression. Restored here, specificity-wins-over-the-base-
   rule via the extra .alignleft/.alignright class, still !important since
   the parent theme's own custom.css has its own un-!important
   .entry-content img.alignleft/alignright rules at equal specificity that
   load after this file. max-width caps a floated image at a reasonable
   fraction of the 820px column instead of letting a large original photo
   swallow the whole width it's supposed to float beside. */
.mm-page .mm-post-article img.alignleft{float:left !important;max-width:45% !important;margin:.3em 24px 1em 0 !important;}
.mm-page .mm-post-article img.alignright{float:right !important;max-width:45% !important;margin:.3em 0 1em 24px !important;}
.mm-page .mm-post-article img.aligncenter{float:none !important;display:block;margin:1em auto !important;}
@media(max-width:599px){
  /* floated text-wrap doesn't work on a narrow column — same full-width
     block treatment as before on mobile, where there's no room for text
     to wrap beside an image anyway. */
  .mm-page .mm-post-article img.alignleft,
  .mm-page .mm-post-article img.alignright{float:none !important;max-width:100% !important;margin:1em 0 !important;}
}
/* the same real .entry-content img rule also reaches every UI icon inside
   the article (share buttons, star ratings) since they all sit inside the
   article tag's real .entry-content class — excluded explicitly rather
   than letting a 250px/100%-width image rule size a 18px icon. */
.mm-page .mm-share-btn img{max-height:none !important;width:18px !important;height:18px !important;margin:0 !important;padding:0 !important;}

/* ---------- meta bar (published / updated / author / rating) ---------- */
/* 2026-08-23 (item 10): dark ink-2/ink-3 card — the same card language as
   the homepage's .mm-price-card / .mm-review-card — instead of the plain
   white/paper-3 bar, so the strip directly under a dark hero reads as one
   continuous "futuristic" dark passage rather than an abrupt light band. */
.mm-page .mm-post-meta{
  display:flex;flex-wrap:wrap;gap:10px 28px;align-items:center;
  max-width:var(--mm-wrap-text);margin:24px auto 0;padding:18px 24px;
  background:var(--mm-ink-2);border:1px solid var(--mm-ink-3);border-radius:var(--r-lg);
  font-family:var(--font-body);font-size:var(--fs-small);box-shadow:var(--sh-card);
}
.mm-page .mm-post-meta__item{display:flex;align-items:center;gap:6px;color:var(--mm-t-inv-dim);}
.mm-page .mm-post-meta__item b{color:var(--mm-t-inv);font-weight:700;font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.mm-page .mm-post-meta__item a{color:var(--mm-blue-soft);text-decoration:none;font-weight:700;}
.mm-page .mm-post-meta__item a:hover{color:#fff;}
.mm-page .mm-post-meta__stars{color:rgba(255,255,255,.22);letter-spacing:1px;}
.mm-page .mm-post-meta__stars .is-filled{color:var(--mm-amber-on-dark);}

/* ---------- table of contents ---------- */
.mm-page .mm-toc-wrap{max-width:var(--mm-wrap-text);margin:16px auto 0;text-align:center;}
.mm-page .mm-toc-toggle{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-body);font-weight:700;font-size:var(--fs-small);
  color:var(--mm-t-inv);background:var(--mm-ink-2);border:1px solid var(--mm-ink-3);
  border-radius:999px;padding:10px 20px;cursor:pointer;transition:background 150ms ease,border-color 150ms ease;
}
.mm-page .mm-toc-toggle:hover{background:var(--mm-ink-3);border-color:var(--mm-blue);}
.mm-page .mm-toc-panel{
  display:none;text-align:left;margin-top:12px;padding:20px 24px;
  background:var(--mm-ink-2);border:1px solid var(--mm-ink-3);border-radius:var(--r-lg);box-shadow:var(--sh-card);
}
.mm-page .mm-toc-panel__title{
  display:block;font-family:var(--font-display);font-weight:700;
  font-size:var(--fs-small);letter-spacing:.08em;text-transform:uppercase;
  color:var(--mm-t-inv-dim);margin-bottom:12px;
}
.mm-page .mm-toc-item{
  padding:9px 0;font-size:var(--fs-body);color:var(--mm-blue-soft);cursor:pointer;
  border-bottom:1px solid rgba(255,255,255,.08);
}
.mm-page .mm-toc-item:last-child{border-bottom:none;}
.mm-page .mm-toc-item:hover{color:#fff;}
.mm-page .mm-toc-item.mm-toc-item--h3{padding-left:18px;font-size:var(--fs-small);}

/* ---------- article body typography ---------- */
/* Real post content (the_content()) itself is untouched — only its
   typography here. Headings pushed bolder/tighter to match the homepage's
   own .mm-section-head h2 language (font-weight:800, tight letter-spacing)
   instead of a generic blog-serif feel. */
.mm-page .mm-post-article{max-width:var(--mm-wrap-text);margin:40px auto 0;}
.mm-page .mm-post-article h2{
  font-size:1.7rem;font-weight:800;letter-spacing:-.01em;margin:2.2em 0 .6em;line-height:var(--lh-snug);
}
.mm-page .mm-post-article h3{font-size:1.3rem;font-weight:700;margin:1.8em 0 .5em;}
/* the real article element itself also carries the legacy "entry-content"
   class (via post_class()) for continuity — its own ".single-post
   .entry-content p{color:#000;font-size:16px;font-weight:500;}" rule in
   custom.css is equal specificity and loads after this file, so it would
   otherwise win the color/size/weight on every real paragraph. */
.mm-page .mm-post-article p{font-size:1.05rem !important;font-weight:400 !important;line-height:var(--lh-relaxed);color:var(--mm-t-secondary) !important;margin:0 0 1.3em;}
.mm-page .mm-post-article a{color:var(--mm-blue);text-decoration:underline;text-underline-offset:2px;}
.mm-page .mm-post-article a:hover{color:var(--mm-blue-hover);}
.mm-page .mm-post-article ul,
.mm-page .mm-post-article ol{margin:0 0 1.3em;padding-left:1.4em;color:var(--mm-t-secondary);line-height:var(--lh-relaxed);}
.mm-page .mm-post-article li{margin-bottom:.4em;}
.mm-page .mm-post-article img{border-radius:var(--r-lg);height:auto;margin:.5em 0;box-shadow:var(--sh-card);}
/* 2026-08-29 (client: embedded YouTube video "стоїть криво не по центру",
   confirmed on both videos on this page): the raw embed markup carries an
   inline `style="width: 100%;justify-content: center"` on the wrapping div
   -- WordPress's wp_kses() sanitizer silently strips `display:flex` from
   iframe/div style attributes (the same pattern already fixed once for
   the service-page video embeds, see pages-shared.css), so
   `justify-content:center` is left with no flex context to act on and
   does nothing. Centering via CSS margin instead of relying on the
   sanitizable inline style. Also fixes a second, separate bug found in
   the same QA pass: the iframe's raw width="560" height="315" attributes
   don't shrink on mobile, so at 375px it overflowed its ~343px-wide
   column by 189px, silently clipped by the article wrapper's own
   overflow-x:hidden -- max-width:100% caps the width, and aspect-ratio
   keeps it at the original 560:315 proportions as height:auto lets it
   shrink instead of staying frozen at 315px (which would otherwise
   squish/stretch the picture once width is capped smaller). */
.mm-page .mm-post-article iframe{display:block;margin:20px auto;max-width:100%;height:auto;aspect-ratio:560/315;}
/* darker "console" quote treatment — same family as the homepage's dark
   cards, kept small/inline (not a full ink-2 box) so it reads as an accent
   inside the light article column rather than breaking the reading flow. */
.mm-page .mm-post-article blockquote{
  position:relative;margin:1.8em 0;padding:20px 24px 20px 52px;border:1px solid var(--mm-paper-3);
  background:var(--mm-paper-2);border-radius:var(--r-md);
  font-style:italic;color:var(--mm-t-primary);
}
.mm-page .mm-post-article blockquote::before{
  content:'\201C';position:absolute;left:18px;top:8px;
  font-family:var(--font-display);font-style:normal;font-weight:800;font-size:2.2rem;
  line-height:1;color:var(--mm-blue);
}
.mm-page .mm-post-article strong{color:var(--mm-t-primary);}

/* ---------- end-of-article CTA ---------- */
/* 2026-08-24 (item 11 consilium): the same dark ink-2 card language as the
   meta bar / TOC / share footer, but with the blue accent leaned into
   harder (a real .mm-btn--primary, not just a text link) since this is
   the one block on the page whose whole job is to convert, not inform. */
.mm-page .mm-post-cta{
  max-width:var(--mm-wrap-text);margin:48px auto 0;padding:32px;
  background:var(--mm-ink-2);border:1px solid var(--mm-ink-3);border-radius:var(--r-lg);box-shadow:var(--sh-card);
  display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:space-between;
}
.mm-page .mm-post-cta__body{flex:1 1 320px;min-width:0;}
.mm-page .mm-post-cta__eyebrow{color:var(--mm-amber-on-dark);}
.mm-page .mm-post-cta__title{
  margin:10px 0 0;color:var(--mm-t-inv);font-size:1.4rem;font-weight:800;
  letter-spacing:-.01em;line-height:var(--lh-snug);
}
.mm-page .mm-post-cta__trust{
  display:flex;flex-wrap:wrap;gap:8px 20px;margin:14px 0 0;padding:0;list-style:none;
}
.mm-page .mm-post-cta__trust li{
  font-family:var(--font-body);font-size:var(--fs-small);font-weight:500;
  color:var(--mm-t-inv-dim);white-space:nowrap;
}
.mm-page .mm-post-cta__btn{flex:none;white-space:nowrap;}
@media(max-width:599px){
  .mm-page .mm-post-cta{padding:24px;}
  .mm-page .mm-post-cta__btn{width:100%;}
}

/* ---------- share / rate footer bar ---------- */
/* Dark ink-2 card again — bookends the light article column with the same
   dark-card language the meta bar opens with, so the page reads as a
   dark→light→dark rhythm like the homepage's own section alternation. */
.mm-page .mm-post-footer-meta{
  max-width:var(--mm-wrap-text);margin:48px auto 0;padding:24px;
  background:var(--mm-ink-2);border:1px solid var(--mm-ink-3);border-radius:var(--r-lg);box-shadow:var(--sh-card);
  display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:space-between;
}
.mm-page .mm-post-share{display:flex;flex-wrap:wrap;align-items:center;gap:12px;}
.mm-page .mm-post-share__label{
  font-family:var(--font-body);font-weight:700;font-size:var(--fs-small);
  color:var(--mm-t-inv);margin-right:4px;
}
.mm-page .mm-share-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:50%;
  background:var(--mm-ink-3);border:1px solid rgba(255,255,255,.12);
  transition:border-color 150ms ease, transform 150ms ease;
}
.mm-page .mm-share-btn:hover{border-color:var(--mm-blue);transform:translateY(-1px);}
.mm-page .mm-share-btn img{width:18px;height:18px;object-fit:contain;}
.mm-page .mm-post-rate{display:flex;align-items:center;gap:10px;}
.mm-page .mm-post-rate__label{font-family:var(--font-body);font-weight:700;font-size:var(--fs-small);color:var(--mm-t-inv);}
.mm-page .rate-post{font-size:1.15rem;letter-spacing:2px;color:rgba(255,255,255,.22);}
.mm-page .rate-post .rate-star{cursor:pointer;transition:color 120ms ease;}
.mm-page .rate-post .rate-star:hover,
.mm-page .rate-post .rate-star.mm-rated{color:var(--mm-amber-on-dark);}

/* ---------- related posts ---------- */
/* Dark ink-2/ink-3 cards, same recipe as .mm-price-card/.mm-review-card on
   the homepage — hover lift + border brighten, blue "Read more" accent. */
/* the real custom.css also carries un-namespaced ".related-posts{padding,
   border-radius,margin-bottom}" and ".single .related-title{font-size:2rem
   fixed,font-weight:700,color,text-align:center,text-transform:capitalize}"
   rules from the ORIGINAL design (kept in production since only the parent
   theme is live there) — the title rule is equal specificity to mine and
   loads later, so without !important it would win and render "See also"
   centered, non-responsive, and off-brand-weight instead of matching the
   article's own h2 styling. */
.mm-page .related-posts{
  max-width:var(--mm-wrap);margin:64px auto 0 !important;padding-inline:var(--mm-edge-m);
  padding-block:0 !important;border-radius:0 !important;
}
@media(min-width:768px){.mm-page .related-posts{padding-inline:var(--mm-edge-t);}}
@media(min-width:1280px){.mm-page .related-posts{padding-inline:var(--mm-edge-d);}}
.mm-page .related-title{
  display:block;font-family:var(--font-display);font-weight:800 !important;letter-spacing:-.01em;
  font-size:var(--fs-h3) !important;margin-bottom:20px;color:var(--mm-t-primary) !important;
  text-align:left !important;text-transform:none !important;
}
.mm-page .related-posts-inner{margin:0;}
/* 2026-08-23: the real parent-theme custom.css (loads LAST in the page,
   same load-order fact already documented for the hero/article rules
   above) carries its own ".related-posts .related-post-item*" block built
   for the ORIGINAL white-card design — fixed 300px width, background:#fff,
   an absolute-positioned white-text title OVERLAID on the image, and a
   black ".related-post-item-read-more span" button. Equal selector
   specificity (two classes each) means the later-loaded legacy rule wins
   ties by source order alone, silently reverting the card back to the old
   look. Confirmed live via getComputedStyle: border-color picked up this
   file's value correctly while background-color did not — proof this is a
   real cascade loss, not a measurement artifact. Every colliding legacy
   property is explicitly countered below, not just the ones this design
   changes on purpose. */
.mm-page .related-post-item{
  background:var(--mm-ink-2) !important;border:1px solid var(--mm-ink-3);border-radius:var(--r-lg) !important;
  box-shadow:none !important;width:100% !important;margin:0 !important;padding-bottom:0;
  overflow:hidden;height:100%;display:flex;flex-direction:column;
  transition:border-color 200ms ease,transform 200ms ease,box-shadow 200ms ease;
}
.mm-page .related-post-item:hover{border-color:rgba(255,255,255,.28);transform:translateY(-2px);box-shadow:var(--sh-lift) !important;}
.mm-page .related-post-item:hover .related-post-item-body{box-shadow:none !important;}
.mm-page .related-post-item-head{position:relative;display:block !important;}
.mm-page .related-post-item-img{
  width:100% !important;height:auto !important;aspect-ratio:16/10;object-fit:cover;display:block;
}
/* legacy title rule makes this an absolute white-on-black overlay sitting
   ON the image (built for the old design, where the title was the image's
   only caption) — this design shows the title as its own block below the
   image instead, so the whole overlay treatment is countered, not just
   recolored. */
.mm-page .related-post-item-title{
  position:static !important;width:auto !important;height:auto !important;z-index:auto !important;
  display:block !important;align-items:normal !important;justify-content:normal !important;
  background:none !important;text-align:left !important;margin:0 !important;
  padding:16px 18px 0;font-family:var(--font-display);font-weight:700 !important;
  font-size:1.02rem !important;line-height:var(--lh-snug);color:var(--mm-t-inv) !important;
}
.mm-page .related-post-item-body{padding:10px 18px 20px;flex:1;display:flex;flex-direction:column;}
.mm-page .related-post-item-body p{
  font-size:var(--fs-small) !important;color:var(--mm-t-inv-dim) !important;text-align:left !important;
  line-height:var(--lh-body) !important;font-weight:400;margin:0;padding:0 !important;min-height:0 !important;flex:1;
}
.mm-page .related-post-item-read-more{
  display:block !important;justify-content:normal !important;align-items:normal !important;
  padding:0 !important;margin-top:10px !important;
}
/* legacy also styles the literal <span>Read more</span> inside the link as
   a solid black button — neutralized so this design's plain blue text
   link (styled on the parent <a>, matching every other in-article link)
   is what actually renders. */
.mm-page .related-post-item-read-more span{
  display:inline !important;padding:0 !important;margin:0 !important;
  border:none !important;background:none !important;color:inherit !important;
}
.mm-page .related-post-item-read-more a{
  font-family:var(--font-body);font-weight:700;font-size:var(--fs-small);
  color:var(--mm-blue-soft);text-decoration:none;
}
.mm-page .related-post-item-read-more a:hover{color:#fff;}
.mm-page .related-post-item-read-more a:hover span{color:inherit !important;}
.mm-page .owl-dots{text-align:center;margin-top:16px;}
.mm-page .owl-dot span{background:var(--mm-paper-3) !important;}
.mm-page .owl-dot.active span{background:var(--mm-blue) !important;}

/* ---------- scroll-reveal motion (matches homepage's .mm-r/.mm-in) ---------- */
/* Fail-safe / progressive-enhancement pattern (2026-08-23): opacity:0 only
   applies once body carries .mm-anim-ready, which the inline script at the
   bottom of single-post.php sets itself right before wiring the
   IntersectionObserver. If JS doesn't run at all (blocked, errors, old
   browser) real content — related-post cards, the share/rate bar — stays
   at its default visible opacity instead of being hidden with nothing to
   ever reveal it. Applied across ~95 real, live posts, so defaulting to
   "always visible unless JS proves it can un-hide it" is the safer
   direction than the reverse. */
body.mm-anim-ready .mm-page .mm-r{opacity:0;transform:translateY(14px);transition:opacity 420ms cubic-bezier(.2,.7,.3,1), transform 420ms cubic-bezier(.2,.7,.3,1);}
body.mm-anim-ready .mm-page .mm-r.mm-in{opacity:1;transform:none;}
@media (prefers-reduced-motion: reduce){
  body.mm-anim-ready .mm-page .mm-r{opacity:1 !important;transform:none !important;transition:none !important;}
}
