/* MI Exercises — page styles for the single, category and hub templates.
 *
 * Consumes the tokens and shared components in foundation.css and adds
 * NO colours of its own: every value here is a var(). The P7 verification
 * greps this file for hex literals — a match means a second palette has
 * crept in.
 */

/* ── Single: hero extras ───────────────────────────────────────────── */

.mie-hero__byline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--mie-space-2);
    margin: 0 0 var(--mie-space-4);
    font-size: var(--mie-text-sm);
    color: var(--mie-text-on-ink-muted);
}

.mie-hero__byline > * + *::before {
    content: "·";
    margin-right: var(--mie-space-2);
    opacity: 0.6;
}

.mie-hero__verified {
    font-weight: 600;
    color: var(--mie-gold);
}

a.mie-hero__verified {
    text-decoration: none;
}

a.mie-hero__verified:hover {
    text-decoration: underline;
}

/* ── Single: body ──────────────────────────────────────────────────── */

.mie-single__body {
    padding-top: var(--mie-space-6);
    padding-bottom: var(--mie-space-6);
}

/* Card head — heading left, video toggle right (mockup). */
.mie-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--mie-space-4);
}

.mie-card__head .mie-card__heading {
    margin-bottom: var(--mie-space-4);
}

/* ── Video + M/F toggle ────────────────────────────────────────────── */

.mie-video__tabs {
    display: flex;
    gap: var(--mie-space-1);
    background: var(--mie-body);
    border-radius: var(--mie-radius-pill);
    padding: var(--mie-space-1);
}

.mie-video__tab {
    cursor: pointer;
    border: 0;
    background: transparent;
    border-radius: var(--mie-radius-pill);
    padding: var(--mie-space-2) var(--mie-space-4);
    font-size: var(--mie-text-sm);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mie-text-muted);
}

.mie-video__tab[aria-pressed="true"] {
    background: var(--mie-purple);
    color: var(--mie-text-on-ink);
}

.mie-video__frame {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--mie-ink);
    border-radius: var(--mie-radius);
    overflow: hidden;
}

.mie-video__frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ── Technique steps — purple circular badges over a semantic <ol> ─── */

.mie-steps {
    list-style: none;
    counter-reset: mie-step;
    margin: 0;
    padding: 0;
}

.mie-steps li {
    counter-increment: mie-step;
    position: relative;
    padding-left: var(--mie-space-7);
    margin: 0 0 var(--mie-space-4);
    line-height: 1.6;
    color: var(--mie-text-muted);
}

.mie-steps li:last-child {
    margin-bottom: 0;
}

.mie-steps li::before {
    content: counter(mie-step);
    position: absolute;
    left: 0;
    top: 0;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: var(--mie-purple);
    color: var(--mie-text-on-ink);
    font-size: var(--mie-text-sm);
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Do This / Avoid This ──────────────────────────────────────────── */

.mie-duo {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--mie-space-5);
}

.mie-duo .mie-card {
    margin-bottom: var(--mie-space-5);
}

.mie-marked {
    list-style: none;
    margin: 0;
    padding: 0;
}

.mie-marked li {
    position: relative;
    padding-left: var(--mie-space-5);
    margin: 0 0 var(--mie-space-3);
    line-height: 1.55;
    font-size: var(--mie-text-md);
    color: var(--mie-text-muted);
}

.mie-marked li:last-child {
    margin-bottom: 0;
}

.mie-marked li::before {
    position: absolute;
    left: 0;
    top: 0;
    font-weight: 700;
}

.mie-marked--do li::before {
    content: "✓";
    color: var(--mie-tick);
}

.mie-marked--avoid li::before {
    content: "✗";
    color: var(--mie-red);
}

