/* blog.css: blog-only styles. Reuses landing.css tokens (--bg, --text,
   --text-dim, --text-faint, --blue, --blue-text). Loaded after
   landing.css. */

/* Blog-index content column. The heading, filter chips and card grid all bind
   to this one width so they share a left edge (see .mk-blog-head comment); a
   single token keeps the three in lockstep. */
:root { --blog-col: 1040px; --blog-measure: min(68ch, 600px); }

/* Visually-hidden helper (screen-reader only) */
.mk-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Current-page nav item */
.mk-nav-links a[aria-current="page"] { color: #fff; }

/* Opt the blog's interactive elements into the site's focus-visible system
   (landing.css styles its own controls with the same teal ring). Without this
   the tag chips, prose/card/breadcrumb/back links and the scrollable comparison
   region fall back to the UA focus ring, which is inconsistent and can be
   low-contrast on the near-black background. Radius is left to each element so
   pills stay pills and the card keeps its 16px corners. */
.mk-tagbar button:focus-visible,
.mk-prose a:focus-visible,
.mk-blog-card:focus-visible,
.mk-crumbs a:focus-visible,
.mk-back-link a:focus-visible,
.mk-cmp-wrap:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* Article shell */
.mk-article { max-width: 760px; margin: 0 auto; padding: 32px 0 64px; }
.mk-article-header { margin-bottom: 28px; }
/* Shared display-heading treatment for the article title and the blog index
   heading. Tight leading plus negative tracking so both use the site's
   display-type conventions instead of the untracked UA <h1>; margin:0 lets each
   header's padding own the spacing. */
.mk-article h1, .mk-blog-head h1 { font-size: clamp(28px, 5vw, 40px); line-height: 1.1; letter-spacing: -0.02em; margin: 0; }
.mk-article-meta { color: var(--text-faint); font-size: 14px; margin-top: 12px; }

/* Breadcrumb */
.mk-crumbs { font-size: 13px; color: var(--text-faint); margin-bottom: 16px; }
.mk-crumbs a { color: var(--blue-text); }

/* Prose rhythm */
.mk-prose { color: var(--text-dim); font-size: 17px; line-height: 1.7; }
.mk-prose > * + * { margin-top: 20px; }
.mk-prose h2 { color: var(--text); font-size: 24px; line-height: 1.25; letter-spacing: -0.01em; margin-top: 44px; }
/* h3 needs its own tight heading leading + tracking; without them it inherits
   the 1.7 body line-height (a two-line subhead sags apart) and reads only 2px
   above the 17px body. 20px/-0.01em gives a clean ~1.2 step (h2 24 / h3 20 /
   body 17) matching the h2 tracking. */
.mk-prose h3 { color: var(--text); font-size: 20px; line-height: 1.3; letter-spacing: -0.01em; margin-top: 28px; }
.mk-prose a { color: var(--blue-text); text-decoration: underline; text-underline-offset: 2px; }
.mk-prose strong { color: var(--text); }
.mk-prose ul { padding-left: 22px; list-style: disc; }
.mk-prose li + li { margin-top: 8px; }
/* Cap the running prose to a comfortable reading measure (--blog-measure). 68ch
   alone renders ~90 characters per line at this font (the "0"-based ch unit runs
   wide), well past the 65-75-character ceiling, so pair it with a ~600px pixel
   cap that binds on tablet and up (~74 characters). On phones the reading column
   is already narrower than either cap, so the measure there is untouched.
   Paragraphs, lists, the comparison table and its footnote all bind to this one
   measure so the whole article shares a single reading column; the table earns
   its extra columns with horizontal scroll and a frozen Musklr column rather
   than by breaking out wider than the prose. */
.mk-prose > p,
.mk-prose > ul { max-width: var(--blog-measure); }

/* App-name headings in "A closer look at each app": the app's rounded iOS icon
   sits inline with the name, matching the comparison table's app-column headers
   (.mk-cmp-app). align-items:center keeps a wrapping two-line title balanced
   against the fixed-size icon. */
.mk-prose h3.mk-app-h3 { display: flex; align-items: center; gap: 10px; }
.mk-app-h3 img { border-radius: 6px; flex-shrink: 0; }

/* In-body CTA buttons: the Musklr "closer look" block and the "why Musklr wins"
   section route readers back to the home page. Same white pill as the site's
   primary download button, sized up to the 44px tap target. The two-class
   selector (0,0,2,0) beats .mk-prose a (0,0,1,1) so the pill keeps its
   black-on-white colour and drops the prose underline. */
.mk-inline-cta .mk-pill-download {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 12px 24px;
  font-size: 14px; color: #000; text-decoration: none;
}

/* Comparison table. Shares the prose reading measure (--blog-measure) rather
   than breaking out full-width: the competitor columns earn their space with
   horizontal scroll, and the two most-consulted columns (the feature labels and
   Musklr) stay frozen so you never lose the row you are reading. */
.mk-cmp-wrap { max-width: var(--blog-measure); overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 28px 0; border: 1px solid rgba(255,255,255,0.08); border-radius: 16px; }
/* tabular-nums so the prices and exercise counts share one figure width and
   align down each column ($4.99 / $12.99, 2,000+ / 1,400+ / 1,000+) instead of
   drifting on proportional digits. Auto layout plus the fixed frozen-column
   widths below push the table wider than its wrap, which is what triggers the
   horizontal scroll. */
/* --feat-w drives the frozen row-label column's width (the phone media query
   below narrows it). */
.mk-cmp-table { --feat-w: 132px; width: 100%; border-collapse: separate; border-spacing: 0; font-size: 15px; font-variant-numeric: tabular-nums; }
.mk-cmp-table caption { text-align: left; }
/* vertical-align:top so the wrapping cells (the feature labels and the multi-line
   price row) sit at the top of each row instead of floating to the middle. */
.mk-cmp-table th, .mk-cmp-table td { padding: 12px 14px; text-align: left; vertical-align: top; border-bottom: 1px solid rgba(255,255,255,0.06); white-space: nowrap; }
.mk-cmp-table tr:last-child th, .mk-cmp-table tr:last-child td { border-bottom: 0; }
.mk-cmp-table thead th { color: var(--text); font-weight: 600; }
.mk-cmp-table tbody th { color: var(--text-dim); font-weight: 600; }

/* App-name column headers: the rounded icon (so it reads as an iOS app icon)
   sits inline with the name. */
.mk-cmp-app { display: inline-flex; align-items: center; gap: 8px; }
.mk-cmp-app img { border-radius: 6px; flex-shrink: 0; }

/* Frozen row-label column only. The table is wider than its wrap, so the
   feature-label column (col 1) is pinned left with position:sticky while every app
   column scrolls past it, keeping the row you are reading in view. It needs an
   OPAQUE background (flat --bg) so scrolling cells do not bleed through.
   box-sizing:border-box so its `width` is its true laid-out width; scoped under
   .mk-cmp-table to beat the base th/td rules (the label cells are <th> and must
   wrap, not nowrap). */
.mk-cmp-table .mk-cmp-feat { position: sticky; left: 0; z-index: 2; box-sizing: border-box; width: var(--feat-w); min-width: var(--feat-w); white-space: normal; background: var(--bg); }
/* Musklr is the highlighted "winner" column: brighter text and a teal frame so it
   stands out among the scrolling apps. It is NOT frozen (a second frozen column
   left too little room for the competitors on phones). */
.mk-cmp-table .mk-cmp-musklr { color: var(--text); min-width: 150px; border-left: 2px solid rgba(34,166,220,0.4); border-right: 2px solid rgba(34,166,220,0.4); }
.mk-cmp-table thead th.is-musklr { background: rgba(34,166,220,0.14); color: var(--text); }

/* Traffic-light cell tints (honest polarity; best / middle / weakest per row,
   with grey left untinted for figures the vendor does not publish). Reuses the
   landing.css status tokens (--green/--orange/--red) at a low alpha so the tint
   stays subtle and the cell text keeps AA contrast on near-black. Colour is a
   backup signal only: the cell text (2,000+, Yes, No, Not published) already
   carries the meaning, and the legend line spells the mapping out. Each tint is
   layered over --bg so the frozen Musklr column reads identically to the
   scrolling ones and never lets content bleed through. */
.mk-cmp-table td.c-green { background: linear-gradient(rgba(48,209,88,0.14), rgba(48,209,88,0.14)), var(--bg); }
.mk-cmp-table td.c-amber { background: linear-gradient(rgba(255,159,10,0.14), rgba(255,159,10,0.14)), var(--bg); }
.mk-cmp-table td.c-red   { background: linear-gradient(rgba(255,69,58,0.14), rgba(255,69,58,0.14)), var(--bg); }
/* c-grey: no tint. A non-answer reads as absent data, not a scored outcome. */

/* Non-answers ("Not published" / "Not stated") dimmed on the neutral ramp so
   they read as missing data rather than a "No". */
.mk-cmp-no  { color: var(--text-faint); }
/* On phones the frozen row-label column would eat too much width; narrow it so a
   useful slice of the scrolling app columns is always visible. */
@media (max-width: 480px) {
  .mk-cmp-table { --feat-w: 104px; }
}

/* Colour-key legend for the traffic-light tints. Upright (the italic below is
   the price/data disclaimer) so the key reads as a functional key. */
.mk-cmp-legend { margin-top: 12px; font-size: 13px; line-height: 1.5; color: var(--text-faint); }

/* Table footnote */
.mk-cmp-note { margin-top: 8px; font-size: 13px; line-height: 1.5; color: var(--text-faint); font-style: italic; }

/* Article CTA */
.mk-article-cta { margin: 48px 0 0; padding: 28px; border: 1px solid rgba(255,255,255,0.1); border-radius: 16px; text-align: center; background: rgba(255,255,255,0.02); }
.mk-article-cta h2 { margin: 0 0 12px; color: var(--text); font-size: 24px; line-height: 1.25; letter-spacing: -0.01em; }
.mk-article-cta p { margin: 0 auto 20px; max-width: 52ch; color: var(--text-dim); font-size: 16px; line-height: 1.6; }
.mk-article-cta .mk-pill-download { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 12px 28px; font-size: 15px; }
/* Secondary link under the beta button: a clear path to the Musklr home page
   (where the main Download button lives) for readers who want the full pitch. */
.mk-article-cta .mk-cta-home { margin: 16px auto 0; font-size: 14px; }
.mk-article-cta .mk-cta-home a { color: var(--blue-text); }

/* Back-to-blog link */
.mk-back-link { margin-top: 40px; font-size: 14px; }
.mk-back-link a { color: var(--blue-text); }
/* The article's exit link is the one interactive element on the page with no
   hover reward. Give its arrow a 3px nudge in its own direction (back), reusing
   the site's translate-on-hover vocabulary (.mk-pill-download, .mk-blog-card) and
   the same --ease-out-quart. inline-block so the transform lands on the inline
   glyph; only the arrow moves, the label holds still, so the motion reads as
   intent, not a wobble. No new color or token. */
.mk-back-arrow { display: inline-block; transition: transform .15s var(--ease-out-quart); }
.mk-back-link a:hover .mk-back-arrow { transform: translateX(-3px); }

/* Blog index */
/* Share the tagbar/grid column width (--blog-col) so the heading, filter chips
   and cards line up on one left edge. A narrower header (e.g. the article's 760px
   reading column) would inset the h1/intro from the content it heads on desktop,
   reading as a misalignment. The index h1 shares the article's display treatment
   (see .mk-article h1, .mk-blog-head h1 above). */
.mk-blog-head { max-width: var(--blog-col); margin: 0 auto; padding: 40px 0 8px; }
/* auto-fill (not auto-fit): auto-fit collapses the empty tracks and lets the
   surviving card's 1fr stretch across the whole 1040px row, so a single post
   balloons into a full-width banner with the wrong proportions. auto-fill keeps
   the empty tracks, so one card stays a normal ~one-third column aligned under
   the tagbar, and the grid still fills left-to-right and wraps as posts grow. */
.mk-blog-grid { max-width: var(--blog-col); margin: 0 auto; padding: 24px 0 64px; display: grid; gap: 20px; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
/* Hover-lift eases on the site's micro-feedback curve (--ease-out-quart), matching
   the identical bordered-surface gesture on landing.css's .mk-btn-ghost / .mk-btn-primary
   / feature mockups. Without the token the card decelerates on the browser default
   `ease`, reading subtly out of step with every other hover on the site. */
.mk-blog-card { display: block; padding: 22px; border: 1px solid rgba(255,255,255,0.08); border-radius: 16px; background: rgba(255,255,255,0.02); text-decoration: none; transition: border-color .15s var(--ease-out-quart), transform .15s var(--ease-out-quart); }
.mk-blog-card:hover { border-color: rgba(34,166,220,0.4); transform: translateY(-2px); }
/* Press feedback: the hover lift settles into a subtle push-in on press, the same
   gesture landing.css's .mk-watch-link uses on its large bordered surface, so a tap
   registers on touch, where there's no hover. Placed after :hover so it wins while
   the pointer is down; a larger surface than a button, so it scales a touch less
   (0.98, matching .mk-watch-link, not the buttons' 0.97). */
.mk-blog-card:active { transform: scale(0.98); }
/* Reset the UA h2/p margins so the card's interior rhythm is owned by the
   explicit margin-tops below (matching how .mk-article h1 / .mk-blog-head h1
   zero theirs). Without this the h2's 0.83em UA top margin adds to the 22px
   padding (top gap ends up larger than the bottom), and its bottom margin
   overrides the p's intended 8px, loosening the title/description pairing. */
.mk-blog-card h2 { color: var(--text); font-size: 19px; line-height: 1.25; letter-spacing: -0.01em; margin: 0; }
.mk-blog-card p { color: var(--text-dim); font-size: 15px; line-height: 1.5; margin: 8px 0 0; }
.mk-blog-card .mk-tag { display: inline-block; margin-top: 14px; font-size: 12px; color: var(--blue-text); border: 1px solid rgba(34,166,220,0.35); border-radius: 999px; padding: 3px 10px; }
.mk-blog-card time { display: block; margin-top: 10px; color: var(--text-faint); font-size: 13px; }
/* Filtered-out cards. Beats the card's own display:block (higher specificity via
   the attribute selector), so a hidden card actually collapses. */
.mk-blog-card[hidden] { display: none; }
/* Tag filter */
.mk-tagbar { max-width: var(--blog-col); margin: 0 auto; padding: 8px 0 0; display: flex; gap: 8px; flex-wrap: wrap; }
/* Chip feedback matches the site's button vocabulary. Transitions: the aria-pressed
   toggle swaps color/border-color/background so the selected chip fades into its teal
   state instead of snapping (like landing.css nav links and .mk-btn-ghost), and
   transform carries the press-scale below. Opacity is left out on purpose; it's set
   once at load on disabled chips, so transitioning it would fade them in on first
   paint. Reduced-motion-safe: those three color properties are exactly what the
   global reduced-motion block (landing.css) keeps at 150ms, and the transform is
   neutralised in the reduced-motion block at the end of this file. */
.mk-tagbar button { font-size: 13px; color: var(--text-dim); background: transparent; border: 1px solid rgba(255,255,255,0.14); border-radius: 999px; padding: 6px 14px; cursor: pointer; transition: color .15s var(--ease-out-quart), border-color .15s var(--ease-out-quart), background-color .15s var(--ease-out-quart), transform .15s var(--ease-out-quart); }
.mk-tagbar button[aria-pressed="true"] { color: var(--text); border-color: var(--blue); background: rgba(34,166,220,0.12); }
/* Desktop hover affordance for a chip that's still selectable: brighten the border
   and add the faint fill landing.css's ghost buttons use, so an idle chip reads as
   clickable rather than dead. Excludes the pressed chip (already teal) and disabled
   chips. Pointer-gated (like the feature mockups on landing.css) so a tap on touch
   doesn't leave a stuck hover on a chip that stays on screen. */
@media (hover: hover) and (pointer: fine) {
  .mk-tagbar button:not([aria-pressed="true"]):not(:disabled):hover {
    border-color: rgba(255,255,255,0.28);
    background: rgba(255,255,255,0.04);
  }
}
/* Press feedback: the same scale(0.97) every pressable on the site uses
   (.mk-pill-download, .mk-btn-primary, .mk-btn-ghost) so a chip confirms the tap on
   touch, where there's no hover to lean on. */
.mk-tagbar button:not(:disabled):active { transform: scale(0.97); }
/* A chip with no posts yet is disabled (see index.html), not a dead end. Dim it
   so it reads as "a category we don't have posts for yet", never as broken. */
.mk-tagbar button:disabled { opacity: 0.45; cursor: not-allowed; }
/* Phone/tablet (max-width 960px), where landing.css makes .mk-nav position:fixed.
   Two a11y adjustments share this breakpoint. */
@media (max-width: 960px) {
  /* Touch: grow the filter chips to the 44px tap minimum, matching how
     landing.css sizes the mobile nav pills (WCAG 2.5.5 / Apple HIG). The compact
     29px chip is fine for a mouse but a small thumb target; min-height plus
     flex-centering enlarges the hit area without changing the label or the
     desktop (mouse) look. */
  .mk-tagbar button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 8px 16px;
  }
  /* The fixed nav (56px + notch inset) would otherwise cover the top of any
     in-page jump target (the skip link or a hash lands it at the viewport top),
     so push the jump targets down by the bar height plus a little air. The
     desktop nav scrolls away and needs no offset. */
  #article,
  #blog-head {
    scroll-margin-top: calc(56px + env(safe-area-inset-top, 0px) + 16px);
  }
}

/* The global reduced-motion block (landing.css) strips the transform transition, but
   the hover/press rules still apply their transforms instantly; suppress the card
   lift, the card and chip press-scales, and the back-arrow nudge so none can
   snap-jump, matching how landing.css handles its own hover/press transforms. */
@media (prefers-reduced-motion: reduce) {
  .mk-blog-card:hover,
  .mk-blog-card:active { transform: none; }
  .mk-tagbar button:active { transform: none; }
  .mk-back-link a:hover .mk-back-arrow { transform: none; }
}