/* ── Card height discipline — ONE pattern, every grid ───────────────
   Liam, 1.2: cards in a row must be the same height whatever the title
   and description do. Measured on staging 1.8.5 before changing
   anything, because "unequal" turned out not to mean what it looks
   like:

     Workouts Featuring This Lift, 28 cards, 7 rows of 4 — WITHIN each
     row the heights were already identical (grid items stretch), but
     the rows themselves ran 461 / 502 / 461 / 461 / 482 / 461 / 461px.
     A row is as tall as its longest description, so a 12-week card
     landed 41px taller than an 8-week one purely from the row it fell
     in.

   So stretching is not the fix — the cards already stretch. CLAMPING
   the content is: with titles at 2 lines and descriptions at 3, every
   row has the same tallest card, and the rows agree.

   The pattern, applied identically to .mie-mini, .mie-prog,
   .mie-exercise-card and .mie-cat:

     1. the card is a flex COLUMN (it is already a stretched grid item)
     2. its media, where it has one, is flex: 0 0 auto so the column
        cannot squash a fixed aspect-ratio well
     3. its body grows (flex: 1)
     4. titles clamp to 2 lines, descriptions to 3
     5. the meta row and the closing link are pinned to the bottom with
        margin-top: auto

   ONE auto margin per card, never two. Two auto margins in a flex
   column SPLIT the free space between them and open a gap in the
   middle of the card rather than pushing the pair down together —
   which is why each card below pins its FIRST bottom element and then
   cancels the auto on the one that follows it with an adjacent-sibling
   rule. The cancel is written as `+`, so a card missing the first
   bottom element still pins the second.

   A CLAMP ALONE DOES NOT EQUALISE, and the first cut of this proved
   it: with titles clamped to 2 lines the rows still measured 362 and
   338px, because a clamp caps the maximum and says nothing about the
   minimum — a row of one-line titles is a line shorter than a row of
   two-line ones. Every clamp here therefore also RESERVES its lines
   with a matching min-height, which is what makes "equal height
   regardless of title or description length" true rather than
   approximately true. The line-height is declared next to the reserve
   on purpose: the two numbers have to agree, and splitting them across
   the file is how they stop agreeing. */

.mie-clamp-2,
.mie-mini__title,
.mie-prog__title,
.mie-exercise-card__title,
.mie-cat__title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.3;
    min-height: 2.6em;   /* 2 × 1.3 */
}

.mie-clamp-3,
.mie-prog__desc,
.mie-cat__desc {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.5;
    min-height: 4.5em;   /* 3 × 1.5 */
}

/* ── More to Explore — labelled bands of mini cards ────────────────── */

.mie-band__label {
    margin: var(--mie-space-5) 0 var(--mie-space-3);
    font-size: var(--mie-text-sm);
    font-weight: 700;
    color: var(--mie-purple);
}

.mie-band__label:first-of-type {
    margin-top: 0;
}

/* 3-up at the shell width, matching the category feed — was 190px, which
   auto-filled FIVE columns inside the card and made "cap the grid to a
   full row" impossible to satisfy with the 3 or 6 Liam asked for (6
   cards became 5 + 1 stranded). At 280px, 1044px of card interior fits
   exactly three. */
.mie-band {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--mie-grid-gap);
}

.mie-mini {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: var(--mie-space-4);
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius);
    text-decoration: none;
    color: inherit;
    background: var(--mie-surface);
}

/* Card hovers are a BORDER change plus a deepened title. The card's own
   <a> takes the light-ground colour from foundation.css, but a title or
   a "View exercise" line inside it carries its own colour, so each has
   to be named — a descendant with an explicit colour does not inherit
   the hover. */
.mie-mini:hover {
    border-color: var(--mie-hover-on-light);
}

.mie-mini:hover .mie-mini__title,
.mie-mini:hover .mie-mini__more {
    color: var(--mie-hover-on-light);
}

.mie-mini__title {
    display: block;
    margin: var(--mie-space-2) 0 var(--mie-space-1);
    font-weight: 700;
    font-size: var(--mie-text-md);
    color: var(--mie-text);
}

.mie-mini__more {
    display: block;
    margin-top: auto;
    padding-top: var(--mie-space-2);
    font-size: var(--mie-text-sm);
    font-weight: 600;
    color: var(--mie-purple);
}

/* ── Workouts Featuring This Lift ──────────────────────────────────── */

/* THREE PER ROW, and that is the only thing this rule does (Liam, round
   2 · 3.1). The cards themselves are mi-workouts' — same partial, same
   classes, same stylesheet — so everything about how one LOOKS is over
   there, on purpose. What is not over there is how many fit a row: their
   `.mi-guide-grid` is `auto-fill, minmax(280px, 1fr)`, which packs to the
   container, and this section's column is a different width from theirs.
   Four fitted, and four is what Liam is asking us to stop doing — at
   three the extra width is what stops the descriptions feeling cramped.

   Specificity is doing work again: `.mi-guide-grid` is (0,1,0) and their
   sheet loads after ours, so this is written at (0,2,0) to win on weight
   rather than on enqueue order.

   The breakpoints are ours for the same reason: their mobile rule drops
   to one column at (0,1,0) INSIDE a media query, and a (0,2,0) rule
   outside one would beat it at every width and strand three columns on a
   phone. So the ladder is restated in full — 3 / 2 / 1. Their 20px gap
   and everything else about the grid still comes from them. */
.mie-card--programmes .mie-prog-grid--shared {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 900px) {
    .mie-card--programmes .mie-prog-grid--shared {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 600px) {
    .mie-card--programmes .mie-prog-grid--shared {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The FALLBACK card below — used only when mi-workouts is not active. */
.mie-prog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--mie-space-4);
}

.mie-prog {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    background: var(--mie-surface);
}

.mie-prog:hover {
    border-color: var(--mie-hover-on-light);
}

.mie-prog:hover .mie-prog__title,
.mie-prog:hover .mie-mini__more {
    color: var(--mie-hover-on-light);
}

.mie-prog__media {
    position: relative;
    display: block;
    /* Never shrinks: in a flex column a fixed-ratio well is otherwise
       squashed by whatever the body needs. */
    flex: 0 0 auto;
    aspect-ratio: 16 / 10;
    background: var(--mie-placeholder);
}

.mie-prog__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.mie-prog__badge {
    position: absolute;
    top: var(--mie-space-2);
    left: var(--mie-space-2);
    padding: 2px var(--mie-space-2);
    border-radius: var(--mie-radius-sm);
    background: var(--mie-ink);
    color: var(--mie-text-on-ink);
    font-size: var(--mie-text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.mie-prog__body {
    display: flex;
    flex-direction: column;
    flex: 1;   /* takes the height the stretched card has spare */
    padding: var(--mie-space-4);
}

.mie-prog__title {
    display: block;
    font-weight: 700;
    line-height: 1.3;
    color: var(--mie-text);
}

.mie-prog__desc {
    display: block;
    margin-top: var(--mie-space-2);
    font-size: var(--mie-text-sm);
    line-height: 1.5;
    color: var(--mie-text-muted);
}

/* The bottom group: the meta row takes the auto margin, and the link
   under it cancels its own so the pair travels together instead of
   splitting the free space between them. A card with no meta row leaves
   the link's own auto margin in place — hence the `+` cancel rather
   than an unconditional one. */
.mie-prog__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mie-space-3);
    margin-top: auto;
    padding-top: var(--mie-space-3);
    font-size: var(--mie-text-xs);
    font-weight: 700;
    color: var(--mie-text);
}

.mie-prog__meta + .mie-mini__more {
    margin-top: 0;
}

/* ── Archive: hub + muscle pages ───────────────────────────────────── */

.mie-archive__body {
    padding-top: var(--mie-space-6);
    padding-bottom: var(--mie-space-6);
}

.mie-archive__heading {
    margin: 0 0 var(--mie-space-2);
    font-size: var(--mie-text-xl);
}

.mie-archive__sub {
    margin: 0 0 var(--mie-space-5);
    font-size: var(--mie-text-md);
    color: var(--mie-text-muted);
}

.mie-archive__browse {
    margin-bottom: var(--mie-space-7);
}

.mie-archive__siblings {
    margin-bottom: var(--mie-space-6);
}

.mie-archive__categories {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mie-space-2);
    margin: 0;
}

.mie-prose p {
    margin: 0 0 var(--mie-space-4);
    line-height: 1.65;
    color: var(--mie-text-muted);
}

.mie-prose p:last-child {
    margin-bottom: 0;
}

/* ── Filter bar ────────────────────────────────────────────────────── */

.mie-filter {
    margin: 0 0 var(--mie-space-5);
}

/* ── Sticky tools (hub only, Liam 4.1) ──────────────────────────────
   The hub is the page long enough for the search field and the facets
   to scroll out of reach; a category page is not, and renders without
   the modifier.

   The BACKGROUND IS NOT OPTIONAL: a transparent sticky bar lets the
   cards scroll visibly through the controls. It takes --mie-body rather
   than white so the bar reads as the page holding still rather than as
   a panel laid over it, with a hairline as the only edge.

   z-index sits above the cards and below the floating facet panel's
   own stacking (that panel is a descendant, so it rides along). */
.mie-filter--sticky {
    position: sticky;
    top: 0;
    z-index: 10;
    margin-left: calc(-1 * var(--mie-space-3));
    margin-right: calc(-1 * var(--mie-space-3));
    padding: var(--mie-space-3) var(--mie-space-3) var(--mie-space-2);
    background: var(--mie-body);
    border-bottom: 1px solid var(--mie-hairline);
}

.mie-filter__label {
    display: block;
    font-size: var(--mie-text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: var(--mie-space-2);
    color: var(--mie-text-muted);
}

.mie-filter__input {
    width: 100%;
    max-width: 420px;
    padding: var(--mie-space-3) var(--mie-space-4);
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius-pill);
    background: var(--mie-surface);
}

/* ── Collapsed facet bar (parity R1) ────────────────────────────────
   One row of disclosure triggers instead of an open panel of every
   option, matching the ~40px bar on /workouts/.

   DELIBERATELY SEPARABLE: the trigger (.mie-filter__trigger) and the
   panel (.mie-filter__panel) are styled independently, because Liam
   expects to iterate here and may want a hybrid. A variation should be
   a change to these two rules, not a change to the markup or the
   engine. */
.mie-filter__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--mie-space-2);
    margin-top: var(--mie-space-4);
}

.mie-filter__dropdown {
    position: relative;
}

/* The closed pill. list-style/::marker removal is per-browser, hence
   both the ::-webkit- rule and list-style. */
.mie-filter__trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--mie-space-2);
    padding: var(--mie-space-2) var(--mie-space-4);
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius-pill);
    background: var(--mie-surface);
    font-size: var(--mie-text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mie-text-muted);
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
}

.mie-filter__trigger::-webkit-details-marker {
    display: none;
}

/* Chevron, rotated when open — the only affordance saying the pill
   opens rather than toggles. */
.mie-filter__trigger::after {
    content: "";
    width: 0.4em;
    height: 0.4em;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-0.15em) rotate(45deg);
}

.mie-filter__dropdown[open] > .mie-filter__trigger::after {
    transform: translateY(0.1em) rotate(-135deg);
}

/* The filter controls are <summary>, <button> and <label> — none of them
   an <a>, so the hover pair in foundation.css cannot reach them and each
   states the light-ground colour itself. They are the controls Liam
   named specifically (1.1, "filter triggers"). */
.mie-filter__trigger:hover,
.mie-filter__clear:hover,
.mie-video__tab:hover {
    color: var(--mie-hover-on-light);
    border-color: var(--mie-hover-on-light);
}

/* The active tab is purple-filled, so a border it doesn't have and ink
   the fill would swallow are both no-ops — it deepens its GROUND
   instead, the same darkening direction as everything else. */
.mie-video__tab[aria-pressed="true"]:hover {
    background: var(--mie-hover-on-light);
    color: var(--mie-text-on-ink);
}

.mie-filter__option:hover span {
    color: var(--mie-hover-on-light);
    border-color: var(--mie-hover-on-light);
}

/* A ticked option is already filled purple, and that rule outweighs the
   outline hover above on its own, so hovering one deepens the FILL. */
.mie-filter__option:hover input:checked + span {
    background: var(--mie-hover-on-light);
    border-color: var(--mie-hover-on-light);
}

.mie-filter__trigger:focus-visible {
    outline: 2px solid var(--mie-purple);
    outline-offset: 2px;
}

/* A facet with selections reads as active while CLOSED — without this a
   user has to open all of them to find out what is applied. */
.mie-filter__dropdown.is-active > .mie-filter__trigger {
    border-color: var(--mie-purple);
    color: var(--mie-purple);
}

/* An ACTIVE trigger is already purple, and that rule outweighs the plain
   hover, so it needs its own — otherwise the one facet a user is most
   likely to click next is the one that stops responding to the pointer. */
.mie-filter__dropdown.is-active > .mie-filter__trigger:hover {
    border-color: var(--mie-hover-on-light);
    color: var(--mie-hover-on-light);
}

.mie-filter__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25em;
    height: 1.25em;
    padding: 0 0.3em;
    border-radius: var(--mie-radius-pill);
    background: var(--mie-purple);
    color: var(--mie-text-on-ink);
    font-size: 0.9em;
    line-height: 1;
}

/* An author `display` beats the UA stylesheet's [hidden] { display:none },
   so an empty badge would otherwise render as a filled purple dot on
   every facet — reading as "everything is filtered" when nothing is. */
.mie-filter__badge[hidden] {
    display: none;
}

/* Floating panel: it must not push the results grid down when opened,
   or every open/close would reflow the page under the pointer. */
.mie-filter__panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + var(--mie-space-2));
    left: 0;
    min-width: 12rem;
    max-width: min(22rem, 90vw);
    max-height: 60vh;
    overflow-y: auto;
    padding: var(--mie-space-3);
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius);
    background: var(--mie-surface);
    box-shadow: var(--mie-shadow-pop);
}

.mie-filter__group {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}

.mie-filter__options {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mie-space-2);
}

/* Inside a dropdown the options stack: a wrapping row inside a narrow
   floating panel produces ragged two-per-line groups that are harder to
   scan than a list. */
.mie-filter__panel .mie-filter__options {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--mie-space-1);
}

/* Checkbox facets styled as selectable pills — the input stays a real
   checkbox (visually hidden) so the JS-off guarantee and keyboard
   behaviour are untouched. */
.mie-filter__option {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}

.mie-filter__option input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.mie-filter__option span {
    display: inline-block;
    padding: var(--mie-space-2) var(--mie-space-4);
    border-radius: var(--mie-radius-pill);
    border: 1px solid var(--mie-hairline);
    background: var(--mie-surface);
    font-size: var(--mie-text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mie-text-muted);
}

.mie-filter__option input:checked + span {
    background: var(--mie-purple);
    border-color: var(--mie-purple);
    color: var(--mie-text-on-ink);
}

.mie-filter__option input:focus-visible + span {
    outline: 2px solid var(--mie-purple);
    outline-offset: 2px;
}

.mie-filter__meta {
    display: flex;
    align-items: center;
    gap: var(--mie-space-4);
    margin: var(--mie-space-4) 0 0;
    font-size: var(--mie-text-sm);
    color: var(--mie-text-muted);
}

.mie-filter__clear {
    cursor: pointer;
    background: transparent;
    border: 1px solid var(--mie-hairline);
    border-radius: var(--mie-radius-pill);
    padding: var(--mie-space-1) var(--mie-space-4);
    font-size: var(--mie-text-sm);
    color: var(--mie-text-muted);
}

/* ── Exercise card grid ────────────────────────────────────────────── */

.mie-archive__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--mie-grid-gap);
    margin-top: var(--mie-space-5);
}

.mie-exercise-card {
    display: flex;
    flex-direction: column;
    background: var(--mie-surface);
    border: 1px solid var(--mie-card-border);
    border-radius: var(--mie-radius-card);
    box-shadow: var(--mie-shadow-card);
    overflow: hidden;
}

.mie-exercise-card:hover {
    border-color: var(--mie-hover-on-light);
}

.mie-exercise-card:hover .mie-exercise-card__title,
.mie-exercise-card:hover .mie-exercise-card__more {
    color: var(--mie-hover-on-light);
}

.mie-exercise-card__link {
    text-decoration: none;
    color: inherit;
    display: block;
}

.mie-exercise-card__media {
    flex: 0 0 auto;
    aspect-ratio: 16 / 10;
    background: var(--mie-placeholder);
    overflow: hidden;
    /* Positioning parent for .mie-corner-pill. */
    position: relative;
}

/* ── Corner pill on a card image ──────────────────────────────────────
   The level, top left of the image (Liam, round 2 · 1.2), matching the
   corner label on a /workouts/ card. Every value here was MEASURED off
   production `.mi-guide-card-badge-overlay` rather than eyeballed:
   rgba(0,0,0,.55) ground, white 10px/700 uppercase, 0.6px tracking,
   5px 11px padding, 12px from both edges, a hairline white border and
   an 8px backdrop blur.

   The blur and the translucent ground are what keep it legible over an
   unpredictable video poster frame — a solid dark chip would read as a
   sticker, and a fully transparent one disappears over a dark gym
   floor. `--mie-radius-pill` renders identically to the 20px measured
   there: at 28px tall both are fully rounded.

   Not a level TRAFFIC LIGHT. `.mie-pill--level-*` colours the tag row
   because that row is a set of labels a reader scans; over a photo the
   scrim is the treatment and a coloured chip fights the image. */
.mie-corner-pill {
    position: absolute;
    top: var(--mie-space-3);
    left: var(--mie-space-3);
    z-index: 2;
    padding: 5px 11px;
    border-radius: var(--mie-radius-pill);
    background: var(--mie-scrim);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: var(--mie-text-on-ink);
    font-size: var(--mie-text-2xs);
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    line-height: 1.4;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.mie-exercise-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.mie-exercise-card__media-empty {
    display: block;
    width: 100%;
    height: 100%;
}

.mie-exercise-card__title {
    font-size: var(--mie-text-md);
    margin: 0 0 var(--mie-space-2);
    padding: 0 var(--mie-space-4);
    color: var(--mie-text);
}

.mie-exercise-card__link .mie-exercise-card__title {
    padding-top: var(--mie-space-4);
}

/* The one-line description: the overview's first SENTENCE (cut at a
   sentence boundary in PHP, never at a word count), clamped to two
   lines here and reserving both. Two jobs kept apart — where a sentence
   ends is a prose question, how much room a card has is a layout one.
   Two lines rather than the three the larger cards use, because Liam
   asked for a one-line description and two lines is the point at which
   a long exercise title's sentence still fits without the card becoming
   a paragraph. */
.mie-exercise-card__desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0 0 var(--mie-space-3);
    padding: 0 var(--mie-space-4);
    font-size: var(--mie-text-sm);
    line-height: 1.5;
    min-height: 3em;   /* 2 × 1.5 */
    color: var(--mie-text-muted);
}

/* Same bottom-group pattern as .mie-prog: the chips row pins, the link
   below it cancels, and a card with no chips leaves the link pinning
   itself. */
.mie-exercise-card__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mie-space-1);
    margin-top: auto;
    padding: 0 var(--mie-space-4);
}

.mie-exercise-card__chips + .mie-exercise-card__more {
    margin-top: 0;
}

.mie-exercise-card__more {
    display: block;
    margin-top: auto;
    padding: var(--mie-space-3) var(--mie-space-4) var(--mie-space-4);
    font-size: var(--mie-text-sm);
    font-weight: 600;
    color: var(--mie-purple);
    text-decoration: none;
}

/* ── Hub: muscle category cards ────────────────────────────────────── */

.mie-archive__categories-section {
    margin-bottom: var(--mie-space-7);
}

/* 3-up at the shell width, matching /workouts/ — was 4-up at 230px. The
   floor is 320px so 4 columns cannot fit inside the 1108px content box
   (4x320 + 3x20 > 1108) while 3 comfortably do. */
.mie-cat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: var(--mie-grid-gap);
}

.mie-cat {
    display: flex;
    flex-direction: column;
    background: var(--mie-surface);
    border: 1px solid var(--mie-card-border);
    border-radius: var(--mie-radius-card);
    box-shadow: var(--mie-shadow-card);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
}

.mie-cat:hover {
    border-color: var(--mie-hover-on-light);
}

.mie-cat:hover .mie-cat__title,
.mie-cat:hover .mie-mini__more {
    color: var(--mie-hover-on-light);
}

/* No placeholder tint: this element only exists when it has an image to
   show, so a fallback background has no state left in which it is right.
   Same rule as .mie-hero__media — see the note there. */
.mie-cat__media {
    position: relative;
    display: block;
    flex: 0 0 auto;
    aspect-ratio: 16 / 10;
}

.mie-cat__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Overlaid on a photo, so it takes a scrim rather than solid ink, and a
   pill rather than a 4px corner — at this height --mie-radius-pill and
   the reference's 20px render identically. */
.mie-cat__count {
    position: absolute;
    top: var(--mie-space-2);
    right: var(--mie-space-2);
    padding: 5px 11px;
    border-radius: var(--mie-radius-pill);
    background: var(--mie-scrim);
    color: var(--mie-text-on-ink);
    font-size: var(--mie-text-2xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The same count when there is no image to overlay. It sits in the card
   body on the light surface instead of floating over a photo, so it
   drops the badge treatment rather than carrying ink-on-ink into a
   place that has no ink. */
.mie-cat__count--inline {
    position: static;
    display: inline-block;
    margin-top: var(--mie-space-2);
    padding: 0;
    background: none;
    color: var(--mie-text-muted);
    font-weight: 500;
}

.mie-cat__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--mie-space-4);
}

.mie-cat__title {
    display: block;
    font-weight: 700;
    font-size: var(--mie-text-lg);
    color: var(--mie-text);
}

.mie-cat__desc {
    display: block;
    margin-top: var(--mie-space-2);
    font-size: var(--mie-text-sm);
    line-height: 1.5;
    color: var(--mie-text-muted);
}

/* ── Hub feed: group headings + progressive reveal ───────────────────
   The compact list card that used to live here is GONE. The hub renders
   the same card as the category feeds (Liam, 4.1: the hub's card was
   the weaker of the two), so a second card layout would be a second
   thing to keep in step with the first. */

/* A full-width item IN the grid rather than a wrapper around a sub-grid.
   Sub-grids would each get their own ragged last row and their own
   column count; one grid with headings in it keeps every card on the
   same column rhythm, and lets a heading hide without disturbing the
   flow of the cards around it. */
.mie-feed-group {
    grid-column: 1 / -1;
    margin: var(--mie-space-4) 0 0;
    font-size: var(--mie-text-lg);
    font-weight: 700;
    color: var(--mie-text);
}

.mie-feed-group:first-child {
    margin-top: 0;
}

.mie-feed-more {
    margin-top: var(--mie-space-6);
    text-align: center;
}

/* ── Load more: /workouts/' own button ────────────────────────────────
   When mi-workouts is active the template renders ITS classes inside
   this wrapper and its stylesheet does the styling, so the two buttons
   stay in step (Liam, round 2 · 2.2). Only two things belong here.

   1. The spacing. `.mi-load-more-wrap` brings its own 28px top margin,
      which would stack on ours.

   2. THE HOVER, which cannot be inherited and is the whole reason this
      rule exists. mi-workouts' own rule hovers the button to gold
      #FFE34D. That is NOT what /workouts/ does: the site's Customizer
      CSS overrides it to a deeper purple — measured live, #4A148C rest
      → #3F0883 hover — and that override is scoped to `.mi-workouts`,
      the page shell we deliberately do not use as a scope hook. So on
      any other page the plugin's gold wins, and a gold hover under the
      pointer on a light ground is precisely the lighter-on-light fade
      v1.10.1 was written to kill. Inheriting the component here would
      have reintroduced the bug the last round closed.

   Specificity is deliberate, not decorative: mi-workouts' rule is
   (0,3,0) and its stylesheet loads AFTER ours, so a matching selector
   would lose on order. Doubling up the wrapper's two classes makes this
   (0,4,0) and settles it on weight instead of on enqueue sequence.

   Worth knowing: /workouts/{term}/ pages wrap in `.mi-beginner` and so
   miss that Customizer override — production is already inconsistent
   with itself here, and this button matches the archive Liam named. */
.mie-feed-more.mi-beginner {
    margin-top: 0;
}

.mie-feed-more.mi-beginner .mi-load-more-btn:hover {
    background: var(--mie-hover-purple-deep);
}

/* Filter engine + reveal show/hide. One class does both: a card is off
   the page because it did not match, or because it is past the reveal
   threshold, and nothing downstream needs to tell those apart. */
.mie-exercise-card.mie-hide,
.mie-feed-group.mie-hide,
.mie-archive__empty.mie-hide {
    display: none;
}

/* The button's wrapper carries [hidden] from the server, and an author
   `display` on the wrapper would beat the UA stylesheet — the same trap
   the facet badge fell into. */
.mie-feed-more[hidden] {
    display: none;
}

.mie-archive__empty {
    margin: var(--mie-space-6) 0;
    padding: var(--mie-space-6);
    text-align: center;
    background: var(--mie-surface);
    border-radius: var(--mie-radius);
}

/* ── Muscles Worked section ────────────────────────────────────────── */

/* The card's own top/bottom padding, tightened from --mie-space-6 (32px)
   so the section height tracks its content (Liam, 2.2). Left and right
   keep the shared card padding — this is a vertical complaint, and
   narrowing the horizontal padding here alone would put the block out
   of line with every other card on the page. */
.mie-card--diagram {
    padding-top: var(--mie-space-5);
    padding-bottom: var(--mie-space-5);
}

/* align-items: center was ALREADY here and already correct — measured on
   staging, the figure's centre and the label column's centre were both
   at y=2118, exactly level. What made the block read as unbalanced was
   the content, not the alignment: a 49px label column beside a 307px
   figure. The primary/secondary split and the role copy are what fill
   that column; this rule is unchanged and stays for the same reason it
   was written. */
.mie-diagram {
    display: flex;
    align-items: center;
    gap: var(--mie-space-5);
}

/* Primary and Secondary stack in the one column rather than sitting
   side by side: stacking is what gives the column the height to sit
   against a portrait figure, and it keeps the reading order
   primary-then-secondary at every width instead of only wide ones. */
.mie-diagram__labels {
    display: flex;
    flex-direction: column;
    gap: var(--mie-space-4);
}

.mie-diagram__role {
    margin: 0;
    max-width: var(--mie-measure);
    font-size: var(--mie-text-sm);
    line-height: 1.6;
    color: var(--mie-text-muted);
}

.mie-muscle-diagram {
    margin: 0;
    flex: 0 0 auto;
}

/* An inline accent beside its labels, not a feature block. The source is
   larger so it stays crisp on retina; srcset does the rest. */
.mie-muscle-diagram__img {
    width: 140px;
    max-width: 100%;
    height: auto;
    display: block;
}

.mie-diagram__labels {
    min-width: 0;
}

.mie-diagram__label {
    display: block;
    margin-bottom: var(--mie-space-2);
    font-size: var(--mie-text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mie-text-muted);
}

.mie-diagram__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mie-space-2);
}

@media (max-width: 600px) {
    .mie-diagram {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--mie-space-4);
    }
}

/* ── Responsive ────────────────────────────────────────────────────── */

@media (max-width: 780px) {
    .mie-duo {
        grid-template-columns: minmax(0, 1fr);
    }

    .mie-card__head {
        flex-direction: column;
    }
}

@media (max-width: 600px) {
    /* Two-up grid of the SAME collapsed pills, mirroring what
       /workouts/ does at its own breakpoint. The panel goes full width
       and left-anchored so a right-hand dropdown cannot open off-screen.
       The open panel this replaced got TALLER on mobile, which was the
       worst place for it to. */
    .mie-filter__bar {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
    }

    .mie-filter__trigger {
        width: 100%;
        justify-content: space-between;
    }

    .mie-filter__panel {
        left: 0;
        right: 0;
        min-width: 0;
        max-width: none;
    }

    .mie-filter__clear {
        justify-self: start;
    }
}
